From 93fb873807d1c57d7b973eaf822dcbef38eb39d3 Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Tue, 18 Nov 2014 10:34:26 +0900 Subject: [PATCH 1/6] Translate "1-distributed-git.asc" --- book/05-distributed-git/1-distributed-git.asc | 19 +- .../diff-1-distributed-git.htm | 3775 +++++++++++++++++ 2 files changed, 3793 insertions(+), 1 deletion(-) create mode 100644 book/05-distributed-git/diff-1-distributed-git.htm diff --git a/book/05-distributed-git/1-distributed-git.asc b/book/05-distributed-git/1-distributed-git.asc index bb2f9ded..777072b6 100644 --- a/book/05-distributed-git/1-distributed-git.asc +++ b/book/05-distributed-git/1-distributed-git.asc @@ -1,11 +1,21 @@ [[_distributed_git]] +////////////////////////// == Distributed Git +////////////////////////// +== Git での分散作業 +////////////////////////// (((distributed git))) Now that you have a remote Git repository set up as a point for all the developers to share their code, and you're familiar with basic Git commands in a local workflow, you'll look at how to utilize some of the distributed workflows that Git affords you. +////////////////////////// +リモート Git リポジトリを用意し、すべての開発者がコードを共有できるようになりました。また、ローカル環境で作業をする際に使う基本的な Git コマンドについても身についたことでしょう。次に、Git を使った分散作業の流れを見ていきましょう。 +////////////////////////// In this chapter, you'll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you'll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. +////////////////////////// +本章では、Git を使った分散環境での作業の流れを説明します。 +自分のコードをプロジェクトに提供する方法、そしてプロジェクトのメンテナーと自分の両方が作業を進めやすくする方法、そして多数の開発者からの貢献を受け入れるプロジェクトを運営する方法などを扱います。 include::sections/distributed-workflows.asc[] @@ -13,8 +23,15 @@ include::sections/contributing.asc[] include::sections/maintaining.asc[] +////////////////////////// === Summary - +////////////////////////// +=== まとめ +////////////////////////// You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users' contributions. Congratulations on being an effective Git developer! In the next chapter, you'll learn about how to use the largest and most popular Git hosting service, GitHub. +////////////////////////// +Git を使っているプロジェクトにコードを提供したり、自分のプロジェクトに他のユーザーからのコードを取り込んだりといった作業を安心してこなせるようになりましたね。 +おめでとうございます。Git を使いこなせる開発者の仲間入りです! +次の章では、世界最大で一番人気の Git ホスティングサービス、GitHub の使い方を見ていきましょう。 diff --git a/book/05-distributed-git/diff-1-distributed-git.htm b/book/05-distributed-git/diff-1-distributed-git.htm new file mode 100644 index 00000000..326bbfe5 --- /dev/null +++ b/book/05-distributed-git/diff-1-distributed-git.htm @@ -0,0 +1,3775 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\1-distributed-git.asc
. 1[[_distributed_git]]
1# Distributed Git # 2== Distributed Git 
2 3 
. 4(((distributed git)))
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you.5Now that you have a remote Git repository set up as a point for all the developers to share their code, and you're familiar with basic Git commands in a local workflow, you'll look at how to utilize some of the distributed workflows that Git affords you.
4 6 
.5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing.7In this chapter, you'll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you'll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing.
6 8 
.7## Distributed Workflows ## 9include::sections/distributed-workflows.asc[] 
8 10 
.9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub — that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. 11include::sections/contributing.asc[] 
10 12 
.11### Centralized Workflow ### 13include::sections/maintaining.asc[] 
12  
13In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). 
14  
15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
17  
18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. 
19  
20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with. 
22  
23### Integration-Manager Workflow ### 
24  
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2): 
26  
271. The project maintainer pushes to their public repository. 
282. A contributor clones that repository and makes changes. 
293. The contributor pushes to their own public copy. 
304. The contributor sends the maintainer an e-mail asking them to pull changes. 
315. The maintainer adds the contributor’s repo as a remote and merges locally. 
326. The maintainer pushes merged changes to the main repository. 
33  
34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
36  
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. 
38  
39### Dictator and Lieutenants Workflow ### 
40  
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3): 
42  
431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator. 
442. Lieutenants merge the developers’ topic branches into their master branch. 
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 
464. The dictator pushes their master to the reference repository so the other developers can rebase on it. 
47  
48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
50  
51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. 
52  
53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 
54  
55## Contributing to a Project ## 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58  
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method. 
60  
61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid? 
62  
63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 
64  
65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? 
66  
67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. 
68  
69### Commit Guidelines ### 
70  
71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches — you can read it in the Git source code in the `Documentation/SubmittingPatches` file. 
72  
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this — before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 
74  
75    $ git diff --check 
76    lib/simplegit.rb:5: trailing whitespace. 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82  
83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers. 
84  
85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible — don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files — use these tools to help craft a clean and understandable history. 
86  
87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 
88Here is a template originally written by Tim Pope at tpope.net: 
89  
90    Short (50 chars or less) summary of changes 
91  
92    More detailed explanatory text, if necessary.  Wrap it to about 72 
93    characters or so.  In some contexts, the first line is treated as the 
94    subject of an email and the rest of the text as the body.  The blank 
95    line separating the summary from the body is critical (unless you omit 
96    the body entirely); tools like rebase can get confused if you run the 
97    two together. 
98  
99    Further paragraphs come after blank lines. 
100  
101     - Bullet points are okay, too 
102  
103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 
104       single space, with blank lines in between, but conventions vary here 
105  
106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages — I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like. 
107  
108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do. 
109  
110### Private Small Team ### 
111  
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source — not read-accessible to the outside world. You and the other developers all have push access to the repository. 
113  
114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.) 
116  
117    # John's Machine 
118    $ git clone john@githost:simplegit.git 
119    Initialized empty Git repository in /home/john/simplegit/.git/ 
120    ... 
121    $ cd simplegit/ 
122    $ vim lib/simplegit.rb 
123    $ git commit -am 'removed invalid default value' 
124    [master 738ee87] removed invalid default value 
125     1 files changed, 1 insertions(+), 1 deletions(-) 
126  
127The second developer, Jessica, does the same thing — clones the repository and commits a change: 
128  
129    # Jessica's Machine 
130    $ git clone jessica@githost:simplegit.git 
131    Initialized empty Git repository in /home/jessica/simplegit/.git/ 
132    ... 
133    $ cd simplegit/ 
134    $ vim TODO 
135    $ git commit -am 'add reset task' 
136    [master fbff5bc] add reset task 
137     1 files changed, 1 insertions(+), 0 deletions(-) 
138  
139Now, Jessica pushes her work up to the server: 
140  
141    # Jessica's Machine 
142    $ git push origin master 
143    ... 
144    To jessica@githost:simplegit.git 
145       1edee6b..fbff5bc  master -> master 
146  
147John tries to push his change up, too: 
148  
149    # John's Machine 
150    $ git push origin master 
151    To john@githost:simplegit.git 
152     ! [rejected]        master -> master (non-fast forward) 
153    error: failed to push some refs to 'john@githost:simplegit.git' 
154  
155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push: 
156  
157    $ git fetch origin 
158    ... 
159    From john@githost:simplegit 
160     + 049d078...fbff5bc master     -> origin/master 
161  
162At this point, John’s local repository looks something like Figure 5-4. 
163  
164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
166  
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: 
168  
169    $ git merge origin/master 
170    Merge made by recursive. 
171     TODO |    1 + 
172     1 files changed, 1 insertions(+), 0 deletions(-) 
173  
174The merge goes smoothly — John’s commit history now looks like Figure 5-5. 
175  
176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
178  
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: 
180  
181    $ git push origin master 
182    ... 
183    To john@githost:simplegit.git 
184       fbff5bc..72bbc59  master -> master 
185  
186Finally, John’s commit history looks like Figure 5-6. 
187  
188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
190  
191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 
192  
193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
195  
196Jessica wants to sync up with John, so she fetches: 
197  
198    # Jessica's Machine 
199    $ git fetch origin 
200    ... 
201    From jessica@githost:simplegit 
202       fbff5bc..72bbc59  master     -> origin/master 
203  
204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 
205  
206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
208  
209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: 
210  
211    $ git log --no-merges origin/master ^issue54 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016 
213    Author: John Smith <jsmith@example.com> 
214    Date:   Fri May 29 16:01:27 2009 -0700 
215  
216        removed invalid default value 
217  
218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work: 
219  
220    $ git checkout master 
221    Switched to branch "master" 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. 
223  
224She can merge either `origin/master` or `issue54` first — they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: 
225  
226    $ git merge issue54 
227    Updating fbff5bc..4af4298 
228    Fast forward 
229     README           |    1 + 
230     lib/simplegit.rb |    6 +++++- 
231     2 files changed, 6 insertions(+), 1 deletions(-) 
232  
233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`): 
234  
235    $ git merge origin/master 
236    Auto-merging lib/simplegit.rb 
237    Merge made by recursive. 
238     lib/simplegit.rb |    2 +- 
239     1 files changed, 1 insertions(+), 1 deletions(-) 
240  
241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 
242  
243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
245  
246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): 
247  
248    $ git push origin master 
249    ... 
250    To jessica@githost:simplegit.git 
251       72bbc59..8059c15  master -> master 
252  
253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. 
254  
255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
257  
258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 
259  
260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
262  
263### Private Managed Team ### 
264  
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. 
266  
267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. 
268  
269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: 
270  
271    # Jessica's Machine 
272    $ git checkout -b featureA 
273    Switched to a new branch "featureA" 
274    $ vim lib/simplegit.rb 
275    $ git commit -am 'add limit to log function' 
276    [featureA 3300904] add limit to log function 
277     1 files changed, 1 insertions(+), 1 deletions(-) 
278  
279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch — only the integrators do — so she has to push to another branch in order to collaborate with John: 
280  
281    $ git push origin featureA 
282    ... 
283    To jessica@githost:simplegit.git 
284     * [new branch]      featureA -> featureA 
285  
286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch: 
287  
288    # Jessica's Machine 
289    $ git fetch origin 
290    $ git checkout -b featureB origin/master 
291    Switched to a new branch "featureB" 
292  
293Now, Jessica makes a couple of commits on the `featureB` branch: 
294  
295    $ vim lib/simplegit.rb 
296    $ git commit -am 'made the ls-tree function recursive' 
297    [featureB e5b0fdc] made the ls-tree function recursive 
298     1 files changed, 1 insertions(+), 1 deletions(-) 
299    $ vim lib/simplegit.rb 
300    $ git commit -am 'add ls-files' 
301    [featureB 8512791] add ls-files 
302     1 files changed, 5 insertions(+), 0 deletions(-) 
303  
304Jessica’s repository looks like Figure 5-12. 
305  
306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
308  
309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: 
310  
311    $ git fetch origin 
312    ... 
313    From jessica@githost:simplegit 
314     * [new branch]      featureBee -> origin/featureBee 
315  
316Jessica can now merge this into the work she did with `git merge`: 
317  
318    $ git merge origin/featureBee 
319    Auto-merging lib/simplegit.rb 
320    Merge made by recursive. 
321     lib/simplegit.rb |    4 ++++ 
322     1 files changed, 4 insertions(+), 0 deletions(-) 
323  
324There is a bit of a problem — she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: 
325  
326    $ git push origin featureB:featureBee 
327    ... 
328    To jessica@githost:simplegit.git 
329       fba9af8..cd685d1  featureB -> featureBee 
330  
331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 
332  
333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: 
334  
335    $ git fetch origin 
336    ... 
337    From jessica@githost:simplegit 
338       3300904..aad881d  featureA   -> origin/featureA 
339  
340Then, she can see what has been changed with `git log`: 
341  
342    $ git log origin/featureA ^featureA 
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 
344    Author: John Smith <jsmith@example.com> 
345    Date:   Fri May 29 19:57:33 2009 -0700 
346  
347        changed log output to 30 from 25 
348  
349Finally, she merges John’s work into her own `featureA` branch: 
350  
351    $ git checkout featureA 
352    Switched to branch "featureA" 
353    $ git merge origin/featureA 
354    Updating 3300904..aad881d 
355    Fast forward 
356     lib/simplegit.rb |   10 +++++++++- 
357    1 files changed, 9 insertions(+), 1 deletions(-) 
358  
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server: 
360  
361    $ git commit -am 'small tweak' 
362    [featureA 774b3ed] small tweak 
363     1 files changed, 1 insertions(+), 1 deletions(-) 
364    $ git push origin featureA 
365    ... 
366    To jessica@githost:simplegit.git 
367       3300904..774b3ed  featureA -> featureA 
368  
369Jessica’s commit history now looks something like Figure 5-13. 
370  
371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
373  
374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 
375  
376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
378  
379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 
380  
381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
383  
384### Public Small Project ### 
385  
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. 
387  
388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this: 
389  
390    $ git clone (url) 
391    $ cd project 
392    $ git checkout -b featureA 
393    $ (work) 
394    $ git commit 
395    $ (work) 
396    $ git commit 
397  
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review — see Chapter 6 for more information about interactive rebasing. 
399  
400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: 
401  
402    $ git remote add myfork (url) 
403  
404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow: 
405  
406    $ git push myfork featureA 
407  
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website — GitHub has a "pull request" button that automatically messages the maintainer — or run the `git request-pull` command and e-mail the output to the project maintainer manually. 
409  
410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this: 
411  
412    $ git request-pull origin/master myfork 
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: 
414      John Smith (1): 
415            added a new function 
416  
417    are available in the git repository at: 
418  
419      git://githost/simplegit.git featureA 
420  
421    Jessica Smith (2): 
422          add limit to log function 
423          change log output to 30 from 25 
424  
425     lib/simplegit.rb |   10 +++++++++- 
426     1 files changed, 9 insertions(+), 1 deletions(-) 
427  
428The output can be sent to the maintainer—it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. 
429  
430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up — start over from the main repository’s `master` branch: 
431  
432    $ git checkout -b featureB origin/master 
433    $ (work) 
434    $ git commit 
435    $ git push myfork featureB 
436    $ (email maintainer) 
437    $ git fetch origin 
438  
439Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 
440  
441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
443  
444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: 
445  
446    $ git checkout featureA 
447    $ git rebase origin/master 
448    $ git push -f myfork featureA 
449  
450This rewrites your history to now look like Figure 5-17. 
451  
452Insert 18333fig0517.png 
453Figure 5-17. Commit history after featureA work. 
454  
455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). 
456  
457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: 
458  
459    $ git checkout -b featureBv2 origin/master 
460    $ git merge --no-commit --squash featureB 
461    $ (change implementation) 
462    $ git commit 
463    $ git push myfork featureBv2 
464  
465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. 
466  
467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). 
468  
469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
471  
472### Public Large Project ### 
473  
474Many larger projects have established procedures for accepting patches — you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now. 
475  
476The workflow is similar to the previous use case — you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: 
477  
478    $ git checkout -b topicA 
479    $ (work) 
480    $ git commit 
481    $ (work) 
482    $ git commit 
483  
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list — it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 
485  
486    $ git format-patch -M origin/master 
487    0001-add-limit-to-log-function.patch 
488    0002-changed-log-output-to-30-from-25.patch 
489  
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: 
491  
492    $ cat 0001-add-limit-to-log-function.patch 
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
494    From: Jessica Smith <jessica@example.com> 
495    Date: Sun, 6 Apr 2008 10:17:23 -0700 
496    Subject: [PATCH 1/2] add limit to log function 
497  
498    Limit log functionality to the first 20 
499  
500    --- 
501     lib/simplegit.rb |    2 +- 
502     1 files changed, 1 insertions(+), 1 deletions(-) 
503  
504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
505    index 76f47bc..f9815f1 100644 
506    --- a/lib/simplegit.rb 
507    +++ b/lib/simplegit.rb 
508    @@ -14,7 +14,7 @@ class SimpleGit 
509       end 
510  
511       def log(treeish = 'master') 
512    -    command("git log #{treeish}") 
513    +    command("git log -n 20 #{treeish}") 
514       end 
515  
516       def ls_tree(treeish = 'master') 
517    -- 
518    1.6.2.rc1.20.g8c5b.dirty 
519  
520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. 
521  
522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. 
523  
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this: 
525  
526    [imap] 
527      folder = "[Gmail]/Drafts" 
528      host = imaps://imap.gmail.com 
529      user = user@gmail.com 
530      pass = p4ssw0rd 
531      port = 993 
532      sslverify = false 
533  
534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`. 
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: 
536  
537    $ cat *.patch |git imap-send 
538    Resolving imap.gmail.com... ok 
539    Connecting to [74.125.142.109]:993... ok 
540    Logging in... 
541    sending 2 messages 
542    100% (2/2) done 
543  
544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. 
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580  
581### Summary ### 
582  
583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager. 
584  
585## Maintaining a Project ## 
586  
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. 
588  
589### Working in Topic Branches ### 
590  
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. 
592As you’ll remember, you can create the branch based off your master branch like this: 
593  
594    $ git branch sc/ruby_client master 
595  
596Or, if you want to also switch to it immediately, you can use the `checkout -b` command: 
597  
598    $ git checkout -b sc/ruby_client master 
599  
600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. 
601  
602### Applying Patches from E-mail ### 
603  
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. 
605  
606#### Applying a Patch with apply #### 
607  
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: 
609  
610    $ git apply /tmp/patch-ruby-client.patch 
611  
612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you — after running it, you must stage and commit the changes introduced manually. 
613  
614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: 
615  
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch 
617    error: patch failed: ticgit.gemspec:1 
618    error: ticgit.gemspec: patch does not apply 
619  
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. 
621  
622#### Applying a Patch with am #### 
623  
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. 
625  
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: 
627  
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
629    From: Jessica Smith <jessica@example.com> 
630    Date: Sun, 6 Apr 2008 10:17:23 -0700 
631    Subject: [PATCH 1/2] add limit to log function 
632  
633    Limit log functionality to the first 20 
634  
635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time. 
636  
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: 
638  
639    $ git am 0001-limit-log-function.patch 
640    Applying: add limit to log function 
641  
642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: 
643  
644    $ git log --pretty=fuller -1 
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
646    Author:     Jessica Smith <jessica@example.com> 
647    AuthorDate: Sun Apr 6 10:17:23 2008 -0700 
648    Commit:     Scott Chacon <schacon@gmail.com> 
649    CommitDate: Thu Apr 9 09:19:06 2009 -0700 
650  
651       add limit to log function 
652  
653       Limit log functionality to the first 20 
654  
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. 
656  
657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: 
658  
659    $ git am 0001-seeing-if-this-helps-the-gem.patch 
660    Applying: seeing if this helps the gem 
661    error: patch failed: ticgit.gemspec:1 
662    error: ticgit.gemspec: patch does not apply 
663    Patch failed at 0001. 
664    When you have resolved this problem run "git am --resolved". 
665    If you would prefer to skip this patch, instead run "git am --skip". 
666    To restore the original branch and stop patching run "git am --abort". 
667  
668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: 
669  
670    $ (fix the file) 
671    $ git add ticgit.gemspec 
672    $ git am --resolved 
673    Applying: seeing if this helps the gem 
674  
675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: 
676  
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch 
678    Applying: seeing if this helps the gem 
679    error: patch failed: ticgit.gemspec:1 
680    error: ticgit.gemspec: patch does not apply 
681    Using index info to reconstruct a base tree... 
682    Falling back to patching base and 3-way merge... 
683    No changes -- Patch already applied. 
684  
685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict. 
686  
687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: 
688  
689    $ git am -3 -i mbox 
690    Commit Body is: 
691    -------------------------- 
692    seeing if this helps the gem 
693    -------------------------- 
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all 
695  
696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. 
697  
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. 
699  
700### Checking Out Remote Branches ### 
701  
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. 
703  
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: 
705  
706    $ git remote add jessica git://github.com/jessica/myproject.git 
707    $ git fetch jessica 
708    $ git checkout -b rubyclient jessica/ruby-client 
709  
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. 
711  
712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier — it depends largely on how you develop and how your contributors develop. 
713  
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. 
715  
716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference: 
717  
718    $ git pull git://github.com/onetimeguy/project.git 
719    From git://github.com/onetimeguy/project 
720     * branch            HEAD       -> FETCH_HEAD 
721    Merge made by recursive. 
722  
723### Determining What Is Introduced ### 
724  
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch. 
726  
727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: 
728  
729    $ git log contrib --not master 
730    commit 5b6235bd297351589efc4d73316f0a68d484f118 
731    Author: Scott Chacon <schacon@gmail.com> 
732    Date:   Fri Oct 24 09:53:59 2008 -0700 
733  
734        seeing if this helps the gem 
735  
736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 
737    Author: Scott Chacon <schacon@gmail.com> 
738    Date:   Mon Oct 22 19:38:36 2008 -0700 
739  
740        updated the gemspec to hopefully work better 
741  
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. 
743  
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: 
745  
746    $ git diff master 
747  
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. 
749  
750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch. 
751  
752What you really want to see are the changes added to the topic branch — the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. 
753  
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: 
755  
756    $ git merge-base contrib master 
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 
758    $ git diff 36c7db 
759  
760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: 
761  
762    $ git diff master...contrib 
763  
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. 
765  
766### Integrating Contributed Work ### 
767  
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them. 
769  
770#### Merging Workflows #### 
771  
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. 
773  
774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
776  
777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
779  
780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. 
781  
782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). 
783  
784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
786  
787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
789  
790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
792  
793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. 
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. 
795  
796#### Large-Merging Workflows #### 
797  
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. 
799  
800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
802  
803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 
804  
805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
807  
808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 
809  
810#### Rebasing and Cherry Picking Workflows #### 
811  
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history. 
813  
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 
815  
816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
818  
819If you want to pull commit `e43a6` into your master branch, you can run 
820  
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf 
822    Finished one cherry-pick. 
823    [master]: created a0a41a9: "More friendly message when locking the index fails." 
824     3 files changed, 17 insertions(+), 3 deletions(-) 
825  
826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 
827  
828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
830  
831Now you can remove your topic branch and drop the commits you didn’t want to pull in. 
832  
833### Tagging Your Releases ### 
834  
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this: 
836  
837    $ git tag -s v1.5 -m 'my signed 1.5 tag' 
838    You need a passphrase to unlock the secret key for 
839    user: "Scott Chacon <schacon@gmail.com>" 
840    1024-bit DSA key, ID F721C45A, created 2009-02-09 
841  
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: 
843  
844    $ gpg --list-keys 
845    /Users/schacon/.gnupg/pubring.gpg 
846    --------------------------------- 
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09] 
848    uid                  Scott Chacon <schacon@gmail.com> 
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09] 
850  
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: 
852  
853    $ gpg -a --export F721C45A | git hash-object -w --stdin 
854    659ef797d181633c87ec71ac3f9ba29fe5775b92 
855  
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: 
857  
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 
859  
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: 
861  
862    $ git show maintainer-pgp-pub | gpg --import 
863  
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification. 
865  
866### Generating a Build Number ### 
867  
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing: 
869  
870    $ git describe master 
871    v1.6.2-rc1-20-g8c5b85c 
872  
873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name. 
874  
875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. 
876  
877### Preparing a Release ### 
878  
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`: 
880  
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz 
882    $ ls *.tar.gz 
883    v1.6.2-rc1-20-g8c5b85c.tar.gz 
884  
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: 
886  
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip 
888  
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. 
890  
891### The Shortlog ### 
892  
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: 
894  
895    $ git shortlog --no-merges master --not v1.0.1 
896    Chris Wanstrath (8): 
897          Add support for annotated tags to Grit::Tag 
898          Add packed-refs annotated tag support. 
899          Add Grit::Commit#to_patch 
900          Update version and History.txt 
901          Remove stray `puts` 
902          Make ls_tree ignore nils 
903  
904    Tom Preston-Werner (4): 
905          fix dates in history 
906          dynamic version method 
907          Version bump to 1.0.2 
908          Regenerated gemspec for version 1.0.2 
909  
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. 
911 14 
.912## Summary ## 15=== Summary 
913 16 
.914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master.17You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users' contributions. Congratulations on being an effective Git developer! In the next chapter, you'll learn about how to use the largest and most popular Git hosting service, GitHub.
915 18 
+
+ From f7457b911b455ac6a97c892aa2bee4fd16050524 Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Wed, 19 Nov 2014 15:12:42 +0900 Subject: [PATCH 2/6] Apply existing translation --- .../sections/contributing.asc | 556 +- .../sections/diff-contributing.htm | 4503 +++++++++++++++++ .../sections/diff-distributed-workflows.htm | 3843 ++++++++++++++ .../sections/diff-maintaining.htm | 4375 ++++++++++++++++ .../sections/distributed-workflows.asc | 103 +- .../sections/maintaining.asc | 369 +- 6 files changed, 13739 insertions(+), 10 deletions(-) create mode 100644 book/05-distributed-git/sections/diff-contributing.htm create mode 100644 book/05-distributed-git/sections/diff-distributed-workflows.htm create mode 100644 book/05-distributed-git/sections/diff-maintaining.htm diff --git a/book/05-distributed-git/sections/contributing.asc b/book/05-distributed-git/sections/contributing.asc index dbd8c3e7..6dcd75ce 100644 --- a/book/05-distributed-git/sections/contributing.asc +++ b/book/05-distributed-git/sections/contributing.asc @@ -1,51 +1,107 @@ [[_contributing_project]] +////////////////////////// === Contributing to a Project +////////////////////////// +=== プロジェクトへの貢献 (((contributing))) +////////////////////////// The main difficulty with describing how to contribute to a project is that there are a huge number of variations on how it's done. Because Git is very flexible, people can and do work together in many ways, and it's problematic to describe how you should contribute – every project is a bit different. Some of the variables involved are active contributor count, chosen workflow, your commit access, and possibly the external contribution method. +////////////////////////// +どうやってプロジェクトに貢献するか、というのは非常に説明しづらい内容です。というのも、ほんとうにいろいろなパターンがあるからです。 +Git は柔軟なシステムなので、いろいろな方法で共同作業をすることができます。そのせいもあり、どのプロジェクトをとってみても微妙に他とは異なる方式を使っているのです。 +違いが出てくる原因としては、アクティブな貢献者の数やプロジェクトで使用しているワークフロー、あなたのコミット権、そして外部からの貢献を受け入れる際の方式などがあります。 +////////////////////////// The first variable is active contributor count – how many users are actively contributing code to this project, and how often? In many instances, you'll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For larger companies or projects, the number of developers could be in the thousands, with hundreds or thousands of commits coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your commits valid? - +////////////////////////// +最初の要素はアクティブな貢献者の数です。そのプロジェクトに対してアクティブにコードを提供している開発者はどれくらいいるのか、そして彼らはどれくらいの頻度で提供しているのか。 +よくあるのは、数名の開発者が一日数回のコミットを行うというものです。休眠状態のプロジェクトなら、もう少し頻度が低くなるでしょう。 +企業やプロジェクトの規模が大きくなると、開発者の数が数千人になることもあります。数百から下手したら千を超えるようなコミットが毎日やってきます。 +開発者の数が増えれば増えるほど、あなたのコードをきちんと適用したり他のコードをマージしたりするのが難しくなります。 +あなたが手元で作業をしている間に他の変更が入って、手元で変更した内容が無意味になってしまったりあるいは他の変更を壊してしまう羽目になったり。そのせいで、手元の変更を適用してもらうための待ち時間が発生したり。 +手元のコードを常に最新の状態にし、正しいコミットを作るにはどうしたらいいのでしょうか。 + +////////////////////////// The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? - +////////////////////////// +次に考えるのは、プロジェクトが採用しているワークフローです。 +中央管理型で、すべての開発者がコードに対して同等の書き込みアクセス権を持っている状態? +特定のメンテナーや統合マネージャーがすべてのパッチをチェックしている? +パッチを適用する前にピアレビューをしている? +あなたはパッチをチェックしたりピアレビューに参加したりしている人? +若頭型のワークフローを使っており、まず彼らにコードを渡さなければならない? + +////////////////////////// The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don't. If you don't have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? - +////////////////////////// +次の問題は、あなたのコミット権です。 +あなたがプロジェクトへの書き込みアクセス権限を持っている場合は、プロジェクトに貢献するための作業の流れが変わってきます。 +書き込み権限がない場合、そのプロジェクトではどのような形式での貢献を推奨していますか? +何かポリシーのようなものはありますか? +一度にどれくらいの作業を貢献することになりますか? +また、どれくらいの頻度で貢献することになりますか? + +////////////////////////// All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. We'll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. +////////////////////////// +これらの点を考慮して、あなたがどんな流れでどのようにプロジェクトに貢献していくのかが決まります。 +単純なものから複雑なものまで、実際の例を見ながら考えていきましょう。これらの例を参考に、あなたなりのワークフローを見つけてください。 [[_commit_guidelines]] +////////////////////////// ==== Commit Guidelines +////////////////////////// +==== コミットの指針 +////////////////////////// Before we start looking at the specific use cases, here's a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches – you can read it in the Git source code in the `Documentation/SubmittingPatches` file. +////////////////////////// +個々の例を見る前に、コミットメッセージについてのちょっとした注意点をお話しておきましょう。 +コミットに関する指針をきちんと定めてそれを守るようにすると、Git での共同作業がよりうまく進むようになります。 +Git プロジェクトでは、パッチの投稿用のコミットを作成するときのヒントをまとめたドキュメントを用意しています。Git のソースの中にある `Documentation/SubmittingPatches` をごらんください。 (((git commands, diff, check))) +////////////////////////// First, you don't want to submit any whitespace errors. Git provides an easy way to check for this – before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. +////////////////////////// +まず、余計な空白文字を含めてしまわないように注意が必要です。 +Git には、余計な空白文字をチェックするための簡単な仕組みがあります。コミットする前に `git diff --check` を実行してみましょう。おそらく意図したものではないと思われる空白文字を探し、それを教えてくれます。 +////////////////////////// .Output of `git diff --check`. image::images/git-diff-check.png[Output of `git diff --check`.] +////////////////////////// +.`git diff --check` 実行結果 +image::images/git-diff-check.png[`git diff --check` 実行結果] +////////////////////////// If you run that command before committing, you can tell if you're about to commit whitespace issues that may annoy other developers. +////////////////////////// +コミットの前にこのコマンドを実行すれば、余計な空白文字をコミットしてしまって他の開発者に嫌がられることもなくなるでしょう。 +////////////////////////// Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible – don't code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don't commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. @@ -53,7 +109,16 @@ If some of the changes modify the same file, try to use `git add --patch` to par The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. <<_rewriting_history>> describes a number of useful Git tricks for rewriting history and interactively staging files – use these tools to help craft a clean and understandable history before sending the work to someone else. - +////////////////////////// +次に、コミットの単位が論理的に独立した変更となるようにしましょう。 +つまり、個々の変更内容を把握しやすくするということです。週末に五つの問題点を修正した大規模な変更を、月曜日にまとめてコミットするなどということは避けましょう。 +仮に週末の間にコミットできなかったとしても、ステージングエリアを活用して月曜日にコミット内容を調整することができます。修正した問題ごとにコミットを分割し、それぞれに適切なコメントをつければいいのです。 +もし別々の問題の修正で同じファイルを変更しているのなら、`git add --patch` を使ってその一部だけをステージすることもできます (詳しくは <<_interactive_staging>> で説明します)。 +すべての変更を同時に追加しさえすれば、一度にコミットしようが五つのコミットに分割しようがブランチの先端は同じ状態になります。あとから変更内容をレビューする他のメンバーのことも考えて、できるだけレビューしやすい状態でコミットするようにしましょう。 +こうしておけば、あとからその変更の一部だけを取り消したりするのにも便利です。 +<<_rewriting_history>> では、Git を使って歴史を書き換えたり対話的にファイルをステージしたりする方法を説明します。作業内容を誰かに送る前にその方法を使えば、きれいでわかりやすい歴史を作り上げることができます。 + +////////////////////////// The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that's no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. @@ -62,8 +127,17 @@ It's also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of ``I added tests for'' or ``Adding tests for,'' use ``Add tests for.'' Here is a template originally written by Tim Pope: +////////////////////////// +最後に注意しておきたいのが、コミットメッセージです。 +よりよいコミットメッセージを書く習慣を身に着けておくと、Git を使った共同作業をより簡単に行えるようになります。 +一般的な規則として、メッセージの最初には変更の概要を一行 (50 文字以内) にまとめた説明をつけるようにします。その後に空行をひとつ置いてからより詳しい説明を続けます。 +Git プロジェクトでは、その変更の動機やこれまでの実装との違いなどのできるだけ詳しい説明をつけることを推奨しています。参考にするとよいでしょう。 +また、メッセージでは命令形、現在形を使うようにしています。 +つまり ``私は○○のテストを追加しました (I added tests for)'' とか ``○○のテストを追加します (Adding tests for,)'' ではなく ``○○のテストを追加 (Add tests for.)'' 形式にするということです。 +Tim Pope が書いたテンプレート (の日本語訳) を以下に示します。 [source,text] +////////////////////////// ----- Short (50 chars or less) summary of changes @@ -83,28 +157,69 @@ Further paragraphs come after blank lines. preceded by a single space, with blank lines in between, but conventions vary here ----- +////////////////////////// +----- +短い (50 文字以下での) 変更内容のまとめ + +必要に応じた、より詳細な説明。72文字程度で折り返します。最初の +行がメールの件名、残りの部分がメールの本文だと考えてもよいでしょ +う。最初の行と詳細な説明の間には、必ず空行を入れなければなりま +せん (詳細説明がまったくない場合は空行は不要です)。空行がないと、 +rebase などがうまく動作しません。 +空行を置いて、さらに段落を続けることもできます。 + + - 箇条書きも可能 + + - 箇条書きの記号としては、主にハイフンやアスタリスクを使います。 + 箇条書き記号の前にはひとつ空白を入れ、各項目の間には空行を入 + れます。しかし、これ以外の流儀もいろいろあります。 +----- + +////////////////////////// If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages – try running `git log --no-merges` there to see what a nicely formatted project-commit history looks like. +////////////////////////// +すべてのコミットメッセージがこのようになっていれば、他の開発者との作業が非常に進めやすくなるでしょう。 +Git プロジェクトでは、このようにきれいに整形されたコミットメッセージを使っています。`git log --no-merges` を実行すれば、きれいに整形されたプロジェクトの歴史がどのように見えるかがわかります。 +////////////////////////// In the following examples, and throughout most of this book, for the sake of brevity this book doesn't have nicely-formatted messages like this; instead, we use the `-m` option to `git commit`. Do as we say, not as we do. +////////////////////////// +これ以降の例を含めて本書では、説明を簡潔にするためにこのような整形を省略します。そのかわりに `git commit` の `-m` オプションを使います。 +本書でのこのやり方をまねするのではなく、ここで説明した方式を使いましょう。 [[_private_team]] +////////////////////////// ==== Private Small Team +////////////////////////// +==== 非公開な小規模のチーム (((contributing, private small team))) +////////////////////////// The simplest setup you're likely to encounter is a private project with one or two other developers. ``Private,'' in this context, means closed-source – not accessible to the outside world. You and the other developers all have push access to the repository. +////////////////////////// +実際に遭遇するであろう環境のうち最も小規模なのは、非公開のプロジェクトで開発者が数名といったものです。 +ここでいう「非公開」とは、クローズドソースであるということ。つまり、チームのメンバー以外は見られないということです。 +チーム内のメンバーは全員、リポジトリへのプッシュ権限を持っています。 +////////////////////////// In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. Let's see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (The protocol messages have been replaced with `...` in these examples to shorten them somewhat.) +////////////////////////// +こういった環境では、今まで Subversion やその他の中央管理型システムを使っていたときとほぼ同じワークフローで作業を進めることができます。 +オフラインでコミットできたりブランチやマージが楽だったりといった Git ならではの利点はいかせますが、作業の流れ自体は今までとほぼ同じです。最大の違いは、マージが (コミット時にサーバー側で行われるのではなく) クライアント側で行われるということです。 +二人の開発者が共有リポジトリで開発を始めるときにどうなるかを見ていきましょう。 +最初の開発者 John が、リポジトリをクローンして変更を加え、それをローカルでコミットします (これ以降のメッセージでは、プロトコル関連のメッセージを `...` で省略しています)。 [source,console] +////////////////////////// ----- # John's Machine $ git clone john@githost:simplegit.git @@ -116,10 +231,26 @@ $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) ----- +////////////////////////// +----- +# John のマシン +$ git clone john@githost:simplegit.git +Initialized empty Git repository in /home/john/simplegit/.git/ +... +$ cd simplegit/ +$ vim lib/simplegit.rb +$ git commit -am 'removed invalid default value' +[master 738ee87] removed invalid default value + 1 files changed, 1 insertions(+), 1 deletions(-) +----- +////////////////////////// The second developer, Jessica, does the same thing – clones the repository and commits a change: +////////////////////////// +もう一人の開発者 Jessica も同様に、リポジトリをクローンして変更をコミットしました。 [source,console] +////////////////////////// ----- # Jessica's Machine $ git clone jessica@githost:simplegit.git @@ -131,10 +262,26 @@ $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) ----- +////////////////////////// +----- +# Jessica のマシン +$ git clone jessica@githost:simplegit.git +Initialized empty Git repository in /home/jessica/simplegit/.git/ +... +$ cd simplegit/ +$ vim TODO +$ git commit -am 'add reset task' +[master fbff5bc] add reset task + 1 files changed, 1 insertions(+), 0 deletions(-) +----- +////////////////////////// Now, Jessica pushes her work up to the server: +////////////////////////// +Jessica が作業内容をサーバーにプッシュします。 [source,console] +////////////////////////// ----- # Jessica's Machine $ git push origin master @@ -142,10 +289,22 @@ $ git push origin master To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master ----- +////////////////////////// +----- +# Jessica のマシン +$ git push origin master +... +To jessica@githost:simplegit.git + 1edee6b..fbff5bc master -> master +----- +////////////////////////// John tries to push his change up, too: +////////////////////////// +John も同様にプッシュしようとしました。 [source,console] +////////////////////////// ----- # John's Machine $ git push origin master @@ -153,11 +312,25 @@ To john@githost:simplegit.git ! [rejected] master -> master (non-fast forward) error: failed to push some refs to 'john@githost:simplegit.git' ----- +////////////////////////// +----- +# John のマシン +$ git push origin master +To john@githost:simplegit.git + ! [rejected] master -> master (non-fast forward) +error: failed to push some refs to 'john@githost:simplegit.git' +----- +////////////////////////// John isn't allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you're used to Subversion, because you'll notice that the two developers didn't edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica's changes and merge them in before he will be allowed to push: +////////////////////////// +John はプッシュできませんでした。Jessica が先にプッシュを済ませていたからです。 +Subversion になじみのある人には特に注目してほしいのですが、ここで John と Jessica が編集していたのは別々のファイルです。 +Subversion ならこのような場合はサーバー側で自動的にマージを行いますが、Git の場合はローカルでマージしなければなりません。 +John は、まず Jessica の変更内容を取得してマージしてからでないと、自分の変更をプッシュできないのです。 [source,console] ----- @@ -167,12 +340,22 @@ From john@githost:simplegit + 049d078...fbff5bc master -> origin/master ----- +////////////////////////// At this point, John's local repository looks something like this: +////////////////////////// +この時点で、John のローカルリポジトリはこのようになっています。 +////////////////////////// .John's divergent history. image::images/small-team-1.png[John's divergent history.] +////////////////////////// +.John の分岐した歴史 +image::images/small-team-1.png[John の分岐した歴史] +////////////////////////// John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: +////////////////////////// +John の手元に Jessica がプッシュした内容が届きましたが、さらにそれを彼自身の作業にマージしてからでないとプッシュできません。 [source,console] ----- @@ -182,12 +365,22 @@ Merge made by recursive. 1 files changed, 1 insertions(+), 0 deletions(-) ----- +////////////////////////// The merge goes smoothly – John's commit history now looks like this: +////////////////////////// +マージがうまくいきました。John のコミット履歴は次のようになります。 +////////////////////////// .John's repository after merging `origin/master`. image::images/small-team-2.png[John's repository after merging `origin/master`.] +////////////////////////// +.`origin/master` をマージしたあとの John のリポジトリ +image::images/small-team-2.png[`origin/master` をマージしたあとの John のリポジトリ] +////////////////////////// Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: +////////////////////////// +自分のコードが正しく動作することを確認した John は、変更内容をサーバーにプッシュします。 [source,console] ----- @@ -197,21 +390,41 @@ To john@githost:simplegit.git fbff5bc..72bbc59 master -> master ----- +////////////////////////// Finally, John's commit history looks like this: +////////////////////////// +最終的に、John のコミット履歴は以下のようになりました。 +////////////////////////// .John's history after pushing to the `origin` server. image::images/small-team-3.png[John's history after pushing to the `origin` server.] +////////////////////////// +.origin サーバーにプッシュした後の John の履歴 +image::images/small-team-3.png[origin サーバーにプッシュした後の John の履歴] +////////////////////////// In the meantime, Jessica has been working on a topic branch. She's created a topic branch called `issue54` and done three commits on that branch. She hasn't fetched John's changes yet, so her commit history looks like this: +////////////////////////// +一方そのころ、Jessica はトピックブランチで作業を進めていました。 +`issue54` というトピックブランチを作成した彼女は、そこで 3 回コミットをしました。 +彼女はまだ John の変更を取得していません。したがって、彼女のコミット履歴はこのような状態です。 +////////////////////////// .Jessica's topic branch. image::images/small-team-4.png[Jessica's topic branch.] +////////////////////////// +.Jessica のコミット履歴 +image::images/small-team-4.png[Jessica のコミット履歴] +////////////////////////// Jessica wants to sync up with John, so she fetches: +////////////////////////// +Jessica は John の作業を取り込もうとしました。 [source,console] +////////////////////////// ----- # Jessica's Machine $ git fetch origin @@ -219,15 +432,34 @@ $ git fetch origin From jessica@githost:simplegit fbff5bc..72bbc59 master -> origin/master ----- +////////////////////////// +----- +# Jessica のマシン +$ git fetch origin +... +From jessica@githost:simplegit + fbff5bc..72bbc59 master -> origin/master +----- +////////////////////////// That pulls down the work John has pushed up in the meantime. Jessica's history now looks like this: +////////////////////////// +これで、さきほど John がプッシュした内容が取り込まれました。Jessica の履歴は次のようになります。 +////////////////////////// .Jessica's history after fetching John's changes. image::images/small-team-5.png[Jessica's history after fetching John's changes.] +////////////////////////// +.John の変更を取り込んだ後の Jessica の履歴 +image::images/small-team-5.png[John の変更を取り込んだ後の Jessica の履歴] +////////////////////////// Jessica thinks her topic branch is ready, but she wants to know what she has to merge into her work so that she can push. She runs `git log` to find out: +////////////////////////// +Jessica のトピックブランチ上での作業が完了しました。そこで、自分の作業をプッシュする前に何をマージしなければならないのかを確認するため、 +彼女は `git log` コマンドを実行しました。 [source,console] ----- @@ -243,8 +475,11 @@ The `issue54..origin/master` syntax is a log filter that asks Git to only show t For now, we can see from the output that there is a single commit that John has made that Jessica has not merged in. If she merges `origin/master`, that is the single commit that will modify her local work. +////////////////////////// Now, Jessica can merge her topic work into her master branch, merge John's work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her master branch to integrate all this work: +////////////////////////// +Jessica はトピックブランチの内容を自分の master ブランチにマージし、同じく John の作業 (`origin/master`) も自分の `master` ブランチにマージして再び変更をサーバーにプッシュすることになります。まずは master ブランチに戻り、これまでの作業を統合できるようにします。 [source,console] ----- @@ -253,9 +488,14 @@ Switched to branch 'master' Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. ----- +////////////////////////// She can merge either `origin/master` or `issue54` first – they're both upstream, so the order doesn't matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: +////////////////////////// +`origin/master` と `issue54` のどちらからマージしてもかまいません。どちらも上流にあるので、マージする順序が変わっても結果は同じなのです。 +どちらの順でマージしても、最終的なスナップショットはまったく同じものになります。ただそこにいたる歴史が微妙に変わってくるだけです。 +彼女はまず `issue54` からマージすることにしました。 [source,console] ----- @@ -267,8 +507,12 @@ Fast forward 2 files changed, 6 insertions(+), 1 deletions(-) ----- +////////////////////////// No problems occur; as you can see it was a simple fast-forward. Now Jessica merges in John's work (`origin/master`): +////////////////////////// +何も問題は発生しません。ご覧の通り、単なる fast-forward です。 +次に Jessica は John の作業 (`origin/master`) をマージします。 [source,console] ----- @@ -279,12 +523,22 @@ Merge made by recursive. 1 files changed, 1 insertions(+), 1 deletions(-) ----- +////////////////////////// Everything merges cleanly, and Jessica's history looks like this: +////////////////////////// +こちらもうまく完了しました。Jessica の履歴はこのようになります。 +////////////////////////// .Jessica's history after merging John's changes. image::images/small-team-6.png[Jessica's history after merging John's changes.] +////////////////////////// +.John の変更をマージした後の Jessica の履歴 +image::images/small-team-6.png[John の変更をマージした後の Jessica の履歴] +////////////////////////// Now `origin/master` is reachable from Jessica's `master` branch, so she should be able to successfully push (assuming John hasn't pushed again in the meantime): +////////////////////////// +これで、Jessica の `master` ブランチから `origin/master` に到達可能となります。これで自分の変更をプッシュできるようになりました (この作業の間に John は何もプッシュしていなかったものとします)。 [source,console] ----- @@ -294,34 +548,69 @@ To jessica@githost:simplegit.git 72bbc59..8059c15 master -> master ----- +////////////////////////// Each developer has committed a few times and merged each other's work successfully. +////////////////////////// +各開発者が何度かコミットし、お互いの作業のマージも無事できました。 +////////////////////////// .Jessica's history after pushing all changes back to the server. image::images/small-team-7.png[Jessica's history after pushing all changes back to the server.] +////////////////////////// +.すべての変更をサーバーに書き戻した後の Jessica の履歴 +image::images/small-team-7.png[すべての変更をサーバーに書き戻した後の Jessica の履歴] +////////////////////////// That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it's ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like this: +////////////////////////// +これがもっとも単純なワークフローです。 +トピックブランチでしばらく作業を進め、統合できる状態になれば自分の master ブランチにマージする。 +他の開発者の作業を取り込む場合は、`origin/master` を取得してもし変更があればマージする。そして最終的にそれをサーバーの master ブランチにプッシュする。 +全体的な流れは次のようになります。 +////////////////////////// .General sequence of events for a simple multiple-developer Git workflow. image::images/small-team-flow.png[General sequence of events for a simple multiple-developer Git workflow.] +////////////////////////// +.複数開発者での Git を使ったシンプルな開発作業のイベントシーケンス +image::images/small-team-flow.png[複数開発者での Git を使ったシンプルな開発作業のイベントシーケンス] +////////////////////////// ==== Private Managed Team +////////////////////////// +==== 非公開で管理されているチーム (((contributing, private managed team))) +////////////////////////// In this next scenario, you'll look at contributor roles in a larger private group. You'll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. +////////////////////////// +次に扱うシナリオは、大規模な非公開のグループに貢献するものです。 +機能単位の小規模なグループで共同作業した結果を別のグループと統合するような環境での作業の進め方を学びましょう。 +////////////////////////// Let's say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. +////////////////////////// +John と Jessica が共同でとある機能を実装しており、Jessica はそれとは別の件で Josie とも作業をしているものとします。 +彼らの勤務先は統合マネージャー型のワークフローを採用しており、各グループの作業を統合する担当者が決まっています。メインリポジトリの `master` ブランチを更新できるのは統合担当者だけです。 +この場合、すべての作業はチームごとのブランチで行われ、後で統合担当者がまとめることになります。 +////////////////////////// Let's follow Jessica's workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: +////////////////////////// +では、Jessica の作業の流れを追っていきましょう。彼女は二つの機能を同時に実装しており、それぞれ別の開発者と共同作業をしています。 +すでに自分用のリポジトリをクローンしている彼女は、まず `featureA` の作業を始めることにしました。 +この機能用に新しいブランチを作成し、そこで作業を進めます。 [source,console] +////////////////////////// ----- # Jessica's Machine $ git checkout -b featureA @@ -331,9 +620,23 @@ $ git commit -am 'add limit to log function' [featureA 3300904] add limit to log function 1 files changed, 1 insertions(+), 1 deletions(-) ----- +////////////////////////// +----- +# Jessica のマシン +$ git checkout -b featureA +Switched to a new branch 'featureA' +$ vim lib/simplegit.rb +$ git commit -am 'add limit to log function' +[featureA 3300904] add limit to log function + 1 files changed, 1 insertions(+), 1 deletions(-) +----- +////////////////////////// At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn't have push access to the `master` branch – only the integrators do – so she has to push to another branch in order to collaborate with John: +////////////////////////// +自分の作業内容を John に渡すため、彼女は `featureA` ブランチへのコミットをサーバーにプッシュしました。 +Jessica には `master` ブランチへのプッシュをする権限はありません。そこにプッシュできるのは統合担当者だけなのです。そこで、John との共同作業用の別のブランチにプッシュします。 [source,console] ----- @@ -343,19 +646,35 @@ To jessica@githost:simplegit.git * [new branch] featureA -> featureA ----- +////////////////////////// Jessica e-mails John to tell him that she's pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server's `master` branch: +////////////////////////// +Jessica は John に「私の作業を `featureA` というブランチにプッシュしておいたので、見てね」というメールを送りました。 +John からの返事を待つ間、Jessica はもう一方の `featureB` の作業を Josie とはじめます。 +まず最初に、この機能用の新しいブランチをサーバーの `master` ブランチから作ります。 [source,console] +////////////////////////// ----- # Jessica's Machine $ git fetch origin $ git checkout -b featureB origin/master Switched to a new branch 'featureB' ----- +////////////////////////// +----- +# Jessicaのマシン +$ git fetch origin +$ git checkout -b featureB origin/master +Switched to a new branch 'featureB' +----- +////////////////////////// Now, Jessica makes a couple of commits on the `featureB` branch: +////////////////////////// +そして Jessica は、`featureB` ブランチに何度かコミットしました。 [source,console] ----- @@ -369,14 +688,26 @@ $ git commit -am 'add ls-files' 1 files changed, 5 insertions(+), 0 deletions(-) ----- +////////////////////////// Jessica's repository looks like this: +////////////////////////// +Jessica のリポジトリはこのようになっています。 +////////////////////////// .Jessica's initial commit history. image::images/managed-team-1.png[Jessica's initial commit history.] +////////////////////////// +.Jessica のコミット履歴 +image::images/managed-team-1.png[Jessica のコミット履歴] +////////////////////////// She's ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie's changes down with `git fetch`: +////////////////////////// +この変更をプッシュしようと思ったそのときに、Josie から「私の作業を `featureBee` というブランチにプッシュしておいたので、見てね」というメールがやってきました。 +Jessica はまずこの変更をマージしてからでないとサーバーにプッシュすることはできません。 +そこで、まず Josie の変更を `git fetch` で取得しました。 [source,console] ----- @@ -386,7 +717,10 @@ From jessica@githost:simplegit * [new branch] featureBee -> origin/featureBee ----- +////////////////////////// Jessica can now merge this into the work she did with `git merge`: +////////////////////////// +次に、`git merge` でこの内容を自分の作業にマージします。 [source,console] ----- @@ -397,8 +731,12 @@ Merge made by recursive. 1 files changed, 4 insertions(+), 0 deletions(-) ----- +////////////////////////// There is a bit of a problem – she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: +////////////////////////// +ここでちょっとした問題が発生しました。彼女は、手元の `featureB` ブランチの内容をサーバーの `featureBee` ブランチにプッシュしなければなりません。 +このような場合は、`git push` コマンドでローカルブランチ名に続けてコロン (:) を書き、その後にリモートブランチ名を指定します。 [source,console] ----- @@ -408,12 +746,21 @@ To jessica@githost:simplegit.git fba9af8..cd685d1 featureB -> featureBee ----- +////////////////////////// This is called a _refspec_. See <<_refspec>> for a more detailed discussion of Git refspecs and different things you can do with them. Also notice the `-u` flag; this is short for `--set-upstream`, which configures the branches for easier pushing and pulling later. +////////////////////////// +これは _refspec_ と呼ばれます。 +<<_refspec>> で、Git の refspec の詳細とそれで何ができるのかを説明します。 +また、 `-u` オプションが使われていることにも注意しましょう。これは `--set-upstream` オプションの省略形で、のちのちブランチのプッシュ・プルで楽をするための設定です。 +////////////////////////// Next, John e-mails Jessica to say he's pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: +////////////////////////// +さて、John からメールが返ってきました。「私の変更も `featureA` ブランチにプッシュしておいたので、確認よろしく」とのことです。 +彼女は `git fetch` でその変更を取り込みます。 [source,console] ----- @@ -423,7 +770,10 @@ From jessica@githost:simplegit 3300904..aad881d featureA -> origin/featureA ----- +////////////////////////// Then, she can see what has been changed with `git log`: +////////////////////////// +そして、`git log` で何が変わったのかを確認します。 [source,console] ----- @@ -435,7 +785,10 @@ Date: Fri May 29 19:57:33 2009 -0700 changed log output to 30 from 25 ----- +////////////////////////// Finally, she merges John's work into her own `featureA` branch: +////////////////////////// +確認を終えた彼女は、John の作業を自分の `featureA` ブランチにマージしました。 [source,console] ----- @@ -448,7 +801,10 @@ Fast forward 1 files changed, 9 insertions(+), 1 deletions(-) ----- +////////////////////////// Jessica wants to tweak something, so she commits again and then pushes this back up to the server: +////////////////////////// +Jessica はもう少し手を入れたいところがあったので、再びコミットしてそれをサーバーにプッシュします。 [source,console] ----- @@ -461,36 +817,74 @@ To jessica@githost:simplegit.git 3300904..774b3ed featureA -> featureA ----- +////////////////////////// Jessica's commit history now looks something like this: +////////////////////////// +Jessica のコミット履歴は、この時点で以下のようになります。 +////////////////////////// .Jessica's history after committing on a feature branch. image::images/managed-team-2.png[Jessica's history after committing on a feature branch.] +////////////////////////// +.Jessica がブランチにコミットした後のコミット履歴 +image::images/managed-team-2.png[Jessica がブランチにコミットした後のコミット履歴] +////////////////////////// Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After the integrators merge these branches into the mainline, a fetch will bring down the new merge commit, making the history look like this: +////////////////////////// +Jessica、Josie そして John は、統合担当者に「`featureA` ブランチと `featureBee` ブランチは本流に統合できる状態になりました」と報告しました。 +これらのブランチを担当者が本流に統合した後でそれを取得すると、マージコミットが新たに追加されてこのような状態になります。 +////////////////////////// .Jessica's history after merging both her topic branches. image::images/managed-team-3.png[Jessica's history after merging both her topic branches.] +////////////////////////// +.Jessica が両方のトピックブランチをマージしたあとのコミット履歴 +image::images/managed-team-3.png[Jessica が両方のトピックブランチをマージしたあとのコミット履歴] +////////////////////////// Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like this: +////////////////////////// +Git へ移行するグループが続出しているのも、この「複数チームの作業を並行して進め、後で統合できる」という機能のおかげです。 +小さなグループ単位でリモートブランチを使った共同作業ができ、しかもそれがチーム全体の作業を妨げることがない。これは Git の大きな利点です。 +ここで見たワークフローをまとめると、次のようになります。 +////////////////////////// .Basic sequence of this managed-team workflow. image::images/managed-team-flow.png[Basic sequence of this managed-team workflow.] +////////////////////////// +.管理されたチームでのワークフローの基本的な流れ +image::images/managed-team-flow.png[管理されたチームでのワークフローの基本的な流れ] [[_public_project]] +////////////////////////// ==== Forked Public Project +////////////////////////// +==== フォークされた公開プロジェクト (((contributing, public small project))) +////////////////////////// Contributing to public projects is a bit different. Because you don't have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. Many hosting sites support this (including GitHub, BitBucket, Google Code, repo.or.cz, and others), and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. - +////////////////////////// +公開プロジェクトに貢献するとなると、また少し話が変わってきます。 +そのプロジェクトのブランチを直接更新できる権限はないでしょうから、何か別の方法でメンテナに接触する必要があります。 +まずは、フォークをサポートしている Git ホスティングサービスでフォークを使って貢献する方法を説明します。 +多くの Git ホスティングサービス(GitHub、 BitBucket、 Google Code、 repo.or.cz など) がフォークをサポートしており、メンテナの多くはこの方式での協力を期待しています。 +そしてこの次のセクションでは、メールでパッチを送る形式での貢献について説明します。 + +////////////////////////// First, you'll probably want to clone the main repository, create a topic branch for the patch or patch series you're planning to contribute, and do your work there. The sequence looks basically like this: +////////////////////////// +まずはメインリポジトリをクローンしましょう。そしてパッチ用のトピックブランチを作り、そこで作業を進めます。 +このような流れになります。 [source,console] ----- @@ -504,22 +898,36 @@ $ git commit ----- [NOTE] +////////////////////////// ==== You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review – see <<_rewriting_history>> for more information about interactive rebasing. ==== +////////////////////////// +==== +`rebase -i` を使ってすべての作業をひとつのコミットにまとめたり、メンテナがレビューしやすいようにコミット内容を整理したりといったことも行うかもしれません。対話的なリベースの方法については <<_rewriting_history>> で詳しく説明します。 +==== +////////////////////////// When your branch work is finished and you're ready to contribute it back to the maintainers, go to the original project page and click the ``Fork'' button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: +////////////////////////// +ブランチでの作業を終えてメンテナに渡せる状態になったら、プロジェクトのページに行って ``Fork'' ボタンを押し、自分用に書き込み可能なフォークを作成します。 +このリポジトリの URL を追加のリモートとして設定しなければなりません。ここでは `myfork` という名前にしました。 [source,console] ----- $ git remote add myfork (url) ----- +////////////////////////// Then you need to push your work up to it. It's easiest to push the topic branch you're working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn't accepted or is cherry picked, you don't have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you'll eventually get it back via pulling from their repository anyhow: +////////////////////////// +今後、自分の作業内容はここにプッシュすることになります。 +変更を master ブランチにマージしてからそれをプッシュするよりも、今作業中の内容をそのままトピックブランチにプッシュするほうが簡単でしょう。 +もしその変更が受け入れられなかったり一部だけが取り込まれたりした場合に、master ブランチを巻き戻す必要がなくなるからです。メンテナがあなたの作業をマージするかリベースするかあるいは一部だけ取り込むか、いずれにせよあなたはその結果をリポジトリから再度取り込むことになります。 [source,console] ----- @@ -527,11 +935,19 @@ $ git push -u myfork featureA ----- (((git commands, request-pull))) +////////////////////////// When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website – GitHub has it's own Pull Request mechanism that we'll go over in <<_github>> – or you can run the `git request-pull` command and e-mail the output to the project maintainer manually. +////////////////////////// +自分用のフォークに作業内容をプッシュし終えたら、それをメンテナに伝えましょう。 +これは、よく「プルリクエスト」と呼ばれるもので、ウェブサイトから実行する (GutHub には Pull request を行う独自の仕組みがあります。詳しくは <<_github>> で説明します) こともできれば、 `git request-pull` コマンドの出力をプロジェクトのメンテナにメールで送ることもできます。 +////////////////////////// The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you're asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she's done two commits on the topic branch she just pushed up, she can run this: +////////////////////////// +`request-pull` コマンドには、トピックブランチをプルしてもらいたい先のブランチとその Git リポジトリの URL を指定します。すると、プルしてもらいたい変更の概要が出力されます。 +たとえば Jessica が John にプルリクエストを送ろうとしたとしましょう。彼女はすでにトピックブランチ上で 2 回のコミットを済ませています。 [source,console] ----- @@ -552,12 +968,21 @@ Jessica Smith (2): 1 files changed, 9 insertions(+), 1 deletions(-) ----- +////////////////////////// The output can be sent to the maintainer–it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. +////////////////////////// +この出力をメンテナに送れば「どのブランチからフォークしたのか、どういったコミットをしたのか、そしてそれをどこにプルしてほしいのか」を伝えることができます。 +////////////////////////// On a project for which you're not the maintainer, it's generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they're rejected. Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don't continue working on the topic branch you just pushed up – start over from the main repository's `master` branch: +////////////////////////// +自分がメンテナになっていないプロジェクトで作業をする場合は、`master` ブランチでは常に `origin/master` を追いかけるようにし、自分の作業はトピックブランチで進めていくほうが楽です。そうすれば、パッチが拒否されたときも簡単にそれを捨てることができます。 +また、作業内容ごとにトピックブランチを分離しておけば、本流のリポジトリが更新されてパッチがうまく適用できなくなったとしても簡単にリベースできるようになります。 +たとえば、さきほどのプロジェクトに対して別の作業をすることになったとしましょう。その場合は、先ほどプッシュしたトピックブランチを使うのではなく、メインリポジトリの `master` ブランチから新たなトピックブランチを作成します。 +////////////////////////// [source,console] ----- $ git checkout -b featureB origin/master @@ -567,14 +992,35 @@ $ git push myfork featureB # (email maintainer) $ git fetch origin ----- +////////////////////////// +[source,console] +----- +$ git checkout -b featureB origin/master +# (作業) +$ git commit +$ git push myfork featureB +# (メンテナにメールを送る) +$ git fetch origin +----- +////////////////////////// Now, each of your topics is contained within a silo – similar to a patch queue – that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other, like so: +////////////////////////// +これで、それぞれのトピックがサイロに入った状態になりました。お互いのトピックが邪魔しあったり依存しあったりすることなく、それぞれ個別に書き換えやリベースが可能となります。詳しくは以下を参照ください。 +////////////////////////// .Initial commit history with `featureB` work. image::images/public-small-1.png[Initial commit history with `featureB` work.] +////////////////////////// +.`featureB` に関する作業のコミット履歴 +image::images/public-small-1.png[`featureB` に関する作業のコミット履歴] +////////////////////////// Let's say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: +////////////////////////// +プロジェクトのメンテナが、他の大量のパッチを適用したあとであなたの最初のパッチを適用しようとしました。しかしその時点でパッチはすでにそのままでは適用できなくなっています。 +こんな場合は、そのブランチを `origin/master` の先端にリベースして衝突を解決させ、あらためて変更内容をメンテナに送ります。 [source,console] ----- @@ -583,21 +1029,38 @@ $ git rebase origin/master $ git push -f myfork featureA ----- +////////////////////////// This rewrites your history to now look like <>. +////////////////////////// +これで、あなたの歴史は <> のように書き換えられました。 [[psp_b]] +////////////////////////// .Commit history after `featureA` work. image::images/public-small-2.png[Commit history after `featureA` work.] +////////////////////////// +.`featureA` の作業を終えた後のコミット履歴 +image::images/public-small-2.png[`featureA` の作業を終えた後のコミット履歴] +////////////////////////// Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn't a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). +////////////////////////// +ブランチをリベースしたので、プッシュする際には `-f` を指定しなければなりません。これは、サーバー上の `featureA` ブランチをその直系の子孫以外のコミットで上書きするためです。 +別のやり方として、今回の作業を別のブランチ (`featureAv2` など) にプッシュすることもできます。 +////////////////////////// Let's look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You'll also take this opportunity to move the work to be based off the project's current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: +////////////////////////// +もうひとつ別のシナリオを考えてみましょう。あなたの二番目のブランチを見たメンテナが、その考え方は気に入ったものの細かい実装をちょっと変更してほしいと連絡してきました。 +この場合も、プロジェクトの `master` ブランチから作業を進めます。 +現在の `origin/master` から新たにブランチを作成し、そこに `featureB` ブランチの変更を押し込み、もし衝突があればそれを解決し、実装をちょっと変更してからそれを新しいブランチとしてプッシュします。 (((git commands, merge, squash))) [source,console] +////////////////////////// ----- $ git checkout -b featureBv2 origin/master $ git merge --no-commit --squash featureB @@ -605,28 +1068,61 @@ $ git merge --no-commit --squash featureB $ git commit $ git push myfork featureBv2 ----- +////////////////////////// +----- +$ git checkout -b featureBv2 origin/master +$ git merge --no-commit --squash featureB +# (実装をちょっと変更する) +$ git commit +$ git push myfork featureBv2 +----- +////////////////////////// The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you're on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. +////////////////////////// +`--squash` オプションは、マージしたいブランチでのすべての作業をひとつのコミットにまとめ、それを現在のブランチの先頭にマージします。 +`--no-commit` オプションは、自動的にコミットを記録しないよう Git に指示しています。 +こうすれば、別のブランチのすべての変更を取り込んでさらに手元で変更を加えたものを新しいコミットとして記録できるのです。 +////////////////////////// Now you can send the maintainer a message that you've made the requested changes and they can find those changes in your `featureBv2` branch. +////////////////////////// +そして、メンテナに「言われたとおりのちょっとした変更をしたものが `featureBv2` ブランチにあるよ」と連絡します。 +////////////////////////// .Commit history after `featureBv2` work. image::images/public-small-3.png[Commit history after `featureBv2` work.] +////////////////////////// +.`featureBv2` の作業を終えた後のコミット履歴 +image::images/public-small-3.png[`featureBv2` の作業を終えた後のコミット履歴] [[_project_over_email]] +////////////////////////// ==== Public Project over E-Mail +////////////////////////// +==== メールを使った公開プロジェクトへの貢献 (((contributing, public large project))) +////////////////////////// Many projects have established procedures for accepting patches – you'll need to check the specific rules for each project, because they will differ. Since there are several older, larger projects which accept patches via a developer mailing list, we'll go over an example of that now. +////////////////////////// +多くのプロジェクトでは、パッチを受け付ける手続きが確立されています。プロジェクトによっていろいろ異なるので、まずはそのプロジェクト固有のルールがないかどうか確認しましょう。 +また、長期間続いている大規模なプロジェクトには、開発者用メーリングリストでパッチを受け付けているものがいくつかあります。そこで、ここではそういったプロジェクトを例にとって話を進めます。 +////////////////////////// The workflow is similar to the previous use case – you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: +////////////////////////// +実際の作業の流れは先ほどとほぼ同じで、作業する内容ごとにトピックブランチを作成することになります。 +違うのは、パッチをプロジェクトに提供する方法です。 +プロジェクトをフォークし、自分用のリポジトリにプッシュするのではなく、個々のコミットについてメールを作成し、それを開発者用メーリングリストに投稿します。 [source,console] +////////////////////////// ----- $ git checkout -b topicA # (work) @@ -634,11 +1130,24 @@ $ git commit # (work) $ git commit ----- +////////////////////////// +----- +$ git checkout -b topicA +# (作業) +$ git commit +# (作業) +$ git commit +----- (((git commands, format-patch))) +////////////////////////// Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list – it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly. +////////////////////////// +これで二つのコミットができあがりました。これらをメーリングリストに投稿します。 +`git format-patch` を使うと mbox 形式のファイルが作成されるので、これをメーリングリストに送ることができます。このコマンドは、コミットメッセージの一行目を件名、残りのコミットメッセージとコミット内容のパッチを本文に書いたメールを作成します。 +これのよいところは、`format-patch` で作成したメールからパッチを適用すると、すべてのコミット情報が適切に維持されるというところです。 [source,console] ----- @@ -647,9 +1156,14 @@ $ git format-patch -M origin/master 0002-changed-log-output-to-30-from-25.patch ----- +////////////////////////// The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: +////////////////////////// +`format-patch` コマンドは、できあがったパッチファイルの名前を出力します。 +`-M` スイッチは、名前が変わったことを検出するためのものです。 +できあがったファイルは次のようになります。 [source,console] ----- @@ -682,17 +1196,31 @@ index 76f47bc..f9815f1 100644 2.1.0 ----- +////////////////////////// You can also edit these patch files to add more information for the e-mail list that you don't want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `diff --git` line), then developers can read it; but applying the patch excludes it. +////////////////////////// +このファイルを編集して、コミットメッセージには書けなかったような情報をメーリングリスト用に追加することもできます。 +`---` の行とパッチの開始位置 ( `diff --git` の行) の間にメッセージを書くと、メールを受信した人はそれを読むことができますが、パッチからは除外されます。 +////////////////////////// To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with ``smarter'' clients that don't preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. We'll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent we know best; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. +////////////////////////// +これをメーリングリストに投稿するには、メールソフトにファイルの内容を貼り付けるか、あるいはコマンドラインのプログラムを使います。 +ファイルの内容をコピーして貼り付けると「かしこい」メールソフトが勝手に改行の位置を変えてしまうなどの問題が起こりがちです。 +ありがたいことに Git には、きちんとしたフォーマットのパッチを IMAP で送ることを支援するツールが用意されています。これを使うと便利です。 +ここでは、パッチを Gmail で送る方法を説明しましょう。というのも、一番よく知っているメールソフトが Gmail だからです。さまざまなメールソフトでの詳細なメール送信方法が、Git ソースコードにある `Documentation/SubmittingPatches` の最後に載っています。 (((git commands, config)))(((email))) +////////////////////////// First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually, but in the end your config file should look something like this: +////////////////////////// +まず。`~/.gitconfig` ファイルの imap セクションを設定します。 +それぞれの値を `git config` コマンドで順に設定してもかまいませんし、このファイルに手で書き加えてもかまいません。最終的に、設定ファイルは次のようになります。 [source,ini] ----- @@ -705,8 +1233,12 @@ You can set each value separately with a series of `git config` commands, or you sslverify = false ----- +////////////////////////// If your IMAP server doesn't use SSL, the last two lines probably aren't necessary, and the host value will be `imap://` instead of `imaps://`. When that is set up, you can use `git send-email` to place the patch series in the Drafts folder of the specified IMAP server: +////////////////////////// +IMAP サーバーで SSL を使っていない場合は、最後の二行はおそらく不要でしょう。そして host のところが `imaps://` ではなく `imap://` となります。 +ここまでの設定が終われば、`git send-email` を実行して IMAP サーバーの Drafts フォルダにパッチを置くことができるようになります。 [source,console] ----- @@ -719,7 +1251,10 @@ Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y ----- +////////////////////////// Then, Git spits out a bunch of log information looking something like this for each patch you're sending: +////////////////////////// +Git はその後、各パッチについてこのようなログ情報をはき出すはずです。 [source,text] ----- @@ -739,10 +1274,21 @@ References: Result: OK ----- +////////////////////////// At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you're sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. +////////////////////////// +あとは、Drafts フォルダに移動して To フィールドをメーリングリストのアドレスに変更し (おそらく CC には担当メンテなのアドレスを入れ)、送信できるようになりました。 +////////////////////////// ==== Summary +////////////////////////// +==== まとめ +////////////////////////// This section has covered a number of common workflows for dealing with several very different types of Git projects you're likely to encounter, and introduced a couple of new tools to help you manage this process. Next, you'll see how to work the other side of the coin: maintaining a Git project. You'll learn how to be a benevolent dictator or integration manager. +////////////////////////// +このセクションでは、今後みなさんが遭遇するであろうさまざまな形式の Git プロジェクトについて、関わっていくための作業手順を説明しました。そして、その際に使える新兵器もいくつか紹介しました。 +次はもう一方の側、つまり Git プロジェクトを運営する側について見ていきましょう。 +慈悲深い独裁者、あるいは統合マネージャーとしての作業手順を説明します。 diff --git a/book/05-distributed-git/sections/diff-contributing.htm b/book/05-distributed-git/sections/diff-contributing.htm new file mode 100644 index 00000000..127282c2 --- /dev/null +++ b/book/05-distributed-git/sections/diff-contributing.htm @@ -0,0 +1,4503 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\sections\contributing.asc
.1# Distributed Git # 1[[_contributing_project]] 
2  
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you. 
4  
5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. 
6  
7## Distributed Workflows ## 
8  
9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub — that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. 
10  
11### Centralized Workflow ### 
12  
13In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). 
14  
15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
17  
18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. 
19  
20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with. 
22  
23### Integration-Manager Workflow ### 
24  
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2): 
26  
271. The project maintainer pushes to their public repository. 
282. A contributor clones that repository and makes changes. 
293. The contributor pushes to their own public copy. 
304. The contributor sends the maintainer an e-mail asking them to pull changes. 
315. The maintainer adds the contributor’s repo as a remote and merges locally. 
326. The maintainer pushes merged changes to the main repository. 
33  
34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
36  
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. 
38  
39### Dictator and Lieutenants Workflow ### 
40  
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3): 
42  
431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator. 
442. Lieutenants merge the developers’ topic branches into their master branch. 
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 
464. The dictator pushes their master to the reference repository so the other developers can rebase on it. 
47  
48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
50  
51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. 
52  
53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 
54  
55## Contributing to a Project ## 2=== Contributing to a Project 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58 3 
. 4(((contributing)))
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method.5The main difficulty with describing how to contribute to a project is that there are a huge number of variations on how it's done. Because Git is very flexible, people can and do work together in many ways, and it's problematic to describe how you should contribute every project is a bit different. Some of the variables involved are active contributor count, chosen workflow, your commit access, and possibly the external contribution method.
60 6 
.61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid?7The first variable is active contributor count how many users are actively contributing code to this project, and how often? In many instances, you'll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For larger companies or projects, the number of developers could be in the thousands, with hundreds or thousands of commits coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your commits valid?
62 8 
.63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 9The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first?  
64 10 
.65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute?11The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don't. If you don't have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute?
66 12 
.67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples.13All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. We'll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples.
68 14 
. 15[[_commit_guidelines]]
69### Commit Guidelines ### 16==== Commit Guidelines 
70 17 
.71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches you can read it in the Git source code in the `Documentation/SubmittingPatches` file.18Before we start looking at the specific use cases, here's a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches you can read it in the Git source code in the `Documentation/SubmittingPatches` file.
72 19 
. 20(((git commands, diff, check)))
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 21First, you don't want to submit any whitespace errors. Git provides an easy way to check for this before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. 
74 22 
.75    $ git diff --check 23.Output of `git diff --check`. 
76    lib/simplegit.rb:5: trailing whitespace. 24image::images/git-diff-check.png[Output of `git diff --check`.] 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82 25 
.83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers.26If you run that command before committing, you can tell if you're about to commit whitespace issues that may annoy other developers.
84 27 
.85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files use these tools to help craft a clean and understandable history.28Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible don't code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don't commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in <<_interactive_staging>>). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. <<_rewriting_history>> describes a number of useful Git tricks for rewriting history and interactively staging files use these tools to help craft a clean and understandable history before sending the work to someone else.
86 29 
.87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 30The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that's no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior this is a good guideline to follow. It's also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of ``I added tests for'' or ``Adding tests for,'' use ``Add tests for.'' 
88Here is a template originally written by Tim Pope at tpope.net:31Here is a template originally written by Tim Pope:
89 32 
. 33[source,text]
 34-----
90    Short (50 chars or less) summary of changes35Short (50 chars or less) summary of changes
91 36 
.92    More detailed explanatory text, if necessary.  Wrap it to about 72 37More detailed explanatory text, if necessary.  Wrap it to 
93    characters or so.  In some contexts, the first line is treated as the 38about 72 characters or so.  In some contexts, the first 
 39line is treated as the subject of an email and the rest of
94    subject of an email and the rest of the text as the body.  The blank 40the text as the body.  The blank line separating the 
95    line separating the summary from the body is critical (unless you omit 41summary from the body is critical (unless you omit the body 
96    the body entirely); tools like rebase can get confused if you run the 42entirely); tools like rebase can get confused if you run 
97    two together.43the two together.
98 44 
.99    Further paragraphs come after blank lines.45Further paragraphs come after blank lines.
100 46 
.101     - Bullet points are okay, too47  - Bullet points are okay, too
102 48 
.103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 49  - Typically a hyphen or asterisk is used for the bullet, 
104       single space, with blank lines in between, but conventions vary here 50    preceded by a single space, with blank lines in 
 51    between, but conventions vary here
 52-----
105 53 
.106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like.54If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages try running `git log --no-merges` there to see what a nicely formatted project-commit history looks like.
107 55 
.108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do.56In the following examples, and throughout most of this book, for the sake of brevity this book doesn't have nicely-formatted messages like this; instead, we use the `-m` option to `git commit`. Do as we say, not as we do.
109 57 
. 58[[_private_team]]
110### Private Small Team ### 59==== Private Small Team 
111 60 
. 61(((contributing, private small team)))
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source not read-accessible to the outside world. You and the other developers all have push access to the repository.62The simplest setup you're likely to encounter is a private project with one or two other developers. ``Private,'' in this context, means closed-source not accessible to the outside world. You and the other developers all have push access to the repository.
113 63 
.114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 64In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time.  
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.)65Let's see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (The protocol messages have been replaced with `...` in these examples to shorten them somewhat.)
116 66 
. 67[source,console]
 68-----
117    # John's Machine69# John's Machine
118    $ git clone john@githost:simplegit.git70$ git clone john@githost:simplegit.git
119    Initialized empty Git repository in /home/john/simplegit/.git/71Initialized empty Git repository in /home/john/simplegit/.git/
120    ...72...
121    $ cd simplegit/73$ cd simplegit/
122    $ vim lib/simplegit.rb74$ vim lib/simplegit.rb
123    $ git commit -am 'removed invalid default value'75$ git commit -am 'removed invalid default value'
124    [master 738ee87] removed invalid default value76[master 738ee87] removed invalid default value
125     1 files changed, 1 insertions(+), 1 deletions(-)77 1 files changed, 1 insertions(+), 1 deletions(-)
 78-----
126 79 
.127The second developer, Jessica, does the same thing clones the repository and commits a change:80The second developer, Jessica, does the same thing clones the repository and commits a change:
128 81 
. 82[source,console]
 83-----
129    # Jessica's Machine84# Jessica's Machine
130    $ git clone jessica@githost:simplegit.git85$ git clone jessica@githost:simplegit.git
131    Initialized empty Git repository in /home/jessica/simplegit/.git/86Initialized empty Git repository in /home/jessica/simplegit/.git/
132    ...87...
133    $ cd simplegit/88$ cd simplegit/
134    $ vim TODO89$ vim TODO
135    $ git commit -am 'add reset task'90$ git commit -am 'add reset task'
136    [master fbff5bc] add reset task91[master fbff5bc] add reset task
137     1 files changed, 1 insertions(+), 0 deletions(-)92 1 files changed, 1 insertions(+), 0 deletions(-)
 93-----
138 94 
139Now, Jessica pushes her work up to the server:95Now, Jessica pushes her work up to the server:
140 96 
. 97[source,console]
 98-----
141    # Jessica's Machine99# Jessica's Machine
142    $ git push origin master100$ git push origin master
143    ...101...
144    To jessica@githost:simplegit.git102To jessica@githost:simplegit.git
145       1edee6b..fbff5bc  master -> master103   1edee6b..fbff5bc  master -> master
 104-----
146 105 
147John tries to push his change up, too:106John tries to push his change up, too:
148 107 
. 108[source,console]
 109-----
149    # John's Machine110# John's Machine
150    $ git push origin master111$ git push origin master
151    To john@githost:simplegit.git112To john@githost:simplegit.git
152     ! [rejected]        master -> master (non-fast forward)113 ! [rejected]        master -> master (non-fast forward)
153    error: failed to push some refs to 'john@githost:simplegit.git'114error: failed to push some refs to 'john@githost:simplegit.git'
 115-----
154 116 
.155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push:117John isn't allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you're used to Subversion, because you'll notice that the two developers didn't edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica's changes and merge them in before he will be allowed to push:
156 118 
. 119[source,console]
 120-----
157    $ git fetch origin121$ git fetch origin
158    ...122...
159    From john@githost:simplegit123From john@githost:simplegit
160     + 049d078...fbff5bc master     -> origin/master124 + 049d078...fbff5bc master     -> origin/master
 125-----
161 126 
.162At this point, John’s local repository looks something like Figure 5-4. 127At this point, John's local repository looks something like this: 
163 128 
.164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
 129.John's divergent history.
 130image::images/small-team-1.png[John's divergent history.]
166 131 
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push:132John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push:
168 133 
. 134[source,console]
 135-----
169    $ git merge origin/master136$ git merge origin/master
170    Merge made by recursive.137Merge made by recursive.
171     TODO |    1 +138 TODO |    1 +
172     1 files changed, 1 insertions(+), 0 deletions(-)139 1 files changed, 1 insertions(+), 0 deletions(-)
 140-----
173 141 
.174The merge goes smoothly John’s commit history now looks like Figure 5-5. 142The merge goes smoothly John's commit history now looks like this: 
175 143 
.176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
 144.John's repository after merging `origin/master`.
 145image::images/small-team-2.png[John's repository after merging `origin/master`.]
178 146 
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server:147Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server:
180 148 
. 149[source,console]
 150-----
181    $ git push origin master151$ git push origin master
182    ...152...
183    To john@githost:simplegit.git153To john@githost:simplegit.git
184       fbff5bc..72bbc59  master -> master154   fbff5bc..72bbc59  master -> master
 155-----
185 156 
.186Finally, John’s commit history looks like Figure 5-6. 157Finally, John's commit history looks like this: 
187 158 
.188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
 159.John's history after pushing to the `origin` server.
 160image::images/small-team-3.png[John's history after pushing to the `origin` server.]
190 161 
.191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 162In the meantime, Jessica has been working on a topic branch. She's created a topic branch called `issue54` and done three commits on that branch. She hasn't fetched John's changes yet, so her commit history looks like this: 
192 163 
.193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
 164.Jessica's topic branch.
 165image::images/small-team-4.png[Jessica's topic branch.]
195 166 
196Jessica wants to sync up with John, so she fetches:167Jessica wants to sync up with John, so she fetches:
197 168 
. 169[source,console]
 170-----
198    # Jessica's Machine171# Jessica's Machine
199    $ git fetch origin172$ git fetch origin
200    ...173...
201    From jessica@githost:simplegit174From jessica@githost:simplegit
202       fbff5bc..72bbc59  master     -> origin/master175   fbff5bc..72bbc59  master     -> origin/master
 176-----
203 177 
.204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 178That pulls down the work John has pushed up in the meantime. Jessica's history now looks like this: 
205 179 
.206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
 180.Jessica's history after fetching John's changes.
 181image::images/small-team-5.png[Jessica's history after fetching John's changes.]
208 182 
.209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out:183Jessica thinks her topic branch is ready, but she wants to know what she has to merge into her work so that she can push. She runs `git log` to find out:
210 184 
. 185[source,console]
 186-----
211    $ git log --no-merges origin/master ^issue54 187$ git log --no-merges issue54..origin/master 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016188commit 738ee872852dfaa9d6634e0dea7a324040193016
213    Author: John Smith <jsmith@example.com>189Author: John Smith <jsmith@example.com>
214    Date:   Fri May 29 16:01:27 2009 -0700190Date:   Fri May 29 16:01:27 2009 -0700
215 191 
.216        removed invalid default value192   removed invalid default value
 193-----
 194 
 195The `issue54..origin/master` syntax is a log filter that asks Git to only show the list of commits that are on the latter branch (in this case `origin/master`) that are not on the first branch (in this case `issue54`). We'll go over this syntax in detail in <<_commit_ranges>>.
 196 
 197For now, we can see from the output that there is a single commit that John has made that Jessica has not merged in. If she merges `origin/master`, that is the single commit that will modify her local work.
217 198 
.218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work:199Now, Jessica can merge her topic work into her master branch, merge John's work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her master branch to integrate all this work:
219 200 
. 201[source,console]
 202-----
220    $ git checkout master203$ git checkout master
221    Switched to branch "master" 204Switched to branch 'master' 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.205Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
 206-----
223 207 
.224She can merge either `origin/master` or `issue54` first they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first:208She can merge either `origin/master` or `issue54` first they're both upstream, so the order doesn't matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first:
225 209 
. 210[source,console]
 211-----
226    $ git merge issue54212$ git merge issue54
227    Updating fbff5bc..4af4298213Updating fbff5bc..4af4298
228    Fast forward214Fast forward
229     README           |    1 +215 README           |    1 +
230     lib/simplegit.rb |    6 +++++-216 lib/simplegit.rb |    6 +++++-
231     2 files changed, 6 insertions(+), 1 deletions(-)217 2 files changed, 6 insertions(+), 1 deletions(-)
 218-----
232 219 
.233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`):220No problems occur; as you can see it was a simple fast-forward. Now Jessica merges in John's work (`origin/master`):
234 221 
. 222[source,console]
 223-----
235    $ git merge origin/master224$ git merge origin/master
236    Auto-merging lib/simplegit.rb225Auto-merging lib/simplegit.rb
237    Merge made by recursive.226Merge made by recursive.
238     lib/simplegit.rb |    2 +-227 lib/simplegit.rb |    2 +-
239     1 files changed, 1 insertions(+), 1 deletions(-)228 1 files changed, 1 insertions(+), 1 deletions(-)
 229-----
240 230 
.241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 231Everything merges cleanly, and Jessica's history looks like this: 
242 232 
.243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
 233.Jessica's history after merging John's changes.
 234image::images/small-team-6.png[Jessica's history after merging John's changes.]
245 235 
.246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime):236Now `origin/master` is reachable from Jessica's `master` branch, so she should be able to successfully push (assuming John hasn't pushed again in the meantime):
247 237 
. 238[source,console]
 239-----
248    $ git push origin master240$ git push origin master
249    ...241...
250    To jessica@githost:simplegit.git242To jessica@githost:simplegit.git
251       72bbc59..8059c15  master -> master243   72bbc59..8059c15  master -> master
 244-----
252 245 
.253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10.246Each developer has committed a few times and merged each other's work successfully.
254 247 
.255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
 248.Jessica's history after pushing all changes back to the server.
 249image::images/small-team-7.png[Jessica's history after pushing all changes back to the server.]
257 250 
.258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 251That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it's ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like this: 
259 252 
.260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
 253.General sequence of events for a simple multiple-developer Git workflow.
 254image::images/small-team-flow.png[General sequence of events for a simple multiple-developer Git workflow.]
262 255 
.263### Private Managed Team ### 256==== Private Managed Team 
264 257 
. 258(((contributing, private managed team)))
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party.259In this next scenario, you'll look at contributor roles in a larger private group. You'll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party.
266 260 
.267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later.261Let's say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later.
268 262 
.269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there:263Let's follow Jessica's workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there:
270 264 
. 265[source,console]
 266-----
271    # Jessica's Machine267# Jessica's Machine
272    $ git checkout -b featureA268$ git checkout -b featureA
273    Switched to a new branch "featureA" 269Switched to a new branch 'featureA' 
274    $ vim lib/simplegit.rb270$ vim lib/simplegit.rb
275    $ git commit -am 'add limit to log function'271$ git commit -am 'add limit to log function'
276    [featureA 3300904] add limit to log function272[featureA 3300904] add limit to log function
277     1 files changed, 1 insertions(+), 1 deletions(-)273 1 files changed, 1 insertions(+), 1 deletions(-)
 274-----
278 275 
.279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch only the integrators do so she has to push to another branch in order to collaborate with John:276At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn't have push access to the `master` branch only the integrators do so she has to push to another branch in order to collaborate with John:
280 277 
. 278[source,console]
 279-----
281    $ git push origin featureA280$ git push -u origin featureA
282    ...281...
283    To jessica@githost:simplegit.git282To jessica@githost:simplegit.git
284     * [new branch]      featureA -> featureA283 * [new branch]      featureA -> featureA
 284-----
285 285 
.286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch:286Jessica e-mails John to tell him that she's pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server's `master` branch:
287 287 
. 288[source,console]
 289-----
288    # Jessica's Machine290# Jessica's Machine
289    $ git fetch origin291$ git fetch origin
290    $ git checkout -b featureB origin/master292$ git checkout -b featureB origin/master
291    Switched to a new branch "featureB" 293Switched to a new branch 'featureB' 
 294-----
292 295 
293Now, Jessica makes a couple of commits on the `featureB` branch:296Now, Jessica makes a couple of commits on the `featureB` branch:
294 297 
. 298[source,console]
 299-----
295    $ vim lib/simplegit.rb300$ vim lib/simplegit.rb
296    $ git commit -am 'made the ls-tree function recursive'301$ git commit -am 'made the ls-tree function recursive'
297    [featureB e5b0fdc] made the ls-tree function recursive302[featureB e5b0fdc] made the ls-tree function recursive
298     1 files changed, 1 insertions(+), 1 deletions(-)303 1 files changed, 1 insertions(+), 1 deletions(-)
299    $ vim lib/simplegit.rb304$ vim lib/simplegit.rb
300    $ git commit -am 'add ls-files'305$ git commit -am 'add ls-files'
301    [featureB 8512791] add ls-files306[featureB 8512791] add ls-files
302     1 files changed, 5 insertions(+), 0 deletions(-)307 1 files changed, 5 insertions(+), 0 deletions(-)
 308-----
303 309 
.304Jessica’s repository looks like Figure 5-12. 310Jessica's repository looks like this: 
305 311 
.306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
 312.Jessica's initial commit history.
 313image::images/managed-team-1.png[Jessica's initial commit history.]
308 314 
.309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`:315She's ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie's changes down with `git fetch`:
310 316 
. 317[source,console]
 318-----
311    $ git fetch origin319$ git fetch origin
312    ...320...
313    From jessica@githost:simplegit321From jessica@githost:simplegit
314     * [new branch]      featureBee -> origin/featureBee322 * [new branch]      featureBee -> origin/featureBee
 323-----
315 324 
316Jessica can now merge this into the work she did with `git merge`:325Jessica can now merge this into the work she did with `git merge`:
317 326 
. 327[source,console]
 328-----
318    $ git merge origin/featureBee329$ git merge origin/featureBee
319    Auto-merging lib/simplegit.rb330Auto-merging lib/simplegit.rb
320    Merge made by recursive.331Merge made by recursive.
321     lib/simplegit.rb |    4 ++++332 lib/simplegit.rb |    4 ++++
322     1 files changed, 4 insertions(+), 0 deletions(-)333 1 files changed, 4 insertions(+), 0 deletions(-)
 334-----
323 335 
.324There is a bit of a problem she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command:336There is a bit of a problem she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command:
325 337 
. 338[source,console]
 339-----
326    $ git push origin featureB:featureBee340$ git push -u origin featureB:featureBee
327    ...341...
328    To jessica@githost:simplegit.git342To jessica@githost:simplegit.git
329       fba9af8..cd685d1  featureB -> featureBee343   fba9af8..cd685d1  featureB -> featureBee
 344-----
330 345 
.331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 346This is called a _refspec_. See <<_refspec>> for a more detailed discussion of Git refspecs and different things you can do with them. Also notice the `-u` flag; this is short for `--set-upstream`, which configures the branches for easier pushing and pulling later. 
332 347 
.333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes:348Next, John e-mails Jessica to say he's pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes:
334 349 
. 350[source,console]
 351-----
335    $ git fetch origin352$ git fetch origin
336    ...353...
337    From jessica@githost:simplegit354From jessica@githost:simplegit
338       3300904..aad881d  featureA   -> origin/featureA355   3300904..aad881d  featureA   -> origin/featureA
 356-----
339 357 
340Then, she can see what has been changed with `git log`:358Then, she can see what has been changed with `git log`:
341 359 
. 360[source,console]
 361-----
342    $ git log origin/featureA ^featureA362$ git log featureA..origin/featureA
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6363commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6
344    Author: John Smith <jsmith@example.com>364Author: John Smith <jsmith@example.com>
345    Date:   Fri May 29 19:57:33 2009 -0700365Date:   Fri May 29 19:57:33 2009 -0700
346 366 
.347        changed log output to 30 from 25367    changed log output to 30 from 25
 368-----
348 369 
.349Finally, she merges John’s work into her own `featureA` branch:370Finally, she merges John's work into her own `featureA` branch:
350 371 
. 372[source,console]
 373-----
351    $ git checkout featureA374$ git checkout featureA
352    Switched to branch "featureA" 375Switched to branch 'featureA' 
353    $ git merge origin/featureA376$ git merge origin/featureA
354    Updating 3300904..aad881d377Updating 3300904..aad881d
355    Fast forward378Fast forward
356     lib/simplegit.rb |   10 +++++++++-379 lib/simplegit.rb |   10 +++++++++-
357    1 files changed, 9 insertions(+), 1 deletions(-)3801 files changed, 9 insertions(+), 1 deletions(-)
 381-----
358 382 
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server:383Jessica wants to tweak something, so she commits again and then pushes this back up to the server:
360 384 
. 385[source,console]
 386-----
361    $ git commit -am 'small tweak'387$ git commit -am 'small tweak'
362    [featureA 774b3ed] small tweak388[featureA 774b3ed] small tweak
363     1 files changed, 1 insertions(+), 1 deletions(-)389 1 files changed, 1 insertions(+), 1 deletions(-)
364    $ git push origin featureA 390$ git push 
365    ...391...
366    To jessica@githost:simplegit.git392To jessica@githost:simplegit.git
367       3300904..774b3ed  featureA -> featureA393   3300904..774b3ed  featureA -> featureA
 394-----
368 395 
.369Jessica’s commit history now looks something like Figure 5-13. 396Jessica's commit history now looks something like this: 
370 397 
.371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
 398.Jessica's history after committing on a feature branch.
 399image::images/managed-team-2.png[Jessica's history after committing on a feature branch.]
373 400 
.374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 401Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After the integrators merge these branches into the mainline, a fetch will bring down the new merge commit, making the history look like this: 
375 402 
.376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
 403.Jessica's history after merging both her topic branches.
 404image::images/managed-team-3.png[Jessica's history after merging both her topic branches.]
378 405 
.379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 406Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like this: 
380 407 
.381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
 408.Basic sequence of this managed-team workflow.
 409image::images/managed-team-flow.png[Basic sequence of this managed-team workflow.]
383 410 
. 411[[_public_project]]
384### Public Small Project ### 412==== Forked Public Project 
385 413 
. 414(((contributing, public small project)))
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail.415Contributing to public projects is a bit different. Because you don't have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking.Many hosting sites support this (including GitHub, BitBucket, Google Code, repo.or.cz, and others), and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail.
387 416 
.388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this:417First, you'll probably want to clone the main repository, create a topic branch for the patch or patch series you're planning to contribute, and do your work there. The sequence looks basically like this:
389 418 
. 419[source,console]
 420-----
390    $ git clone (url)421$ git clone (url)
391    $ cd project422$ cd project
392    $ git checkout -b featureA423$ git checkout -b featureA
393    $ (work)424# (work)
394    $ git commit425$ git commit
395    $ (work)426# (work)
396    $ git commit427$ git commit
 428-----
397 429 
. 430[NOTE]
 431====
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review see Chapter 6 for more information about interactive rebasing.432You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review see <<_rewriting_history>> for more information about interactive rebasing.
 433====
399 434 
.400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`:435When your branch work is finished and you're ready to contribute it back to the maintainers, go to the original project page and click the ``Fork'' button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`:
401 436 
. 437[source,console]
 438-----
402    $ git remote add myfork (url)439$ git remote add myfork (url)
 440-----
403 441 
.404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow:442Then you need to push your work up to it. It's easiest to push the topic branch you're working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn't accepted or is cherry picked, you don't have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you'll eventually get it back via pulling from their repository anyhow:
405 443 
. 444[source,console]
 445-----
406    $ git push myfork featureA446$ git push -u myfork featureA
 447-----
407 448 
. 449(((git commands, request-pull)))
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website GitHub has a "pull request" button that automatically messages the maintainer or run the `git request-pull` command and e-mail the output to the project maintainer manually.450When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website GitHub has it's own Pull Request mechanism that we'll go over in <<_github>> or you can run the `git request-pull` command and e-mail the output to the project maintainer manually.
409 451 
.410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this:452The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you're asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she's done two commits on the topic branch she just pushed up, she can run this:
411 453 
. 454[source,console]
 455-----
412    $ git request-pull origin/master myfork456$ git request-pull origin/master myfork
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:457The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:
414      John Smith (1):458  John Smith (1):
415            added a new function459        added a new function
416 460 
.417    are available in the git repository at:461are available in the git repository at:
418 462 
.419      git://githost/simplegit.git featureA463  git://githost/simplegit.git featureA
420 464 
.421    Jessica Smith (2):465Jessica Smith (2):
422          add limit to log function466      add limit to log function
423          change log output to 30 from 25467      change log output to 30 from 25
424 468 
.425     lib/simplegit.rb |   10 +++++++++-469 lib/simplegit.rb |   10 +++++++++-
426     1 files changed, 9 insertions(+), 1 deletions(-)470 1 files changed, 9 insertions(+), 1 deletions(-)
 471-----
427 472 
.428The output can be sent to the maintainerit tells them where the work was branched from, summarizes the commits, and tells where to pull this work from.473The output can be sent to the maintainerit tells them where the work was branched from, summarizes the commits, and tells where to pull this work from.
429 474 
.430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up start over from the main repository’s `master` branch:475On a project for which you're not the maintainer, it's generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they're rejected. Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don't continue working on the topic branch you just pushed up start over from the main repository's `master` branch:
431 476 
. 477[source,console]
 478-----
432    $ git checkout -b featureB origin/master479$ git checkout -b featureB origin/master
433    $ (work)480# (work)
434    $ git commit481$ git commit
435    $ git push myfork featureB482$ git push myfork featureB
436    $ (email maintainer)483# (email maintainer)
437    $ git fetch origin484$ git fetch origin
 485-----
438 486 
.439Now, each of your topics is contained within a silo similar to a patch queue that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 487Now, each of your topics is contained within a silo similar to a patch queue that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other, like so: 
440 488 
.441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
 489.Initial commit history with `featureB` work.
 490image::images/public-small-1.png[Initial commit history with `featureB` work.]
443 491 
.444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes:492Let's say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes:
445 493 
. 494[source,console]
 495-----
446    $ git checkout featureA496$ git checkout featureA
447    $ git rebase origin/master497$ git rebase origin/master
448    $ git push -f myfork featureA498$ git push -f myfork featureA
 499-----
449 500 
.450This rewrites your history to now look like Figure 5-17.501This rewrites your history to now look like <<psp_b>>.
451 502 
.452Insert 18333fig0517.png 503[[psp_b]] 
453Figure 5-17. Commit history after featureA work.504.Commit history after `featureA` work.
 505image::images/public-small-2.png[Commit history after `featureA` work.]
454 506 
.455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`).507Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn't a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`).
456 508 
.457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch:509Let's look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You'll also take this opportunity to move the work to be based off the project's current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch:
458 510 
. 511(((git commands, merge, squash)))
 512[source,console]
 513-----
459    $ git checkout -b featureBv2 origin/master514$ git checkout -b featureBv2 origin/master
460    $ git merge --no-commit --squash featureB515$ git merge --no-commit --squash featureB
461    $ (change implementation)516# (change implementation)
462    $ git commit517$ git commit
463    $ git push myfork featureBv2518$ git push myfork featureBv2
 519-----
464 520 
.465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit.521The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you're on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit.
466 522 
.467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18).523Now you can send the maintainer a message that you've made the requested changes and they can find those changes in your `featureBv2` branch.
468 524 
.469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
 525.Commit history after `featureBv2` work.
 526image::images/public-small-3.png[Commit history after `featureBv2` work.]
471 527 
. 528[[_project_over_email]]
472### Public Large Project ### 529==== Public Project over E-Mail 
473 530 
. 531(((contributing, public large project)))
474Many larger projects have established procedures for accepting patches you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now.532Many projects have established procedures for accepting patches you'll need to check the specific rules for each project, because they will differ. Since there are several older, larger projects which accept patches via a developer mailing list, we'll go over an example of that now.
475 533 
.476The workflow is similar to the previous use case you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list:534The workflow is similar to the previous use case you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list:
477 535 
. 536[source,console]
 537-----
478    $ git checkout -b topicA538$ git checkout -b topicA
479    $ (work)539# (work)
480    $ git commit540$ git commit
481    $ (work)541# (work)
482    $ git commit542$ git commit
 543-----
483 544 
. 545(((git commands, format-patch)))
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 546Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly. 
485 547 
. 548[source,console]
 549-----
486    $ git format-patch -M origin/master550$ git format-patch -M origin/master
487    0001-add-limit-to-log-function.patch5510001-add-limit-to-log-function.patch
488    0002-changed-log-output-to-30-from-25.patch5520002-changed-log-output-to-30-from-25.patch
 553-----
489 554 
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this:555The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this:
491 556 
. 557[source,console]
 558-----
492    $ cat 0001-add-limit-to-log-function.patch559$ cat 0001-add-limit-to-log-function.patch
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001560From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
494    From: Jessica Smith <jessica@example.com>561From: Jessica Smith <jessica@example.com>
495    Date: Sun, 6 Apr 2008 10:17:23 -0700562Date: Sun, 6 Apr 2008 10:17:23 -0700
496    Subject: [PATCH 1/2] add limit to log function563Subject: [PATCH 1/2] add limit to log function
497 564 
.498    Limit log functionality to the first 20565Limit log functionality to the first 20
499 566 
.500    ---567---
501     lib/simplegit.rb |    2 +-568 lib/simplegit.rb |    2 +-
502     1 files changed, 1 insertions(+), 1 deletions(-)569 1 files changed, 1 insertions(+), 1 deletions(-)
503 570 
.504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb571diff --git a/lib/simplegit.rb b/lib/simplegit.rb
505    index 76f47bc..f9815f1 100644572index 76f47bc..f9815f1 100644
506    --- a/lib/simplegit.rb573--- a/lib/simplegit.rb
507    +++ b/lib/simplegit.rb574+++ b/lib/simplegit.rb
508    @@ -14,7 +14,7 @@ class SimpleGit575@@ -14,7 +14,7 @@ class SimpleGit
509       end576   end
510 577 
.511       def log(treeish = 'master')578   def log(treeish = 'master')
512    -    command("git log #{treeish}")579-    command("git log #{treeish}")
513    +    command("git log -n 20 #{treeish}")580+    command("git log -n 20 #{treeish}")
514       end581   end
515 582 
.516       def ls_tree(treeish = 'master')583   def ls_tree(treeish = 'master')
517    --584--
518    1.6.2.rc1.20.g8c5b.dirty 5852.1.0 
 586-----
519 587 
.520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it.588You can also edit these patch files to add more information for the e-mail list that you don't want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `diff --git` line), then developers can read it; but applying the patch excludes it.
521 589 
.522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code.590To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with ``smarter'' clients that don't preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. We'll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent we know best; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code.
523 591 
. 592(((git commands, config)))(((email)))
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this:593First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually, but in the end your config file should look something like this:
525 594 
. 595[source,ini]
 596-----
526    [imap]597[imap]
527      folder = "[Gmail]/Drafts"598  folder = "[Gmail]/Drafts"
528      host = imaps://imap.gmail.com599  host = imaps://imap.gmail.com
529      user = user@gmail.com600  user = user@gmail.com
530      pass = p4ssw0rd601  pass = p4ssw0rd
531      port = 993602  port = 993
532      sslverify = false603  sslverify = false
 604-----
533 605 
.534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`.606If your IMAP server doesn't use SSL, the last two lines probably aren't necessary, and the host value will be `imap://` instead of `imaps://`.
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server:607When that is set up, you can use `git send-email` to place the patch series in the Drafts folder of the specified IMAP server:
536 608 
.537    $ cat *.patch |git imap-send 609[source,console] 
538    Resolving imap.gmail.com... ok 610----- 
539    Connecting to [74.125.142.109]:993... ok 611$ git send-email *.patch 
540    Logging in... 6120001-added-limit-to-log-function.patch 
541    sending 2 messages 6130002-changed-log-output-to-30-from-25.patch 
542    100% (2/2) done 614Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
 615Emails will be sent from: Jessica Smith <jessica@example.com>
 616Who should the emails be sent to? jessica@example.com
 617Message-ID to be used as In-Reply-To for the first email? y
 618-----
 619 
 620Then, Git spits out a bunch of log information looking something like this for each patch you're sending:
 621 
 622[source,text]
 623-----
 624(mbox) Adding cc: Jessica Smith <jessica@example.com> from
 625  \line 'From: Jessica Smith <jessica@example.com>'
 626OK. Log says:
 627Sendmail: /usr/sbin/sendmail -i jessica@example.com
 628From: Jessica Smith <jessica@example.com>
 629To: jessica@example.com
 630Subject: [PATCH 1/2] added limit to log function
 631Date: Sat, 30 May 2009 13:29:15 -0700
 632Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com>
 633X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty
 634In-Reply-To: <y>
 635References: <y>
 636 
 637Result: OK
 638-----
543 639 
.544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off.640At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you're sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off.
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580 641 
.581### Summary ### 642==== Summary 
582 643 
.583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager.644This section has covered a number of common workflows for dealing with several very different types of Git projects you're likely to encounter, and introduced a couple of new tools to help you manage this process. Next, you'll see how to work the other side of the coin: maintaining a Git project. You'll learn how to be a benevolent dictator or integration manager.
584  
585## Maintaining a Project ## 
586  
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. 
588  
589### Working in Topic Branches ### 
590  
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. 
592As you’ll remember, you can create the branch based off your master branch like this: 
593  
594    $ git branch sc/ruby_client master 
595  
596Or, if you want to also switch to it immediately, you can use the `checkout -b` command: 
597  
598    $ git checkout -b sc/ruby_client master 
599  
600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. 
601  
602### Applying Patches from E-mail ### 
603  
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. 
605  
606#### Applying a Patch with apply #### 
607  
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: 
609  
610    $ git apply /tmp/patch-ruby-client.patch 
611  
612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you — after running it, you must stage and commit the changes introduced manually. 
613  
614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: 
615  
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch 
617    error: patch failed: ticgit.gemspec:1 
618    error: ticgit.gemspec: patch does not apply 
619  
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. 
621  
622#### Applying a Patch with am #### 
623  
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. 
625  
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: 
627  
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
629    From: Jessica Smith <jessica@example.com> 
630    Date: Sun, 6 Apr 2008 10:17:23 -0700 
631    Subject: [PATCH 1/2] add limit to log function 
632  
633    Limit log functionality to the first 20 
634  
635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time. 
636  
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: 
638  
639    $ git am 0001-limit-log-function.patch 
640    Applying: add limit to log function 
641  
642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: 
643  
644    $ git log --pretty=fuller -1 
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
646    Author:     Jessica Smith <jessica@example.com> 
647    AuthorDate: Sun Apr 6 10:17:23 2008 -0700 
648    Commit:     Scott Chacon <schacon@gmail.com> 
649    CommitDate: Thu Apr 9 09:19:06 2009 -0700 
650  
651       add limit to log function 
652  
653       Limit log functionality to the first 20 
654  
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. 
656  
657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: 
658  
659    $ git am 0001-seeing-if-this-helps-the-gem.patch 
660    Applying: seeing if this helps the gem 
661    error: patch failed: ticgit.gemspec:1 
662    error: ticgit.gemspec: patch does not apply 
663    Patch failed at 0001. 
664    When you have resolved this problem run "git am --resolved". 
665    If you would prefer to skip this patch, instead run "git am --skip". 
666    To restore the original branch and stop patching run "git am --abort". 
667  
668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: 
669  
670    $ (fix the file) 
671    $ git add ticgit.gemspec 
672    $ git am --resolved 
673    Applying: seeing if this helps the gem 
674  
675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: 
676  
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch 
678    Applying: seeing if this helps the gem 
679    error: patch failed: ticgit.gemspec:1 
680    error: ticgit.gemspec: patch does not apply 
681    Using index info to reconstruct a base tree... 
682    Falling back to patching base and 3-way merge... 
683    No changes -- Patch already applied. 
684  
685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict. 
686  
687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: 
688  
689    $ git am -3 -i mbox 
690    Commit Body is: 
691    -------------------------- 
692    seeing if this helps the gem 
693    -------------------------- 
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all 
695  
696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. 
697  
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. 
699  
700### Checking Out Remote Branches ### 
701  
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. 
703  
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: 
705  
706    $ git remote add jessica git://github.com/jessica/myproject.git 
707    $ git fetch jessica 
708    $ git checkout -b rubyclient jessica/ruby-client 
709  
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. 
711  
712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier — it depends largely on how you develop and how your contributors develop. 
713  
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. 
715  
716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference: 
717  
718    $ git pull git://github.com/onetimeguy/project.git 
719    From git://github.com/onetimeguy/project 
720     * branch            HEAD       -> FETCH_HEAD 
721    Merge made by recursive. 
722  
723### Determining What Is Introduced ### 
724  
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch. 
726  
727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: 
728  
729    $ git log contrib --not master 
730    commit 5b6235bd297351589efc4d73316f0a68d484f118 
731    Author: Scott Chacon <schacon@gmail.com> 
732    Date:   Fri Oct 24 09:53:59 2008 -0700 
733  
734        seeing if this helps the gem 
735  
736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 
737    Author: Scott Chacon <schacon@gmail.com> 
738    Date:   Mon Oct 22 19:38:36 2008 -0700 
739  
740        updated the gemspec to hopefully work better 
741  
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. 
743  
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: 
745  
746    $ git diff master 
747  
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. 
749  
750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch. 
751  
752What you really want to see are the changes added to the topic branch — the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. 
753  
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: 
755  
756    $ git merge-base contrib master 
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 
758    $ git diff 36c7db 
759  
760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: 
761  
762    $ git diff master...contrib 
763  
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. 
765  
766### Integrating Contributed Work ### 
767  
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them. 
769  
770#### Merging Workflows #### 
771  
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. 
773  
774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
776  
777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
779  
780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. 
781  
782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). 
783  
784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
786  
787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
789  
790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
792  
793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. 
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. 
795  
796#### Large-Merging Workflows #### 
797  
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. 
799  
800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
802  
803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 
804  
805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
807  
808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 
809  
810#### Rebasing and Cherry Picking Workflows #### 
811  
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history. 
813  
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 
815  
816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
818  
819If you want to pull commit `e43a6` into your master branch, you can run 
820  
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf 
822    Finished one cherry-pick. 
823    [master]: created a0a41a9: "More friendly message when locking the index fails." 
824     3 files changed, 17 insertions(+), 3 deletions(-) 
825  
826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 
827  
828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
830  
831Now you can remove your topic branch and drop the commits you didn’t want to pull in. 
832  
833### Tagging Your Releases ### 
834  
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this: 
836  
837    $ git tag -s v1.5 -m 'my signed 1.5 tag' 
838    You need a passphrase to unlock the secret key for 
839    user: "Scott Chacon <schacon@gmail.com>" 
840    1024-bit DSA key, ID F721C45A, created 2009-02-09 
841  
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: 
843  
844    $ gpg --list-keys 
845    /Users/schacon/.gnupg/pubring.gpg 
846    --------------------------------- 
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09] 
848    uid                  Scott Chacon <schacon@gmail.com> 
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09] 
850  
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: 
852  
853    $ gpg -a --export F721C45A | git hash-object -w --stdin 
854    659ef797d181633c87ec71ac3f9ba29fe5775b92 
855  
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: 
857  
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 
859  
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: 
861  
862    $ git show maintainer-pgp-pub | gpg --import 
863  
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification. 
865  
866### Generating a Build Number ### 
867  
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing: 
869  
870    $ git describe master 
871    v1.6.2-rc1-20-g8c5b85c 
872  
873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name. 
874  
875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. 
876  
877### Preparing a Release ### 
878  
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`: 
880  
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz 
882    $ ls *.tar.gz 
883    v1.6.2-rc1-20-g8c5b85c.tar.gz 
884  
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: 
886  
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip 
888  
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. 
890  
891### The Shortlog ### 
892  
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: 
894  
895    $ git shortlog --no-merges master --not v1.0.1 
896    Chris Wanstrath (8): 
897          Add support for annotated tags to Grit::Tag 
898          Add packed-refs annotated tag support. 
899          Add Grit::Commit#to_patch 
900          Update version and History.txt 
901          Remove stray `puts` 
902          Make ls_tree ignore nils 
903  
904    Tom Preston-Werner (4): 
905          fix dates in history 
906          dynamic version method 
907          Version bump to 1.0.2 
908          Regenerated gemspec for version 1.0.2 
909  
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. 
911  
912## Summary ## 
913  
914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master. 
915 645 
+
+ diff --git a/book/05-distributed-git/sections/diff-distributed-workflows.htm b/book/05-distributed-git/sections/diff-distributed-workflows.htm new file mode 100644 index 00000000..79be3f05 --- /dev/null +++ b/book/05-distributed-git/sections/diff-distributed-workflows.htm @@ -0,0 +1,3843 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\sections\distributed-workflows.asc
.1# Distributed Git # 
2  
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you. 
4  
5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. 
6  
7## Distributed Workflows ## 1=== Distributed Workflows 
8 2 
. 3(((workflows)))
9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each.4Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so we'll cover a few common paradigms that take advantage of this flexibility. We'll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each.
10 5 
.11### Centralized Workflow ### 6==== Centralized Workflow 
12 7 
. 8(((workflows, centralized)))
13In centralized systems, there is generally a single collaboration modelthe centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes consumers of that hub and synchronize to that one place (see Figure 5-1).9In centralized systems, there is generally a single collaboration modelthe centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes consumers of that hub and synchronize to that one place.
14 10 
.15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
 11.Centralized workflow.
 12image::images/centralized.png[Centralized workflow.]
17 13 
.18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git.14This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one's work before pushing changes up, so as not to overwrite the first developer's changes. This concept is as true in Git as it is in Subversion(((Subversion))) (or any CVCS), and this model works perfectly well in Git.
19 15 
.20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 16If you are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won't let users overwrite each other. Say John and Jessica both start working at the same time. John finishes his change and pushes it to the server. Then Jessica tries to push her changes, but the server rejects them. She is told that she's trying to push non-fast-forward changes and that she won't be able to do so until she fetches and merges.  
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with.17This workflow is attractive to a lot of people because it's a paradigm that many are familiar and comfortable with.
22 18 
. 19This is also not limited to small teams. With Git's branching model, it's possible for hundreds of developers to successfully work on a single project through dozens of branches simultaneously.
 20 
 21[[_integration_manager]]
23### Integration-Manager Workflow ### 22==== Integration-Manager Workflow 
24 23 
. 24(((workflows, integration manager)))
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2):25Because Git allows you to have multiple remote repositories, it's possible to have a workflow where each developer has write access to their own public repository and read access to everyone else's. This scenario often includes a canonical repository that represents the ``official'' project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. The maintainer can then add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see <<wfdiag_b>>):
26 26 
.271. The project maintainer pushes to their public repository.271.  The project maintainer pushes to their public repository.
282. A contributor clones that repository and makes changes.282.  A contributor clones that repository and makes changes.
293. The contributor pushes to their own public copy.293.  The contributor pushes to their own public copy.
304. The contributor sends the maintainer an e-mail asking them to pull changes.304.  The contributor sends the maintainer an e-mail asking them to pull changes.
315. The maintainer adds the contributor’s repo as a remote and merges locally.315.  The maintainer adds the contributor's repo as a remote and merges locally.
326. The maintainer pushes merged changes to the main repository.326.  The maintainer pushes merged changes to the main repository.
33 33 
.34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
 34[[wfdiag_b]]
 35.Integration-manager workflow.
 36image::images/integration-manager.png[Integration-manager workflow.]
36 37 
. 38(((forking)))
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes each party can work at their own pace.39This is a very common workflow with hub-based tools like GitHub or GitLab, where it's easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don't have to wait for the project to incorporate their changes each party can work at their own pace.
38 40 
.39### Dictator and Lieutenants Workflow ### 41==== Dictator and Lieutenants Workflow 
40 42 
. 43(((workflows, dictator and lieutenants)))
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3):44This is a variant of a multiple-repository workflow. It's generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they're called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator's repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see <<wfdiag_c>>):
42 45 
.431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator.461.  Regular developers work on their topic branch and rebase their work on top of `master`.
 47    The `master` branch is that of the dictator.
442. Lieutenants merge the developers’ topic branches into their master branch.482.  Lieutenants merge the developers' topic branches into their `master` branch.
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch.493.  The dictator merges the lieutenants' `master` branches into the dictator's `master` branch.
464. The dictator pushes their master to the reference repository so the other developers can rebase on it.504.  The dictator pushes their `master` to the reference repository so the other developers can rebase on it.
47 51 
.48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
 52[[wfdiag_c]]
 53.Benevolent dictator workflow.
 54image::images/benevolent-dictator.png[Benevolent dictator workflow.]
50 55 
.51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them.56This kind of workflow isn't common, but can be useful in very big projects, or in highly hierarchical environments. It allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them.
 57 
 58==== Workflows Summary
52 59 
.53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 60These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (hopefully) determine which workflow combination may work for you, we'll cover some more specific examples of how to accomplish the main roles that make up the different flows. In the next section, you'll learn about a few common patterns for contributing to a project. 
54  
55## Contributing to a Project ## 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58  
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method. 
60  
61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid? 
62  
63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 
64  
65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? 
66  
67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. 
68  
69### Commit Guidelines ### 
70  
71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches — you can read it in the Git source code in the `Documentation/SubmittingPatches` file. 
72  
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this — before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 
74  
75    $ git diff --check 
76    lib/simplegit.rb:5: trailing whitespace. 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82  
83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers. 
84  
85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible — don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files — use these tools to help craft a clean and understandable history. 
86  
87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 
88Here is a template originally written by Tim Pope at tpope.net: 
89  
90    Short (50 chars or less) summary of changes 
91  
92    More detailed explanatory text, if necessary.  Wrap it to about 72 
93    characters or so.  In some contexts, the first line is treated as the 
94    subject of an email and the rest of the text as the body.  The blank 
95    line separating the summary from the body is critical (unless you omit 
96    the body entirely); tools like rebase can get confused if you run the 
97    two together. 
98  
99    Further paragraphs come after blank lines. 
100  
101     - Bullet points are okay, too 
102  
103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 
104       single space, with blank lines in between, but conventions vary here 
105  
106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages — I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like. 
107  
108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do. 
109  
110### Private Small Team ### 
111  
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source — not read-accessible to the outside world. You and the other developers all have push access to the repository. 
113  
114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.) 
116  
117    # John's Machine 
118    $ git clone john@githost:simplegit.git 
119    Initialized empty Git repository in /home/john/simplegit/.git/ 
120    ... 
121    $ cd simplegit/ 
122    $ vim lib/simplegit.rb 
123    $ git commit -am 'removed invalid default value' 
124    [master 738ee87] removed invalid default value 
125     1 files changed, 1 insertions(+), 1 deletions(-) 
126  
127The second developer, Jessica, does the same thing — clones the repository and commits a change: 
128  
129    # Jessica's Machine 
130    $ git clone jessica@githost:simplegit.git 
131    Initialized empty Git repository in /home/jessica/simplegit/.git/ 
132    ... 
133    $ cd simplegit/ 
134    $ vim TODO 
135    $ git commit -am 'add reset task' 
136    [master fbff5bc] add reset task 
137     1 files changed, 1 insertions(+), 0 deletions(-) 
138  
139Now, Jessica pushes her work up to the server: 
140  
141    # Jessica's Machine 
142    $ git push origin master 
143    ... 
144    To jessica@githost:simplegit.git 
145       1edee6b..fbff5bc  master -> master 
146  
147John tries to push his change up, too: 
148  
149    # John's Machine 
150    $ git push origin master 
151    To john@githost:simplegit.git 
152     ! [rejected]        master -> master (non-fast forward) 
153    error: failed to push some refs to 'john@githost:simplegit.git' 
154  
155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push: 
156  
157    $ git fetch origin 
158    ... 
159    From john@githost:simplegit 
160     + 049d078...fbff5bc master     -> origin/master 
161  
162At this point, John’s local repository looks something like Figure 5-4. 
163  
164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
166  
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: 
168  
169    $ git merge origin/master 
170    Merge made by recursive. 
171     TODO |    1 + 
172     1 files changed, 1 insertions(+), 0 deletions(-) 
173  
174The merge goes smoothly — John’s commit history now looks like Figure 5-5. 
175  
176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
178  
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: 
180  
181    $ git push origin master 
182    ... 
183    To john@githost:simplegit.git 
184       fbff5bc..72bbc59  master -> master 
185  
186Finally, John’s commit history looks like Figure 5-6. 
187  
188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
190  
191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 
192  
193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
195  
196Jessica wants to sync up with John, so she fetches: 
197  
198    # Jessica's Machine 
199    $ git fetch origin 
200    ... 
201    From jessica@githost:simplegit 
202       fbff5bc..72bbc59  master     -> origin/master 
203  
204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 
205  
206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
208  
209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: 
210  
211    $ git log --no-merges origin/master ^issue54 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016 
213    Author: John Smith <jsmith@example.com> 
214    Date:   Fri May 29 16:01:27 2009 -0700 
215  
216        removed invalid default value 
217  
218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work: 
219  
220    $ git checkout master 
221    Switched to branch "master" 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. 
223  
224She can merge either `origin/master` or `issue54` first — they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: 
225  
226    $ git merge issue54 
227    Updating fbff5bc..4af4298 
228    Fast forward 
229     README           |    1 + 
230     lib/simplegit.rb |    6 +++++- 
231     2 files changed, 6 insertions(+), 1 deletions(-) 
232  
233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`): 
234  
235    $ git merge origin/master 
236    Auto-merging lib/simplegit.rb 
237    Merge made by recursive. 
238     lib/simplegit.rb |    2 +- 
239     1 files changed, 1 insertions(+), 1 deletions(-) 
240  
241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 
242  
243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
245  
246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): 
247  
248    $ git push origin master 
249    ... 
250    To jessica@githost:simplegit.git 
251       72bbc59..8059c15  master -> master 
252  
253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. 
254  
255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
257  
258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 
259  
260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
262  
263### Private Managed Team ### 
264  
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. 
266  
267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. 
268  
269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: 
270  
271    # Jessica's Machine 
272    $ git checkout -b featureA 
273    Switched to a new branch "featureA" 
274    $ vim lib/simplegit.rb 
275    $ git commit -am 'add limit to log function' 
276    [featureA 3300904] add limit to log function 
277     1 files changed, 1 insertions(+), 1 deletions(-) 
278  
279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch — only the integrators do — so she has to push to another branch in order to collaborate with John: 
280  
281    $ git push origin featureA 
282    ... 
283    To jessica@githost:simplegit.git 
284     * [new branch]      featureA -> featureA 
285  
286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch: 
287  
288    # Jessica's Machine 
289    $ git fetch origin 
290    $ git checkout -b featureB origin/master 
291    Switched to a new branch "featureB" 
292  
293Now, Jessica makes a couple of commits on the `featureB` branch: 
294  
295    $ vim lib/simplegit.rb 
296    $ git commit -am 'made the ls-tree function recursive' 
297    [featureB e5b0fdc] made the ls-tree function recursive 
298     1 files changed, 1 insertions(+), 1 deletions(-) 
299    $ vim lib/simplegit.rb 
300    $ git commit -am 'add ls-files' 
301    [featureB 8512791] add ls-files 
302     1 files changed, 5 insertions(+), 0 deletions(-) 
303  
304Jessica’s repository looks like Figure 5-12. 
305  
306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
308  
309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: 
310  
311    $ git fetch origin 
312    ... 
313    From jessica@githost:simplegit 
314     * [new branch]      featureBee -> origin/featureBee 
315  
316Jessica can now merge this into the work she did with `git merge`: 
317  
318    $ git merge origin/featureBee 
319    Auto-merging lib/simplegit.rb 
320    Merge made by recursive. 
321     lib/simplegit.rb |    4 ++++ 
322     1 files changed, 4 insertions(+), 0 deletions(-) 
323  
324There is a bit of a problem — she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: 
325  
326    $ git push origin featureB:featureBee 
327    ... 
328    To jessica@githost:simplegit.git 
329       fba9af8..cd685d1  featureB -> featureBee 
330  
331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 
332  
333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: 
334  
335    $ git fetch origin 
336    ... 
337    From jessica@githost:simplegit 
338       3300904..aad881d  featureA   -> origin/featureA 
339  
340Then, she can see what has been changed with `git log`: 
341  
342    $ git log origin/featureA ^featureA 
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 
344    Author: John Smith <jsmith@example.com> 
345    Date:   Fri May 29 19:57:33 2009 -0700 
346  
347        changed log output to 30 from 25 
348  
349Finally, she merges John’s work into her own `featureA` branch: 
350  
351    $ git checkout featureA 
352    Switched to branch "featureA" 
353    $ git merge origin/featureA 
354    Updating 3300904..aad881d 
355    Fast forward 
356     lib/simplegit.rb |   10 +++++++++- 
357    1 files changed, 9 insertions(+), 1 deletions(-) 
358  
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server: 
360  
361    $ git commit -am 'small tweak' 
362    [featureA 774b3ed] small tweak 
363     1 files changed, 1 insertions(+), 1 deletions(-) 
364    $ git push origin featureA 
365    ... 
366    To jessica@githost:simplegit.git 
367       3300904..774b3ed  featureA -> featureA 
368  
369Jessica’s commit history now looks something like Figure 5-13. 
370  
371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
373  
374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 
375  
376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
378  
379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 
380  
381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
383  
384### Public Small Project ### 
385  
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. 
387  
388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this: 
389  
390    $ git clone (url) 
391    $ cd project 
392    $ git checkout -b featureA 
393    $ (work) 
394    $ git commit 
395    $ (work) 
396    $ git commit 
397  
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review — see Chapter 6 for more information about interactive rebasing. 
399  
400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: 
401  
402    $ git remote add myfork (url) 
403  
404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow: 
405  
406    $ git push myfork featureA 
407  
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website — GitHub has a "pull request" button that automatically messages the maintainer — or run the `git request-pull` command and e-mail the output to the project maintainer manually. 
409  
410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this: 
411  
412    $ git request-pull origin/master myfork 
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: 
414      John Smith (1): 
415            added a new function 
416  
417    are available in the git repository at: 
418  
419      git://githost/simplegit.git featureA 
420  
421    Jessica Smith (2): 
422          add limit to log function 
423          change log output to 30 from 25 
424  
425     lib/simplegit.rb |   10 +++++++++- 
426     1 files changed, 9 insertions(+), 1 deletions(-) 
427  
428The output can be sent to the maintainer—it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. 
429  
430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up — start over from the main repository’s `master` branch: 
431  
432    $ git checkout -b featureB origin/master 
433    $ (work) 
434    $ git commit 
435    $ git push myfork featureB 
436    $ (email maintainer) 
437    $ git fetch origin 
438  
439Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 
440  
441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
443  
444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: 
445  
446    $ git checkout featureA 
447    $ git rebase origin/master 
448    $ git push -f myfork featureA 
449  
450This rewrites your history to now look like Figure 5-17. 
451  
452Insert 18333fig0517.png 
453Figure 5-17. Commit history after featureA work. 
454  
455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). 
456  
457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: 
458  
459    $ git checkout -b featureBv2 origin/master 
460    $ git merge --no-commit --squash featureB 
461    $ (change implementation) 
462    $ git commit 
463    $ git push myfork featureBv2 
464  
465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. 
466  
467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). 
468  
469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
471  
472### Public Large Project ### 
473  
474Many larger projects have established procedures for accepting patches — you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now. 
475  
476The workflow is similar to the previous use case — you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: 
477  
478    $ git checkout -b topicA 
479    $ (work) 
480    $ git commit 
481    $ (work) 
482    $ git commit 
483  
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list — it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 
485  
486    $ git format-patch -M origin/master 
487    0001-add-limit-to-log-function.patch 
488    0002-changed-log-output-to-30-from-25.patch 
489  
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: 
491  
492    $ cat 0001-add-limit-to-log-function.patch 
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
494    From: Jessica Smith <jessica@example.com> 
495    Date: Sun, 6 Apr 2008 10:17:23 -0700 
496    Subject: [PATCH 1/2] add limit to log function 
497  
498    Limit log functionality to the first 20 
499  
500    --- 
501     lib/simplegit.rb |    2 +- 
502     1 files changed, 1 insertions(+), 1 deletions(-) 
503  
504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
505    index 76f47bc..f9815f1 100644 
506    --- a/lib/simplegit.rb 
507    +++ b/lib/simplegit.rb 
508    @@ -14,7 +14,7 @@ class SimpleGit 
509       end 
510  
511       def log(treeish = 'master') 
512    -    command("git log #{treeish}") 
513    +    command("git log -n 20 #{treeish}") 
514       end 
515  
516       def ls_tree(treeish = 'master') 
517    -- 
518    1.6.2.rc1.20.g8c5b.dirty 
519  
520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. 
521  
522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. 
523  
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this: 
525  
526    [imap] 
527      folder = "[Gmail]/Drafts" 
528      host = imaps://imap.gmail.com 
529      user = user@gmail.com 
530      pass = p4ssw0rd 
531      port = 993 
532      sslverify = false 
533  
534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`. 
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: 
536  
537    $ cat *.patch |git imap-send 
538    Resolving imap.gmail.com... ok 
539    Connecting to [74.125.142.109]:993... ok 
540    Logging in... 
541    sending 2 messages 
542    100% (2/2) done 
543  
544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. 
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580  
581### Summary ### 
582  
583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager. 
584  
585## Maintaining a Project ## 
586  
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. 
588  
589### Working in Topic Branches ### 
590  
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. 
592As you’ll remember, you can create the branch based off your master branch like this: 
593  
594    $ git branch sc/ruby_client master 
595  
596Or, if you want to also switch to it immediately, you can use the `checkout -b` command: 
597  
598    $ git checkout -b sc/ruby_client master 
599  
600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. 
601  
602### Applying Patches from E-mail ### 
603  
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. 
605  
606#### Applying a Patch with apply #### 
607  
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: 
609  
610    $ git apply /tmp/patch-ruby-client.patch 
611  
612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you — after running it, you must stage and commit the changes introduced manually. 
613  
614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: 
615  
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch 
617    error: patch failed: ticgit.gemspec:1 
618    error: ticgit.gemspec: patch does not apply 
619  
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. 
621  
622#### Applying a Patch with am #### 
623  
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. 
625  
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: 
627  
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
629    From: Jessica Smith <jessica@example.com> 
630    Date: Sun, 6 Apr 2008 10:17:23 -0700 
631    Subject: [PATCH 1/2] add limit to log function 
632  
633    Limit log functionality to the first 20 
634  
635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time. 
636  
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: 
638  
639    $ git am 0001-limit-log-function.patch 
640    Applying: add limit to log function 
641  
642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: 
643  
644    $ git log --pretty=fuller -1 
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
646    Author:     Jessica Smith <jessica@example.com> 
647    AuthorDate: Sun Apr 6 10:17:23 2008 -0700 
648    Commit:     Scott Chacon <schacon@gmail.com> 
649    CommitDate: Thu Apr 9 09:19:06 2009 -0700 
650  
651       add limit to log function 
652  
653       Limit log functionality to the first 20 
654  
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. 
656  
657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: 
658  
659    $ git am 0001-seeing-if-this-helps-the-gem.patch 
660    Applying: seeing if this helps the gem 
661    error: patch failed: ticgit.gemspec:1 
662    error: ticgit.gemspec: patch does not apply 
663    Patch failed at 0001. 
664    When you have resolved this problem run "git am --resolved". 
665    If you would prefer to skip this patch, instead run "git am --skip". 
666    To restore the original branch and stop patching run "git am --abort". 
667  
668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: 
669  
670    $ (fix the file) 
671    $ git add ticgit.gemspec 
672    $ git am --resolved 
673    Applying: seeing if this helps the gem 
674  
675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: 
676  
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch 
678    Applying: seeing if this helps the gem 
679    error: patch failed: ticgit.gemspec:1 
680    error: ticgit.gemspec: patch does not apply 
681    Using index info to reconstruct a base tree... 
682    Falling back to patching base and 3-way merge... 
683    No changes -- Patch already applied. 
684  
685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict. 
686  
687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: 
688  
689    $ git am -3 -i mbox 
690    Commit Body is: 
691    -------------------------- 
692    seeing if this helps the gem 
693    -------------------------- 
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all 
695  
696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. 
697  
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. 
699  
700### Checking Out Remote Branches ### 
701  
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. 
703  
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: 
705  
706    $ git remote add jessica git://github.com/jessica/myproject.git 
707    $ git fetch jessica 
708    $ git checkout -b rubyclient jessica/ruby-client 
709  
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. 
711  
712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier — it depends largely on how you develop and how your contributors develop. 
713  
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. 
715  
716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference: 
717  
718    $ git pull git://github.com/onetimeguy/project.git 
719    From git://github.com/onetimeguy/project 
720     * branch            HEAD       -> FETCH_HEAD 
721    Merge made by recursive. 
722  
723### Determining What Is Introduced ### 
724  
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch. 
726  
727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: 
728  
729    $ git log contrib --not master 
730    commit 5b6235bd297351589efc4d73316f0a68d484f118 
731    Author: Scott Chacon <schacon@gmail.com> 
732    Date:   Fri Oct 24 09:53:59 2008 -0700 
733  
734        seeing if this helps the gem 
735  
736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 
737    Author: Scott Chacon <schacon@gmail.com> 
738    Date:   Mon Oct 22 19:38:36 2008 -0700 
739  
740        updated the gemspec to hopefully work better 
741  
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. 
743  
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: 
745  
746    $ git diff master 
747  
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. 
749  
750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch. 
751  
752What you really want to see are the changes added to the topic branch — the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. 
753  
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: 
755  
756    $ git merge-base contrib master 
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 
758    $ git diff 36c7db 
759  
760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: 
761  
762    $ git diff master...contrib 
763  
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. 
765  
766### Integrating Contributed Work ### 
767  
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them. 
769  
770#### Merging Workflows #### 
771  
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. 
773  
774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
776  
777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
779  
780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. 
781  
782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). 
783  
784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
786  
787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
789  
790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
792  
793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. 
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. 
795  
796#### Large-Merging Workflows #### 
797  
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. 
799  
800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
802  
803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 
804  
805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
807  
808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 
809  
810#### Rebasing and Cherry Picking Workflows #### 
811  
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history. 
813  
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 
815  
816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
818  
819If you want to pull commit `e43a6` into your master branch, you can run 
820  
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf 
822    Finished one cherry-pick. 
823    [master]: created a0a41a9: "More friendly message when locking the index fails." 
824     3 files changed, 17 insertions(+), 3 deletions(-) 
825  
826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 
827  
828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
830  
831Now you can remove your topic branch and drop the commits you didn’t want to pull in. 
832  
833### Tagging Your Releases ### 
834  
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this: 
836  
837    $ git tag -s v1.5 -m 'my signed 1.5 tag' 
838    You need a passphrase to unlock the secret key for 
839    user: "Scott Chacon <schacon@gmail.com>" 
840    1024-bit DSA key, ID F721C45A, created 2009-02-09 
841  
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: 
843  
844    $ gpg --list-keys 
845    /Users/schacon/.gnupg/pubring.gpg 
846    --------------------------------- 
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09] 
848    uid                  Scott Chacon <schacon@gmail.com> 
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09] 
850  
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: 
852  
853    $ gpg -a --export F721C45A | git hash-object -w --stdin 
854    659ef797d181633c87ec71ac3f9ba29fe5775b92 
855  
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: 
857  
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 
859  
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: 
861  
862    $ git show maintainer-pgp-pub | gpg --import 
863  
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification. 
865  
866### Generating a Build Number ### 
867  
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing: 
869  
870    $ git describe master 
871    v1.6.2-rc1-20-g8c5b85c 
872  
873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name. 
874  
875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. 
876  
877### Preparing a Release ### 
878  
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`: 
880  
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz 
882    $ ls *.tar.gz 
883    v1.6.2-rc1-20-g8c5b85c.tar.gz 
884  
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: 
886  
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip 
888  
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. 
890  
891### The Shortlog ### 
892  
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: 
894  
895    $ git shortlog --no-merges master --not v1.0.1 
896    Chris Wanstrath (8): 
897          Add support for annotated tags to Grit::Tag 
898          Add packed-refs annotated tag support. 
899          Add Grit::Commit#to_patch 
900          Update version and History.txt 
901          Remove stray `puts` 
902          Make ls_tree ignore nils 
903  
904    Tom Preston-Werner (4): 
905          fix dates in history 
906          dynamic version method 
907          Version bump to 1.0.2 
908          Regenerated gemspec for version 1.0.2 
909  
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. 
911  
912## Summary ## 
913  
914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master. 
915 61 
+
+ diff --git a/book/05-distributed-git/sections/diff-maintaining.htm b/book/05-distributed-git/sections/diff-maintaining.htm new file mode 100644 index 00000000..a25a869b --- /dev/null +++ b/book/05-distributed-git/sections/diff-maintaining.htm @@ -0,0 +1,4375 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\sections\maintaining.asc
.1# Distributed Git # 
2  
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you. 
4  
5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. 
6  
7## Distributed Workflows ## 
8  
9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub — that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. 
10  
11### Centralized Workflow ### 
12  
13In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). 
14  
15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
17  
18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. 
19  
20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with. 
22  
23### Integration-Manager Workflow ### 
24  
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2): 
26  
271. The project maintainer pushes to their public repository. 
282. A contributor clones that repository and makes changes. 
293. The contributor pushes to their own public copy. 
304. The contributor sends the maintainer an e-mail asking them to pull changes. 
315. The maintainer adds the contributor’s repo as a remote and merges locally. 
326. The maintainer pushes merged changes to the main repository. 
33  
34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
36  
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. 
38  
39### Dictator and Lieutenants Workflow ### 
40  
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3): 
42  
431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator. 
442. Lieutenants merge the developers’ topic branches into their master branch. 
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 
464. The dictator pushes their master to the reference repository so the other developers can rebase on it. 
47  
48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
50  
51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. 
52  
53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 
54  
55## Contributing to a Project ## 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58  
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method. 
60  
61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid? 
62  
63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 
64  
65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? 
66  
67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. 
68  
69### Commit Guidelines ### 
70  
71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches — you can read it in the Git source code in the `Documentation/SubmittingPatches` file. 
72  
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this — before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 
74  
75    $ git diff --check 
76    lib/simplegit.rb:5: trailing whitespace. 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82  
83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers. 
84  
85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible — don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files — use these tools to help craft a clean and understandable history. 
86  
87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 
88Here is a template originally written by Tim Pope at tpope.net: 
89  
90    Short (50 chars or less) summary of changes 
91  
92    More detailed explanatory text, if necessary.  Wrap it to about 72 
93    characters or so.  In some contexts, the first line is treated as the 
94    subject of an email and the rest of the text as the body.  The blank 
95    line separating the summary from the body is critical (unless you omit 
96    the body entirely); tools like rebase can get confused if you run the 
97    two together. 
98  
99    Further paragraphs come after blank lines. 
100  
101     - Bullet points are okay, too 
102  
103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 
104       single space, with blank lines in between, but conventions vary here 
105  
106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages — I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like. 
107  
108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do. 
109  
110### Private Small Team ### 
111  
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source — not read-accessible to the outside world. You and the other developers all have push access to the repository. 
113  
114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.) 
116  
117    # John's Machine 
118    $ git clone john@githost:simplegit.git 
119    Initialized empty Git repository in /home/john/simplegit/.git/ 
120    ... 
121    $ cd simplegit/ 
122    $ vim lib/simplegit.rb 
123    $ git commit -am 'removed invalid default value' 
124    [master 738ee87] removed invalid default value 
125     1 files changed, 1 insertions(+), 1 deletions(-) 
126  
127The second developer, Jessica, does the same thing — clones the repository and commits a change: 
128  
129    # Jessica's Machine 
130    $ git clone jessica@githost:simplegit.git 
131    Initialized empty Git repository in /home/jessica/simplegit/.git/ 
132    ... 
133    $ cd simplegit/ 
134    $ vim TODO 
135    $ git commit -am 'add reset task' 
136    [master fbff5bc] add reset task 
137     1 files changed, 1 insertions(+), 0 deletions(-) 
138  
139Now, Jessica pushes her work up to the server: 
140  
141    # Jessica's Machine 
142    $ git push origin master 
143    ... 
144    To jessica@githost:simplegit.git 
145       1edee6b..fbff5bc  master -> master 
146  
147John tries to push his change up, too: 
148  
149    # John's Machine 
150    $ git push origin master 
151    To john@githost:simplegit.git 
152     ! [rejected]        master -> master (non-fast forward) 
153    error: failed to push some refs to 'john@githost:simplegit.git' 
154  
155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push: 
156  
157    $ git fetch origin 
158    ... 
159    From john@githost:simplegit 
160     + 049d078...fbff5bc master     -> origin/master 
161  
162At this point, John’s local repository looks something like Figure 5-4. 
163  
164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
166  
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: 
168  
169    $ git merge origin/master 
170    Merge made by recursive. 
171     TODO |    1 + 
172     1 files changed, 1 insertions(+), 0 deletions(-) 
173  
174The merge goes smoothly — John’s commit history now looks like Figure 5-5. 
175  
176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
178  
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: 
180  
181    $ git push origin master 
182    ... 
183    To john@githost:simplegit.git 
184       fbff5bc..72bbc59  master -> master 
185  
186Finally, John’s commit history looks like Figure 5-6. 
187  
188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
190  
191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 
192  
193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
195  
196Jessica wants to sync up with John, so she fetches: 
197  
198    # Jessica's Machine 
199    $ git fetch origin 
200    ... 
201    From jessica@githost:simplegit 
202       fbff5bc..72bbc59  master     -> origin/master 
203  
204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 
205  
206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
208  
209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: 
210  
211    $ git log --no-merges origin/master ^issue54 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016 
213    Author: John Smith <jsmith@example.com> 
214    Date:   Fri May 29 16:01:27 2009 -0700 
215  
216        removed invalid default value 
217  
218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work: 
219  
220    $ git checkout master 
221    Switched to branch "master" 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. 
223  
224She can merge either `origin/master` or `issue54` first — they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: 
225  
226    $ git merge issue54 
227    Updating fbff5bc..4af4298 
228    Fast forward 
229     README           |    1 + 
230     lib/simplegit.rb |    6 +++++- 
231     2 files changed, 6 insertions(+), 1 deletions(-) 
232  
233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`): 
234  
235    $ git merge origin/master 
236    Auto-merging lib/simplegit.rb 
237    Merge made by recursive. 
238     lib/simplegit.rb |    2 +- 
239     1 files changed, 1 insertions(+), 1 deletions(-) 
240  
241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 
242  
243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
245  
246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): 
247  
248    $ git push origin master 
249    ... 
250    To jessica@githost:simplegit.git 
251       72bbc59..8059c15  master -> master 
252  
253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. 
254  
255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
257  
258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 
259  
260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
262  
263### Private Managed Team ### 
264  
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. 
266  
267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. 
268  
269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: 
270  
271    # Jessica's Machine 
272    $ git checkout -b featureA 
273    Switched to a new branch "featureA" 
274    $ vim lib/simplegit.rb 
275    $ git commit -am 'add limit to log function' 
276    [featureA 3300904] add limit to log function 
277     1 files changed, 1 insertions(+), 1 deletions(-) 
278  
279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch — only the integrators do — so she has to push to another branch in order to collaborate with John: 
280  
281    $ git push origin featureA 
282    ... 
283    To jessica@githost:simplegit.git 
284     * [new branch]      featureA -> featureA 
285  
286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch: 
287  
288    # Jessica's Machine 
289    $ git fetch origin 
290    $ git checkout -b featureB origin/master 
291    Switched to a new branch "featureB" 
292  
293Now, Jessica makes a couple of commits on the `featureB` branch: 
294  
295    $ vim lib/simplegit.rb 
296    $ git commit -am 'made the ls-tree function recursive' 
297    [featureB e5b0fdc] made the ls-tree function recursive 
298     1 files changed, 1 insertions(+), 1 deletions(-) 
299    $ vim lib/simplegit.rb 
300    $ git commit -am 'add ls-files' 
301    [featureB 8512791] add ls-files 
302     1 files changed, 5 insertions(+), 0 deletions(-) 
303  
304Jessica’s repository looks like Figure 5-12. 
305  
306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
308  
309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: 
310  
311    $ git fetch origin 
312    ... 
313    From jessica@githost:simplegit 
314     * [new branch]      featureBee -> origin/featureBee 
315  
316Jessica can now merge this into the work she did with `git merge`: 
317  
318    $ git merge origin/featureBee 
319    Auto-merging lib/simplegit.rb 
320    Merge made by recursive. 
321     lib/simplegit.rb |    4 ++++ 
322     1 files changed, 4 insertions(+), 0 deletions(-) 
323  
324There is a bit of a problem — she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: 
325  
326    $ git push origin featureB:featureBee 
327    ... 
328    To jessica@githost:simplegit.git 
329       fba9af8..cd685d1  featureB -> featureBee 
330  
331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 
332  
333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: 
334  
335    $ git fetch origin 
336    ... 
337    From jessica@githost:simplegit 
338       3300904..aad881d  featureA   -> origin/featureA 
339  
340Then, she can see what has been changed with `git log`: 
341  
342    $ git log origin/featureA ^featureA 
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 
344    Author: John Smith <jsmith@example.com> 
345    Date:   Fri May 29 19:57:33 2009 -0700 
346  
347        changed log output to 30 from 25 
348  
349Finally, she merges John’s work into her own `featureA` branch: 
350  
351    $ git checkout featureA 
352    Switched to branch "featureA" 
353    $ git merge origin/featureA 
354    Updating 3300904..aad881d 
355    Fast forward 
356     lib/simplegit.rb |   10 +++++++++- 
357    1 files changed, 9 insertions(+), 1 deletions(-) 
358  
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server: 
360  
361    $ git commit -am 'small tweak' 
362    [featureA 774b3ed] small tweak 
363     1 files changed, 1 insertions(+), 1 deletions(-) 
364    $ git push origin featureA 
365    ... 
366    To jessica@githost:simplegit.git 
367       3300904..774b3ed  featureA -> featureA 
368  
369Jessica’s commit history now looks something like Figure 5-13. 
370  
371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
373  
374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 
375  
376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
378  
379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 
380  
381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
383  
384### Public Small Project ### 
385  
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. 
387  
388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this: 
389  
390    $ git clone (url) 
391    $ cd project 
392    $ git checkout -b featureA 
393    $ (work) 
394    $ git commit 
395    $ (work) 
396    $ git commit 
397  
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review — see Chapter 6 for more information about interactive rebasing. 
399  
400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: 
401  
402    $ git remote add myfork (url) 
403  
404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow: 
405  
406    $ git push myfork featureA 
407  
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website — GitHub has a "pull request" button that automatically messages the maintainer — or run the `git request-pull` command and e-mail the output to the project maintainer manually. 
409  
410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this: 
411  
412    $ git request-pull origin/master myfork 
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: 
414      John Smith (1): 
415            added a new function 
416  
417    are available in the git repository at: 
418  
419      git://githost/simplegit.git featureA 
420  
421    Jessica Smith (2): 
422          add limit to log function 
423          change log output to 30 from 25 
424  
425     lib/simplegit.rb |   10 +++++++++- 
426     1 files changed, 9 insertions(+), 1 deletions(-) 
427  
428The output can be sent to the maintainer—it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. 
429  
430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up — start over from the main repository’s `master` branch: 
431  
432    $ git checkout -b featureB origin/master 
433    $ (work) 
434    $ git commit 
435    $ git push myfork featureB 
436    $ (email maintainer) 
437    $ git fetch origin 
438  
439Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 
440  
441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
443  
444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: 
445  
446    $ git checkout featureA 
447    $ git rebase origin/master 
448    $ git push -f myfork featureA 
449  
450This rewrites your history to now look like Figure 5-17. 
451  
452Insert 18333fig0517.png 
453Figure 5-17. Commit history after featureA work. 
454  
455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). 
456  
457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: 
458  
459    $ git checkout -b featureBv2 origin/master 
460    $ git merge --no-commit --squash featureB 
461    $ (change implementation) 
462    $ git commit 
463    $ git push myfork featureBv2 
464  
465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. 
466  
467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). 
468  
469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
471  
472### Public Large Project ### 
473  
474Many larger projects have established procedures for accepting patches — you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now. 
475  
476The workflow is similar to the previous use case — you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: 
477  
478    $ git checkout -b topicA 
479    $ (work) 
480    $ git commit 
481    $ (work) 
482    $ git commit 
483  
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list — it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 
485  
486    $ git format-patch -M origin/master 
487    0001-add-limit-to-log-function.patch 
488    0002-changed-log-output-to-30-from-25.patch 
489  
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: 
491  
492    $ cat 0001-add-limit-to-log-function.patch 
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
494    From: Jessica Smith <jessica@example.com> 
495    Date: Sun, 6 Apr 2008 10:17:23 -0700 
496    Subject: [PATCH 1/2] add limit to log function 
497  
498    Limit log functionality to the first 20 
499  
500    --- 
501     lib/simplegit.rb |    2 +- 
502     1 files changed, 1 insertions(+), 1 deletions(-) 
503  
504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
505    index 76f47bc..f9815f1 100644 
506    --- a/lib/simplegit.rb 
507    +++ b/lib/simplegit.rb 
508    @@ -14,7 +14,7 @@ class SimpleGit 
509       end 
510  
511       def log(treeish = 'master') 
512    -    command("git log #{treeish}") 
513    +    command("git log -n 20 #{treeish}") 
514       end 
515  
516       def ls_tree(treeish = 'master') 
517    -- 
518    1.6.2.rc1.20.g8c5b.dirty 
519  
520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. 
521  
522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. 
523  
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this: 
525  
526    [imap] 
527      folder = "[Gmail]/Drafts" 
528      host = imaps://imap.gmail.com 
529      user = user@gmail.com 
530      pass = p4ssw0rd 
531      port = 993 
532      sslverify = false 
533  
534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`. 
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: 
536  
537    $ cat *.patch |git imap-send 
538    Resolving imap.gmail.com... ok 
539    Connecting to [74.125.142.109]:993... ok 
540    Logging in... 
541    sending 2 messages 
542    100% (2/2) done 
543  
544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. 
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580  
581### Summary ### 
582  
583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager. 
584  
585## Maintaining a Project ## 1=== Maintaining a Project 
586 2 
. 3(((maintaining a project)))
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run.4In addition to knowing how to effectively contribute to a project, you'll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you've added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run.
588 5 
.589### Working in Topic Branches ### 6==== Working in Topic Branches 
590 7 
. 8(((branches, topic)))
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well such as `sc/ruby_client`, where `sc` is short for the person who contributed the work.9When you're thinking of integrating new work, it's generally a good idea to try it out in a topic branch a temporary branch specifically made to try out that new work. This way, it's easy to tweak a patch individually and leave it if it's not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you're going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well such as `sc/ruby_client`, where `sc` is short for the person who contributed the work.
592As you’ll remember, you can create the branch based off your master branch like this:10As you'll remember, you can create the branch based off your master branch like this:
593 11 
. 12[source,console]
 13-----
594    $ git branch sc/ruby_client master14$ git branch sc/ruby_client master
 15-----
595 16 
.596Or, if you want to also switch to it immediately, you can use the `checkout -b` command:17Or, if you want to also switch to it immediately, you can use the `checkout -b` option:
597 18 
. 19[source,console]
 20-----
598    $ git checkout -b sc/ruby_client master21$ git checkout -b sc/ruby_client master
 22-----
599 23 
.600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches.24Now you're ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches.
601 25 
. 26[[_patches_from_email]]
602### Applying Patches from E-mail ### 27==== Applying Patches from E-mail 
603 28 
. 29(((email, applying patches from)))
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`.30If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`.
605 31 
.606#### Applying a Patch with apply #### 32===== Applying a Patch with apply 
607 33 
. 34(((git commands, apply)))
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this:35If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command (which is not recommended; see the next section), you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this:
609 36 
. 37[source,console]
 38-----
610    $ git apply /tmp/patch-ruby-client.patch39$ git apply /tmp/patch-ruby-client.patch
 40-----
611 41 
.612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you after running it, you must stage and commit the changes introduced manually.42This modifies the files in your working directory. It's almost identical to running a `patch -p1` command to apply the patch, although it's more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they're described in the `git diff` format, which `patch` won't do. Finally, `git apply` is an ``apply all or abort all'' model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more conservative than `patch`. It won't create a commit for you after running it, you must stage and commit the changes introduced manually.
613 43 
.614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it you can run `git apply --check` with the patch:44You can also use git apply to see if a patch applies cleanly before you try actually applying it you can run `git apply --check` with the patch:
615 45 
. 46[source,console]
 47-----
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch48$ git apply --check 0001-seeing-if-this-helps-the-gem.patch
617    error: patch failed: ticgit.gemspec:149error: patch failed: ticgit.gemspec:1
618    error: ticgit.gemspec: patch does not apply50error: ticgit.gemspec: patch does not apply
 51-----
619 52 
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want.53If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want.
621 54 
. 55[[_git_am]]
622#### Applying a Patch with am #### 56===== Applying a Patch with `am` 
623 57 
. 58(((git commands, am)))
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that.59If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that.
625 60 
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this:61To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this:
627 62 
. 63[source,console]
 64-----
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 200165From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
629    From: Jessica Smith <jessica@example.com>66From: Jessica Smith <jessica@example.com>
630    Date: Sun, 6 Apr 2008 10:17:23 -070067Date: Sun, 6 Apr 2008 10:17:23 -0700
631    Subject: [PATCH 1/2] add limit to log function68Subject: [PATCH 1/2] add limit to log function
632 69 
.633    Limit log functionality to the first 2070Limit log functionality to the first 20
 71-----
634 72 
.635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time.73This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time.
636 74 
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it:75However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it:
638 76 
. 77[source,console]
 78-----
639    $ git am 0001-limit-log-function.patch79$ git am 0001-limit-log-function.patch
640    Applying: add limit to log function80Applying: add limit to log function
 81-----
641 82 
.642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this:83You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail's `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example above, the commit generated would look something like this:
643 84 
. 85-----
644    $ git log --pretty=fuller -186$ git log --pretty=fuller -1
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e087commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
646    Author:     Jessica Smith <jessica@example.com>88Author:     Jessica Smith <jessica@example.com>
647    AuthorDate: Sun Apr 6 10:17:23 2008 -070089AuthorDate: Sun Apr 6 10:17:23 2008 -0700
648    Commit:     Scott Chacon <schacon@gmail.com>90Commit:     Scott Chacon <schacon@gmail.com>
649    CommitDate: Thu Apr 9 09:19:06 2009 -070091CommitDate: Thu Apr 9 09:19:06 2009 -0700
650 92 
.651       add limit to log function93   add limit to log function
652 94 
.653       Limit log functionality to the first 2095   Limit log functionality to the first 20
 96-----
654 97 
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created.98The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created.
656 99 
.657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do:100But it's possible that the patch won't apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven't applied yet. In that case, the `git am` process will fail and ask you what you want to do:
658 101 
. 102[source,console]
 103-----
659    $ git am 0001-seeing-if-this-helps-the-gem.patch104$ git am 0001-seeing-if-this-helps-the-gem.patch
660    Applying: seeing if this helps the gem105Applying: seeing if this helps the gem
661    error: patch failed: ticgit.gemspec:1106error: patch failed: ticgit.gemspec:1
662    error: ticgit.gemspec: patch does not apply107error: ticgit.gemspec: patch does not apply
663    Patch failed at 0001.108Patch failed at 0001.
664    When you have resolved this problem run "git am --resolved".109When you have resolved this problem run "git am --resolved".
665    If you would prefer to skip this patch, instead run "git am --skip".110If you would prefer to skip this patch, instead run "git am --skip".
666    To restore the original branch and stop patching run "git am --abort".111To restore the original branch and stop patching run "git am --abort".
 112-----
667 113 
.668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch:114This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch:
669 115 
. 116[source,console]
 117-----
670    $ (fix the file)118$ (fix the file)
671    $ git add ticgit.gemspec119$ git add ticgit.gemspec
672    $ git am --resolved120$ git am --resolved
673    Applying: seeing if this helps the gem121Applying: seeing if this helps the gem
 122-----
674 123 
.675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit if the patch was based on a public commit then the `-3` option is generally much smarter about applying a conflicting patch:124If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn't on by default because it doesn't work if the commit the patch says it was based on isn't in your repository. If you do have that commit if the patch was based on a public commit then the `-3` option is generally much smarter about applying a conflicting patch:
676 125 
. 126[source,console]
 127-----
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch128$ git am -3 0001-seeing-if-this-helps-the-gem.patch
678    Applying: seeing if this helps the gem129Applying: seeing if this helps the gem
679    error: patch failed: ticgit.gemspec:1130error: patch failed: ticgit.gemspec:1
680    error: ticgit.gemspec: patch does not apply131error: ticgit.gemspec: patch does not apply
681    Using index info to reconstruct a base tree...132Using index info to reconstruct a base tree...
682    Falling back to patching base and 3-way merge...133Falling back to patching base and 3-way merge...
683    No changes -- Patch already applied.134No changes -- Patch already applied.
 135-----
684 136 
.685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict.137In this case, this patch had already been applied. Without the `-3` option, it looks like a conflict.
686 138 
.687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it:139If you're applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it:
688 140 
. 141[source,console]
 142-----
689    $ git am -3 -i mbox143$ git am -3 -i mbox
690    Commit Body is:144Commit Body is:
691    --------------------------145--------------------------
692    seeing if this helps the gem146seeing if this helps the gem
693    --------------------------147--------------------------
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all148Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all
 149-----
695 150 
.696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so.151This is nice if you have a number of patches saved, because you can view the patch first if you don't remember what it is, or not apply the patch if you've already done so.
697 152 
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch.153When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch.
699 154 
. 155[[_checking_out_remotes]]
700### Checking Out Remote Branches ### 156==== Checking Out Remote Branches 
701 157 
. 158(((branches, remote)))
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally.159If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally.
703 160 
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally:161For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally:
705 162 
. 163[source,console]
 164-----
706    $ git remote add jessica git://github.com/jessica/myproject.git165$ git remote add jessica git://github.com/jessica/myproject.git
707    $ git fetch jessica166$ git fetch jessica
708    $ git checkout -b rubyclient jessica/ruby-client167$ git checkout -b rubyclient jessica/ruby-client
 168-----
709 169 
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup.170If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup.
711 171 
.712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier it depends largely on how you develop and how your contributors develop.172This is most useful if you're working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You're also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier it depends largely on how you develop and how your contributors develop.
713 173 
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access.174The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access.
715 175 
.716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference:176If you aren't working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn't save the URL as a remote reference:
717 177 
. 178[source,console]
 179-----
718    $ git pull git://github.com/onetimeguy/project.git180$ git pull https://github.com/onetimeguy/project
719    From git://github.com/onetimeguy/project181From https://github.com/onetimeguy/project
720     * branch            HEAD       -> FETCH_HEAD182 * branch            HEAD       -> FETCH_HEAD
721    Merge made by recursive.183Merge made by recursive.
 184-----
722 185 
. 186[[_what_is_introduced]]
723### Determining What Is Introduced ### 187==== Determining What Is Introduced 
724 188 
. 189(((branches, diffing)))
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch.190Now you have a topic branch that contains contributed work. At this point, you can determine what you'd like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you'll be introducing if you merge this into your main branch.
726 191 
.727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this:192It's often helpful to get a review of all the commits that are in this branch but that aren't in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. This does the same thing as the `master..contrib` format that we used earlier. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this:
728 193 
. 194[source,console]
 195-----
729    $ git log contrib --not master196$ git log contrib --not master
730    commit 5b6235bd297351589efc4d73316f0a68d484f118197commit 5b6235bd297351589efc4d73316f0a68d484f118
731    Author: Scott Chacon <schacon@gmail.com>198Author: Scott Chacon <schacon@gmail.com>
732    Date:   Fri Oct 24 09:53:59 2008 -0700199Date:   Fri Oct 24 09:53:59 2008 -0700
733 200 
.734        seeing if this helps the gem201    seeing if this helps the gem
735 202 
.736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0203commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
737    Author: Scott Chacon <schacon@gmail.com>204Author: Scott Chacon <schacon@gmail.com>
738    Date:   Mon Oct 22 19:38:36 2008 -0700205Date:   Mon Oct 22 19:38:36 2008 -0700
739 206 
.740        updated the gemspec to hopefully work better207    updated the gemspec to hopefully work better
 208-----
741 209 
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit.210To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit.
743 211 
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this:212To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this:
745 213 
. 214[source,console]
 215-----
746    $ git diff master216$ git diff master
 217-----
747 218 
. 219This command gives you a diff, but it may be misleading.
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line.220If your `master` branch has moved forward since you created the topic branch from it, then you'll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you're on and the snapshot of the last commit on the `master` branch. For example, if you've added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line.
749 221 
.750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch.222If `master` is a direct ancestor of your topic branch, this isn't a problem; but if the two histories have diverged, the diff will look like you're adding all the new stuff in your topic branch and removing everything unique to the `master` branch.
751 223 
.752What you really want to see are the changes added to the topic branch the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch.224What you really want to see are the changes added to the topic branch the work you'll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch.
753 225 
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it:226Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it:
755 227 
. 228[source,console]
 229-----
756    $ git merge-base contrib master230$ git merge-base contrib master
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca64923136c7dba2c95e6bbb78dfa822519ecfec6e1ca649
758    $ git diff 36c7db232$ git diff 36c7db
 233-----
759 234 
.760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch:235However, that isn't convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you're on and its common ancestor with another branch:
761 236 
. 237[source,console]
 238-----
762    $ git diff master...contrib239$ git diff master...contrib
 240-----
763 241 
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember.242This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember.
765 243 
.766### Integrating Contributed Work ### 244==== Integrating Contributed Work 
767 245 
. 246(((integrating work)))
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them.247When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so we'll cover a few of them.
769 248 
.770#### Merging Workflows #### 249===== Merging Workflows 
771 250 
. 251(((workflows, merging)))
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20.252One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you've done or that someone has contributed and you've verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like <<merwf_a>> and merge `ruby_client` first and then `php_client` next, then your history will end up looking like <<merwf_b>>.
773 253 
.774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
 254[[merwf_a]]
 255.History with several topic branches.
 256image::images/merging-workflows-1.png[History with several topic branches.]
776 257 
.777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
 258[[merwf_b]]
 259.After a topic branch merge.
 260image::images/merging-workflows-2.png[After a topic branch merge.]
779 261 
.780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects.262That is probably the simplest workflow, but it can possibly be problematic if you're dealing with larger or more stable projects where you want to be really careful about what you introduce.
781 263 
.782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23).264If you have a more important project, you might want to use a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (<<merwf_c>>), you merge it into `develop` (<<merwf_d>>); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (<<merwf_e>>).
783 265 
.784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
 266[[merwf_c]]
 267.Before a topic branch merge.
 268image::images/merging-workflows-3.png[Before a topic branch merge.]
786 269 
.787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
 270[[merwf_d]]
 271.After a topic branch merge.
 272image::images/merging-workflows-4.png[After a topic branch merge.]
789 273 
.790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
 274[[merwf_e]]
 275.After a project release.
 276image::images/merging-workflows-5.png[After a topic branch release.]
792 277 
.793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff.278This way, when people clone your project's repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff.
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch.279You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch.
795 280 
.796#### Large-Merging Workflows #### 281===== Large-Merging Workflows 
797 282 
. 283(((workflows, "merging (large)")))
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together.284The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it's collected into topic branches in the maintainer's repository in a manner similar to what we've described (see <<merwf_f>>). At this point, the topics are evaluated to determine whether they're safe and ready for consumption or whether they need more work. If they're safe, they're merged into `next`, and that branch is pushed up so everyone can try the topics integrated together.
799 285 
.800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
 286[[merwf_f]]
 287.Managing a complex series of parallel contributed topic branches.
 288image::images/large-merges-1.png[Managing a complex series of parallel contributed topic branches.]
802 289 
.803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 290If the topics still need work, they're merged into `pu` instead. When it's determined that they're totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn't yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often: 
804 291 
.805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
 292.Merging contributed topic branches into long-term integration branches.
 293image::images/large-merges-2.png[Merging contributed topic branches into long-term integration branches.]
807 294 
.808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 295When a topic branch has finally been merged into `master`, it's removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions.  
809 296 
. 297[[_rebase_cherry_pick]]
810#### Rebasing and Cherry Picking Workflows #### 298===== Rebasing and Cherry Picking Workflows 
811 299 
. 300(((workflows, rebasing and cherry-picking)))
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history.301Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you'll end up with a linear project history.
813 302 
. 303(((git commands, cherry-pick)))
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 304The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you're currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you'd prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like this: 
815 305 
.816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
 306.Example history before a cherry-pick.
 307image::images/rebasing-1.png[Example history before a cherry-pick.]
818 308 
819If you want to pull commit `e43a6` into your master branch, you can run309If you want to pull commit `e43a6` into your master branch, you can run
820 310 
. 311[source,console]
 312-----
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf313$ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf
822    Finished one cherry-pick.314Finished one cherry-pick.
823    [master]: created a0a41a9: "More friendly message when locking the index fails."315[master]: created a0a41a9: "More friendly message when locking the index fails."
824     3 files changed, 17 insertions(+), 3 deletions(-)316 3 files changed, 17 insertions(+), 3 deletions(-)
 317-----
825 318 
.826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 319This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like this: 
827 320 
.828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
 321.History after cherry-picking a commit on a topic branch.
 322image::images/rebasing-2.png[History after cherry-picking a commit on a topic branch.]
830 323 
.831Now you can remove your topic branch and drop the commits you didn’t want to pull in.324Now you can remove your topic branch and drop the commits you didn't want to pull in.
832 325 
. 326===== Rerere
 327 
 328(((git commands, rerere)))(((rerere)))
 329If you're doing lots of merging and rebasing, or you're maintaining a long-lived topic branch, Git has a feature called ``rerere'' that can help.
 330 
 331Rerere stands for ``reuse recorded resolution'' – it's a way of shortcutting manual conflict resolution.
 332When rerere is enabled, Git will keep a set of pre- and post-images from successful merges, and if it notices that there's a conflict that looks exactly like one you've already fixed, it'll just use the fix from last time, without bothering you with it.
 333 
 334This feature comes in two parts: a configuration setting and a command.
 335The configuration setting is `rerere.enabled`, and it's handy enough to put in your global config:
 336 
 337[source,console]
 338----
 339$ git config --global rerere.enabled true
 340----
 341 
 342Now, whenever you do a merge that resolves conflicts, the resolution will be recorded in the cache in case you need it in the future.
 343 
 344If you need to, you can interact with the rerere cache using the `git rerere` command.
 345When it's invoked alone, Git checks its database of resolutions and tries to find a match with any current merge conflicts and resolve them (although this is done automatically if `rerere.enabled` is set to `true`).
 346There are also subcommands to see what will be recorded, to erase specific resolution from the cache, and to clear the entire cache. We will cover rerere in more detail in <<_rerere>>.
 347 
 348[[_tagging_releases]]
833### Tagging Your Releases ### 349==== Tagging Your Releases 
834 350 
. 351(((tags)))(((tags, signing)))
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this:352When you've decided to cut a release, you'll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as discussed in <<_git_basics_chapter>>. If you decide to sign the tag as the maintainer, the tagging may look something like this:
836 353 
. 354[source,console]
 355-----
837    $ git tag -s v1.5 -m 'my signed 1.5 tag'356$ git tag -s v1.5 -m 'my signed 1.5 tag'
838    You need a passphrase to unlock the secret key for357You need a passphrase to unlock the secret key for
839    user: "Scott Chacon <schacon@gmail.com>"358user: "Scott Chacon <schacon@gmail.com>"
840    1024-bit DSA key, ID F721C45A, created 2009-02-093591024-bit DSA key, ID F721C45A, created 2009-02-09
 360-----
841 361 
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`:362If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`:
843 363 
. 364[source,console]
 365-----
844    $ gpg --list-keys366$ gpg --list-keys
845    /Users/schacon/.gnupg/pubring.gpg367/Users/schacon/.gnupg/pubring.gpg
846    ---------------------------------368---------------------------------
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09]369pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09]
848    uid                  Scott Chacon <schacon@gmail.com>370uid                  Scott Chacon <schacon@gmail.com>
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09]371sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09]
 372-----
850 373 
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob:374Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob:
852 375 
. 376[source,console]
 377-----
853    $ gpg -a --export F721C45A | git hash-object -w --stdin378$ gpg -a --export F721C45A | git hash-object -w --stdin
854    659ef797d181633c87ec71ac3f9ba29fe5775b92379659ef797d181633c87ec71ac3f9ba29fe5775b92
 380-----
855 381 
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you:382Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you:
857 383 
. 384[source,console]
 385-----
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92386$ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92
 387-----
859 388 
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG:389If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG:
861 390 
. 391[source,console]
 392-----
862    $ git show maintainer-pgp-pub | gpg --import393$ git show maintainer-pgp-pub | gpg --import
 394-----
863 395 
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification.396They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification.
865 397 
. 398[[_build_number]]
866### Generating a Build Number ### 399==== Generating a Build Number 
867 400 
. 401(((build numbers)))(((git commands, describe)))
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing:402Because Git doesn't have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you're describing:
869 403 
. 404[source,console]
 405-----
870    $ git describe master406$ git describe master
871    v1.6.2-rc1-20-g8c5b85c407v1.6.2-rc1-20-g8c5b85c
 408-----
872 409 
.873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name.410This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you're describing a commit that you have directly tagged, it gives you the tag name.
874 411 
.875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated.412The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you're using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated.
876 413 
. 414[[_preparing_release]]
877### Preparing a Release ### 415==== Preparing a Release 
878 416 
. 417(((releasing)))(((git commands, archive)))
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`:418Now you want to release a build. One of the things you'll want to do is create an archive of the latest snapshot of your code for those poor souls who don't use Git. The command to do this is `git archive`:
880 419 
. 420[source,console]
 421-----
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz422$ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz
882    $ ls *.tar.gz423$ ls *.tar.gz
883    v1.6.2-rc1-20-g8c5b85c.tar.gz424v1.6.2-rc1-20-g8c5b85c.tar.gz
 425-----
884 426 
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`:427If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`:
886 428 
. 429[source,console]
 430-----
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip431$ git archive master --prefix='project/' --format=zip > `git describe master`.zip
 432-----
888 433 
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people.434You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people.
890 435 
. 436[[_the_shortlog]]
891### The Shortlog ### 437==== The Shortlog 
892 438 
. 439(((git commands, shortlog)))
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1:440It's time to e-mail your mailing list of people who want to know what's happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1:
894 441 
. 442[source,console]
 443-----
895    $ git shortlog --no-merges master --not v1.0.1444$ git shortlog --no-merges master --not v1.0.1
896    Chris Wanstrath (8):445Chris Wanstrath (8):
897          Add support for annotated tags to Grit::Tag446      Add support for annotated tags to Grit::Tag
898          Add packed-refs annotated tag support.447      Add packed-refs annotated tag support.
899          Add Grit::Commit#to_patch448      Add Grit::Commit#to_patch
900          Update version and History.txt449      Update version and History.txt
901          Remove stray `puts`450      Remove stray `puts`
902          Make ls_tree ignore nils451      Make ls_tree ignore nils
903 452 
.904    Tom Preston-Werner (4):453Tom Preston-Werner (4):
905          fix dates in history454      fix dates in history
906          dynamic version method455      dynamic version method
907          Version bump to 1.0.2456      Version bump to 1.0.2
908          Regenerated gemspec for version 1.0.2457      Regenerated gemspec for version 1.0.2
 458-----
909 459 
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list.460You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list.
.911  
912## Summary ## 
913  
914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master. 
915 461 
+
+ diff --git a/book/05-distributed-git/sections/distributed-workflows.asc b/book/05-distributed-git/sections/distributed-workflows.asc index 560f38e2..d2ef33b2 100644 --- a/book/05-distributed-git/sections/distributed-workflows.asc +++ b/book/05-distributed-git/sections/distributed-workflows.asc @@ -1,26 +1,54 @@ +////////////////////////// === Distributed Workflows +////////////////////////// +=== 分散作業の流れ (((workflows))) +////////////////////////// Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub – that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so we'll cover a few common paradigms that take advantage of this flexibility. We'll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. - +////////////////////////// +中央管理型のバージョン管理システム (Centralized Version Control System: CVCS) とは違い、Git は分散型だという特徴があります。この特徴を生かすと、プロジェクトの開発者間での共同作業をより柔軟に行えるようになります。 +中央管理型のシステムでは、個々の開発者は中央のハブに対するノードという位置づけとなります。 +しかし Git では、各開発者はノードであると同時にハブにもなり得ます。つまり、誰もが他のリポジトリに対してコードを提供することができ、誰もが公開リポジトリを管理して他の開発者の作業を受け入れることもできるということです。 +これは、みなさんのプロジェクトや開発チームでの作業の流れにさまざまな可能性をもたらします。本章では、この柔軟性を生かすいくつかの実例を示します。 +それぞれについて、利点だけでなく想定される弱点についても扱うので、適宜取捨選択してご利用ください。 + +////////////////////////// ==== Centralized Workflow +////////////////////////// +==== 中央集権型のワークフロー (((workflows, centralized))) +////////////////////////// In centralized systems, there is generally a single collaboration model–the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes – consumers of that hub – and synchronize to that one place. +////////////////////////// +中央管理型のシステムでは共同作業の方式は一つだけです。それが中央集権型のワークフローです。 +これは、中央にある一つのハブ (リポジトリ) がコードを受け入れ、他のメンバー全員がそこに作業内容を同期させるという流れです。 +多数の開発者がハブにつながるノードとなり、作業を一か所に集約します。 +////////////////////////// .Centralized workflow. image::images/centralized.png[Centralized workflow.] +////////////////////////// +.中央集権型のワークフロー +image::images/centralized.png[中央集権型のワークフロー] +////////////////////////// This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one's work before pushing changes up, so as not to overwrite the first developer's changes. This concept is as true in Git as it is in Subversion(((Subversion))) (or any CVCS), and this model works perfectly well in Git. +////////////////////////// +二人の開発者がハブからのクローンを作成して個々に変更をした場合、最初の開発者がそれをプッシュするのは特に問題なくできます。 +もう一人の開発者は、まず最初の開発者の変更をマージしてからサーバーへのプッシュを行い、最初の開発者の変更を消してしまわないようにします。 +この考え方は、Git 上でも Subversion (((Subversion))) (あるいはその他の CVCS) と同様に生かせます。そしてこの方式は Git でも完全に機能します。 +////////////////////////// If you are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won't let users overwrite each other. Say John and Jessica both start working at the same time. @@ -28,61 +56,130 @@ John finishes his change and pushes it to the server. Then Jessica tries to push her changes, but the server rejects them. She is told that she's trying to push non-fast-forward changes and that she won't be able to do so until she fetches and merges. This workflow is attractive to a lot of people because it's a paradigm that many are familiar and comfortable with. +////////////////////////// +小規模なチームに所属していたり、組織内で既に中央集権型のワークフローになじんでいたりなどの場合は、Git でその方式を続けることも簡単です。 +リポジトリをひとつ立ち上げて、チームのメンバー全員がそこにプッシュできるようにすればいいのです。Git は他のユーザーの変更を上書きしてしまうことはありません。 +たとえば、John と Jessica が作業を一斉に始めたとしましょう。 +先に作業が終わった John が、変更をサーバーにプッシュします。 +次に、Jessica が変更をプッシュしようとすると、サーバー側でそのプッシュは拒否されます。 +そして Jessica は、直接プッシュすることはできないのでまずは変更内容をマージする必要があることを Git のエラーメッセージから気づきます。 +この方式は多くの人にとって魅力的なものでしょう。これまでにもなじみのある方式だし、今までそれでうまくやってきたからです。 This is also not limited to small teams. With Git's branching model, it's possible for hundreds of developers to successfully work on a single project through dozens of branches simultaneously. [[_integration_manager]] +////////////////////////// ==== Integration-Manager Workflow +////////////////////////// +==== 統合マネージャー型のワークフロー (((workflows, integration manager))) +////////////////////////// Because Git allows you to have multiple remote repositories, it's possible to have a workflow where each developer has write access to their own public repository and read access to everyone else's. This scenario often includes a canonical repository that represents the ``official'' project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. The maintainer can then add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see <>): - +////////////////////////// +Git では複数のリモートリポジトリを持つことができるので、書き込み権限を持つ公開リポジトリを各自が持ち、他のメンバーからは読み込みのみのアクセスを許可するという方式をとることもできます。 +この方式には、「公式」プロジェクトを表す公式なリポジトリも含みます。 +このプロジェクトの開発に参加するには、まずプロジェクトのクローンを自分用に作成し、変更はそこにプッシュします。 +次に、メインプロジェクトのメンテナーに「変更を取り込んでほしい」とお願いします。 +メンテナーはあなたのリポジトリをリモートに追加し、変更を取り込んでマージします。そしてその結果をリポジトリにプッシュするのです。 +この作業の流れは次のようになります ( <> を参照ください)。 + +////////////////////////// 1. The project maintainer pushes to their public repository. 2. A contributor clones that repository and makes changes. 3. The contributor pushes to their own public copy. 4. The contributor sends the maintainer an e-mail asking them to pull changes. 5. The maintainer adds the contributor's repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. +////////////////////////// +1. プロジェクトのメンテナーが公開リポジトリにプッシュする +2. 開発者がそのリポジトリをクローンし、変更を加える +3. 開発者が各自の公開リポジトリにプッシュする +4. 開発者がメンテナーに「変更を取り込んでほしい」というメールを送る +5. メンテナーが開発者のリポジトリをリモートに追加し、それをマージする +6. マージした結果をメンテナーがメインリポジトリにプッシュする [[wfdiag_b]] +////////////////////////// .Integration-manager workflow. image::images/integration-manager.png[Integration-manager workflow.] +////////////////////////// +.統合マネージャー型のワークフロー +image::images/integration-manager.png[統合マネージャー型のワークフロー] (((forking))) +////////////////////////// This is a very common workflow with hub-based tools like GitHub or GitLab, where it's easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don't have to wait for the project to incorporate their changes – each party can work at their own pace. +////////////////////////// +これは GitHub や GitLab のようなハブ型のツールでよく使われている流れです。プロジェクトを容易にフォークでき、そこにプッシュした内容をみんなに簡単に見てもらえます。 +この方式の主な利点の一つは、あなたはそのまま開発を続行し、メインリポジトリのメンテナーはいつでも好きなタイミングで変更を取り込めるということです。 +変更を取り込んでもらえるまで作業を止めて待つ必要はありません。自分のペースで作業を進められるのです。 +////////////////////////// ==== Dictator and Lieutenants Workflow +////////////////////////// +==== 独裁者と若頭型のワークフロー (((workflows, dictator and lieutenants))) +////////////////////////// This is a variant of a multiple-repository workflow. It's generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they're called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator's repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see <>): - +////////////////////////// +これは、複数リポジトリ型のワークフローのひとつです。 +何百人もの開発者が参加するような巨大なプロジェクトで採用されています。有名どころでは Linux カーネルがこの方式です。 +統合マネージャーを何人も用意し、それぞれにリポジトリの特定の部分を担当させます。彼らは若頭 (lieutenant) と呼ばれます。 +そしてすべての若頭をまとめる統合マネージャーが「慈悲深い独裁者 (benevalent dictator)」です。 +独裁者のリポジトリが基準リポジトリとなり、すべてのメンバーはこれをプルします。 +この作業の流れは次のようになります ( <> を参照ください)。 + +////////////////////////// 1. Regular developers work on their topic branch and rebase their work on top of `master`. The `master` branch is that of the dictator. 2. Lieutenants merge the developers' topic branches into their `master` branch. 3. The dictator merges the lieutenants' `master` branches into the dictator's `master` branch. 4. The dictator pushes their `master` to the reference repository so the other developers can rebase on it. +////////////////////////// +1. 一般の開発者はトピックブランチ上で作業を進め、`master` の先頭にリベースする。独裁者の `master` ブランチがマスターとなる +2. 若頭が各開発者のトピックブランチを自分の `master` ブランチにマージする +3. 独裁者が各若頭の `master` ブランチを自分の `master` ブランチにマージする +4. 独裁者が自分の `master` をリポジトリにプッシュし、他のメンバーがリベースできるようにする [[wfdiag_c]] +////////////////////////// .Benevolent dictator workflow. image::images/benevolent-dictator.png[Benevolent dictator workflow.] +////////////////////////// +.慈悲深い独裁者型のワークフロー +image::images/benevolent-dictator.png[慈悲深い独裁者型のワークフロー] +////////////////////////// This kind of workflow isn't common, but can be useful in very big projects, or in highly hierarchical environments. It allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. +////////////////////////// +この手のワークフローはあまり一般的ではありませんが、大規模なプロジェクトや高度に階層化された環境では便利です。 +プロジェクトリーダー (独裁者) が大半の作業を委譲し、サブセット単位である程度まとまってからコードを統合することができるからです。 +////////////////////////// ==== Workflows Summary +////////////////////////// +==== ワークフローのまとめ +////////////////////////// These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (hopefully) determine which workflow combination may work for you, we'll cover some more specific examples of how to accomplish the main roles that make up the different flows. In the next section, you'll learn about a few common patterns for contributing to a project. +////////////////////////// +Git のような分散システムでよく使われるワークフローの多くは、実社会での何らかのワークフローにあてはめて考えることができます。 +これで、どのワークフローがあなたに合うかがわかったことでしょう (ですよね?)。 +次は、より特化した例をあげて個々のフローを実現する方法を見ていきましょう。 diff --git a/book/05-distributed-git/sections/maintaining.asc b/book/05-distributed-git/sections/maintaining.asc index 2f521758..21b47f5d 100644 --- a/book/05-distributed-git/sections/maintaining.asc +++ b/book/05-distributed-git/sections/maintaining.asc @@ -1,59 +1,108 @@ +////////////////////////// === Maintaining a Project +////////////////////////// +=== プロジェクトの運営 (((maintaining a project))) +////////////////////////// In addition to knowing how to effectively contribute to a project, you'll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you've added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. +////////////////////////// +プロジェクトに貢献する方法だけでなく、プロジェクトを運営する方法についても知っておくといいでしょう。 +たとえば `format-patch` を使ってメールで送られてきたパッチを処理する方法や、別のリポジトリのリモートブランチでの変更を統合する方法などです。 +本流のリポジトリを保守するにせよパッチの検証や適用を手伝うにせよ、どうすれば貢献者たちにとってわかりやすくなるかを知っておくべきでしょう。 +////////////////////////// ==== Working in Topic Branches +////////////////////////// +==== トピックブランチでの作業 (((branches, topic))) +////////////////////////// When you're thinking of integrating new work, it's generally a good idea to try it out in a topic branch – a temporary branch specifically made to try out that new work. This way, it's easy to tweak a patch individually and leave it if it's not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you're going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well – such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you'll remember, you can create the branch based off your master branch like this: +////////////////////////// +新しい機能を組み込もうと考えている場合は、トピックブランチを作ることをおすすめします。トピックブランチとは、新しく作業を始めるときに一時的に作るブランチのことです。 +そうすれば、そのパッチだけを個別にいじることができ、もしうまくいかなかったとしてもすぐに元の状態に戻すことができます。 +ブランチの名前は、今からやろうとしている作業の内容にあわせたシンプルな名前にしておきます。たとえば `ruby_client` などといったものです。そうすれば、しばらく時間をおいた後でそれを廃棄することになったときに、内容を思い出しやすくなります。 +Git プロジェクトのメンテナは、ブランチ名に名前空間を使うことが多いようです。たとえば `sc/ruby_client` のようになり、ここでの `sc` はその作業をしてくれた人の名前を短縮したものとなります。 +自分の master ブランチをもとにしたブランチを作成する方法は、このようになります。 [source,console] ----- $ git branch sc/ruby_client master ----- +////////////////////////// Or, if you want to also switch to it immediately, you can use the `checkout -b` option: +////////////////////////// +作成してすぐそのブランチに切り替えたい場合は、`checkout -b` オプションを使います。 [source,console] ----- $ git checkout -b sc/ruby_client master ----- +////////////////////////// Now you're ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. +////////////////////////// +受け取った作業はこのトピックブランチですすめ、長期ブランチに統合するかどうかを判断することになります。 [[_patches_from_email]] +////////////////////////// ==== Applying Patches from E-mail +////////////////////////// +==== メールで受け取ったパッチの適用 (((email, applying patches from))) +////////////////////////// If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. +////////////////////////// +あなたのプロジェクトへのパッチをメールで受け取った場合は、まずそれをトピックブランチに適用して中身を検証します。 +メールで届いたパッチを適用するには `git apply` と `git am` の二通りの方法があります。 +////////////////////////// ===== Applying a Patch with apply +////////////////////////// +===== apply によるパッチの適用 (((git commands, apply))) +////////////////////////// If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command (which is not recommended; see the next section), you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: +////////////////////////// +`git diff` あるいは Unix の `diff` コマンドで作ったパッチ(パッチの作り方としては推奨できません。次節で理由を説明します)を受け取ったときは、`git apply` コマンドを使ってパッチを適用します。 +パッチが `/tmp/patch-ruby-client.patch` にあるとすると、このようにすればパッチを適用できます。 [source,console] ----- $ git apply /tmp/patch-ruby-client.patch ----- +////////////////////////// This modifies the files in your working directory. It's almost identical to running a `patch -p1` command to apply the patch, although it's more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they're described in the `git diff` format, which `patch` won't do. Finally, `git apply` is an ``apply all or abort all'' model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more conservative than `patch`. It won't create a commit for you – after running it, you must stage and commit the changes introduced manually. - +////////////////////////// +これは、作業ディレクトリ内のファイルを変更します。 +`patch -p1` コマンドでパッチをあてるのとほぼ同じなのですが、それ以上に「これでもか」というほどのこだわりを持ってパッチを適用するので fuzzy マッチになる可能性が少なくなります。 +また、`git diff` 形式ではファイルの追加・削除やファイル名の変更も扱うことができますが、`patch` コマンドにはそれはできません。 +そして最後に、`git apply` は「全部適用するか、あるいは一切適用しないか」というモデルを採用しています。一方 `patch` コマンドの場合は、途中までパッチがあたった中途半端な状態になって困ることがあります。 +`git apply` のほうが、 `patch` よりも慎重に処理を行うのです。 +`git apply` コマンドはコミットを作成するわけではありません。実行した後で、その変更をステージしてコミットする必要があります。 + +////////////////////////// You can also use git apply to see if a patch applies cleanly before you try actually applying it – you can run `git apply --check` with the patch: +////////////////////////// +git apply を使って、そのパッチをきちんと適用できるかどうかを事前に確かめることができます。パッチをチェックするには `git apply --check` を実行します。 [source,console] ----- @@ -62,20 +111,35 @@ error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply ----- +////////////////////////// If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. +////////////////////////// +何も出力されなければ、そのパッチはうまく適用できるということです。 +このコマンドは、チェックに失敗した場合にゼロ以外の値を返して終了します。スクリプト内でチェックしたい場合などにはこの返り値を使用します。 [[_git_am]] +////////////////////////// ===== Applying a Patch with `am` +////////////////////////// +===== `am` でのパッチの適用 (((git commands, am))) +////////////////////////// If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. +////////////////////////// +コードを提供してくれた人が Git のユーザーで、`format-patch` コマンドを使ってパッチを送ってくれたとしましょう。この場合、あなたの作業はより簡単になります。パッチの中に、作者の情報やコミットメッセージも含まれているからです。 +「パッチを作るときには、できるだけ `diff` ではなく `format-patch` を使ってね」とお願いしてみるのもいいでしょう。 +昔ながらの形式のパッチが届いたときだけは `git apply` を使わなければならなくなります。 +////////////////////////// To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: +////////////////////////// +`format-patch` で作ったパッチを適用するには `git am` を使います。技術的なお話をすると、`git am` は mbox ファイルを読み込む仕組みになっています。mbox はシンプルなプレーンテキスト形式で、一通あるいは複数のメールのメッセージをひとつのテキストファイルにまとめるためのものです。中身はこのようになります。 [source,console] ----- @@ -87,12 +151,21 @@ Subject: [PATCH 1/2] add limit to log function Limit log functionality to the first 20 ----- +////////////////////////// This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +////////////////////////// +先ほどのセクションでごらんいただいたように、format-patch コマンドの出力結果もこれと同じ形式で始まっていますね。 +これは、mbox 形式のメールフォーマットとしても正しいものです。 +git send-email を正しく使ったパッチが送られてきた場合、受け取ったメールを mbox 形式で保存して git am コマンドでそのファイルを指定すると、すべてのパッチの適用が始まります。 +複数のメールをまとめてひとつの mbox に保存できるメールソフトを使っていれば、送られてきたパッチをひとつのファイルにまとめて git am で一度に適用することもできます。 +////////////////////////// However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: +////////////////////////// +しかし、`format-patch` で作ったパッチがチケットシステム (あるいはそれに類する何か) にアップロードされたような場合は、まずそのファイルをローカルに保存して、それを `git am` に渡すことになります。 [source,console] ----- @@ -100,9 +173,12 @@ $ git am 0001-limit-log-function.patch Applying: add limit to log function ----- +////////////////////////// You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail's `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example above, the commit generated would look something like this: +////////////////////////// +どんなパッチを適用したのかが表示され、コミットも自動的に作られます。作者の情報はメールの `From` ヘッダと `Date` ヘッダから取得し、コミットメッセージは `Subject` とメールの本文 (パッチより前の部分) から取得します。たとえば、先ほどごらんいただいた mbox の例にあるパッチを適用した場合は次のようなコミットとなります。 ----- $ git log --pretty=fuller -1 @@ -117,12 +193,21 @@ CommitDate: Thu Apr 9 09:19:06 2009 -0700 Limit log functionality to the first 20 ----- +////////////////////////// The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +////////////////////////// +`Commit` には、そのパッチを適用した人と適用した日時が表示されます。 +`Author` には、そのパッチを実際に作成した人と作成した日時が表示されます。 +////////////////////////// But it's possible that the patch won't apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven't applied yet. In that case, the `git am` process will fail and ask you what you want to do: +////////////////////////// +しかし、パッチが常にうまく適用できるとは限りません。 +パッチを作成したときの状態と現在のメインブランチとが大きくかけ離れてしまっていたり、そのパッチが別の (まだ適用していない) パッチに依存していたりなどといったことがあり得るでしょう。 +そんな場合は `git am` は失敗し、次にどうするかを聞かれます。 [source,console] ----- @@ -136,20 +221,37 @@ If you would prefer to skip this patch, instead run "git am --skip". To restore the original branch and stop patching run "git am --abort". ----- +////////////////////////// This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way – edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: +////////////////////////// +このコマンドは、何か問題が発生したファイルについて衝突マークを書き込みます。これは、マージやリベースに失敗したときに書き込まれるのとよく似たものです。 +問題を解決する方法も同じです。まずはファイルを編集して衝突を解決し、新しいファイルをステージし、`git am --resolved` を実行して次のパッチに進みます。 [source,console] +////////////////////////// ----- $ (fix the file) $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem ----- +////////////////////////// +----- +$ (ファイルを編集する) +$ git add ticgit.gemspec +$ git am --resolved +Applying: seeing if this helps the gem +----- +////////////////////////// If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn't on by default because it doesn't work if the commit the patch says it was based on isn't in your repository. If you do have that commit – if the patch was based on a public commit – then the `-3` option is generally much smarter about applying a conflicting patch: +////////////////////////// +Git にもうちょっと賢く働いてもらって衝突を回避したい場合は、`-3` オプションを使用します。これは、Git で三方向のマージを行うオプションです。 +このオプションはデフォルトでは有効になっていません。適用するパッチの元になっているコミットがあなたのリポジトリ上のものでない場合に正しく動作しないからです。 +パッチの元になっているコミットが手元にある場合は、`-3` オプションを使うと、衝突しているパッチをうまく適用できます。 [source,console] ----- @@ -162,10 +264,17 @@ Falling back to patching base and 3-way merge... No changes -- Patch already applied. ----- +////////////////////////// In this case, this patch had already been applied. Without the `-3` option, it looks like a conflict. +////////////////////////// +ここでは、既に適用済みのパッチを適用してみました。 +`-3` オプションがなければ、衝突が発生していたことでしょう。 +////////////////////////// If you're applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: +////////////////////////// +たくさんのパッチが含まれる mbox からパッチを適用するときには、`am` コマンドを対話モードで実行することもできます。パッチが見つかるたびに処理を止め、それを適用するかどうかの確認を求められます。 [source,console] ----- @@ -177,17 +286,32 @@ seeing if this helps the gem Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all ----- +////////////////////////// This is nice if you have a number of patches saved, because you can view the patch first if you don't remember what it is, or not apply the patch if you've already done so. +////////////////////////// +これは、「大量にあるパッチについて、内容をまず一通り確認したい」「既に適用済みのパッチは適用しないようにしたい」などの場合に便利です。 +////////////////////////// When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. +////////////////////////// +トピックブランチ上でそのトピックに関するすべてのパッチの適用を済ませてコミットすれば、次はそれを長期ブランチに統合するかどうか (そしてどのように統合するか) を考えることになります。 [[_checking_out_remotes]] +////////////////////////// ==== Checking Out Remote Branches +////////////////////////// +==== リモートブランチのチェックアウト (((branches, remote))) +////////////////////////// If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. +////////////////////////// +自前のリポジトリを持つ Git ユーザーが自分のリポジトリに変更をプッシュし、そのリポジトリの URL とリモートブランチ名だけをあなたにメールで連絡してきた場合のことを考えてみましょう。そのリポジトリをリモートとして登録し、それをローカルにマージすることになります。 +////////////////////////// For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: +////////////////////////// +Jessica から「すばらしい新機能を作ったので、私のリポジトリの `ruby-client` ブランチを見てください」といったメールが来たとします。これを手元でテストするには、リモートとしてこのリポジトリを追加し、ローカルにブランチをチェックアウトします。 [source,console] ----- @@ -196,18 +320,35 @@ $ git fetch jessica $ git checkout -b rubyclient jessica/ruby-client ----- +////////////////////////// If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. +////////////////////////// +「この前のとは違う、別のすばらしい機能を作ったの!」と別のブランチを伝えられた場合は、すでにリモートの設定が済んでいるので単にそのブランチを取得してチェックアウトするだけで確認できます。 +////////////////////////// This is most useful if you're working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You're also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier – it depends largely on how you develop and how your contributors develop. +////////////////////////// +この方法は、誰かと継続的に共同作業を進めていく際に便利です。 +ちょっとしたパッチをたまに提供してくれるだけの人の場合は、パッチをメールで受け取るようにしたほうが時間の節約になるでしょう。全員に自前のサーバーを用意させて、たまに送られてくるパッチを取得するためだけに定期的にリモートの追加と削除を行うなどというのは時間の無駄です。 +ほんの数件のパッチを提供してくれる人たちを含めて数百ものリモートを管理することなど、きっとあなたはお望みではないでしょう。 +しかし、スクリプトやホスティングサービスを使えばこの手の作業は楽になります。つまり、どのような方式をとるかは、あなたや他のメンバーがどのような方式で開発を進めるかによって決まります。 +////////////////////////// The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. +////////////////////////// +この方式のもうひとつの利点は、コミットの履歴も同時に取得できるということです。 +マージの際に問題が起こることもあるでしょうが、そんな場合にも相手の作業が自分側のどの地点に基づくものなのかを知ることができます。適切に三方向のマージが行われるので、`-3` を指定したときに「このパッチの基点となるコミットにアクセスできればいいなぁ」と祈る必要はありません。 +////////////////////////// If you aren't working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn't save the URL as a remote reference: +////////////////////////// +継続的に共同作業を続けるわけではないけれど、それでもこの方式でパッチを取得したいという場合は、リモートリポジトリの URL を `git pull` コマンドで指定することもできます。 +これは一度きりのプルに使うものであり、リモートを参照する URL は保存されません。 [source,console] ----- @@ -218,17 +359,31 @@ Merge made by recursive. ----- [[_what_is_introduced]] +////////////////////////// ==== Determining What Is Introduced +////////////////////////// +==== 何が変わるのかの把握 (((branches, diffing))) +////////////////////////// Now you have a topic branch that contains contributed work. At this point, you can determine what you'd like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you'll be introducing if you merge this into your main branch. +////////////////////////// +トピックブランチの中に、提供してもらった作業が含まれた状態になりました。 +次に何をすればいいのか考えてみましょう。 +このセクションでは、これまでに扱ったいくつかのコマンドを復習します。それらを使って、もしこの変更をメインブランチにマージしたらいったい何が起こるのかを調べていきましょう。 +////////////////////////// It's often helpful to get a review of all the commits that are in this branch but that aren't in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. This does the same thing as the `master..contrib` format that we used earlier. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: +////////////////////////// +トピックブランチのコミットのうち、master ブランチに存在しないコミットの内容をひとつひとつレビューできれば便利でしょう。 +master ブランチに含まれるコミットを除外するには、ブランチ名の前に `--not` オプションを指定します。 +これは、これまで使ってきた `master..contrib` という書式と同じ役割を果たしてくれます。 +たとえば、誰かから受け取った二つのパッチを適用するために `contrib` というブランチを作成したとすると、 [source,console] ----- @@ -246,27 +401,50 @@ Date: Mon Oct 22 19:38:36 2008 -0700 updated the gemspec to hopefully work better ----- +////////////////////////// To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. +////////////////////////// +このようなコマンドを実行すればそれぞれのコミットの内容を確認できます。`git log` に `-p` オプションを渡せば、コミットの後に diff を表示させることもできます。これも以前に説明しましたね。 +////////////////////////// To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: +////////////////////////// +このトピックブランチを別のブランチにマージしたときに何が起こるのかを完全な diff で知りたい場合は、ちょっとした裏技を使わないと正しい結果が得られません。 +おそらく「こんなコマンドを実行するだけじゃないの?」と考えておられることでしょう。 [source,console] ----- $ git diff master ----- +////////////////////////// This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you'll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you're on and the snapshot of the last commit on the `master` branch. For example, if you've added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. +////////////////////////// +このコマンドで表示される diff は、誤解を招きかねないものです。 +トピックブランチを切った時点からさらに `master` ブランチが先に進んでいたとすると、これは少し奇妙に見える結果を返します。 +というのも、Git は現在のトピックブランチの最新のコミットのスナップショットと `master` ブランチの最新のコミットのスナップショットを直接比較するからです。 +トピックブランチを切った後に `master` ブランチ上であるファイルに行を追加したとすると、スナップショットを比較した結果は「トピックブランチでその行を削除しようとしている」状態になります。 +////////////////////////// If `master` is a direct ancestor of your topic branch, this isn't a problem; but if the two histories have diverged, the diff will look like you're adding all the new stuff in your topic branch and removing everything unique to the `master` branch. +////////////////////////// +`master` がトピックブランチの直系の先祖である場合は、これは特に問題とはなりません。しかし二つの歴史が分岐している場合には、diff の結果は「トピックブランチで新しく追加したすべての内容を追加し、`master` ブランチにしかないものはすべて削除する」というものになります。 +////////////////////////// What you really want to see are the changes added to the topic branch – the work you'll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. +////////////////////////// +本当に知りたいのはトピックブランチで変更された内容、つまりこのブランチを master にマージしたときに master に加わる変更です。 +これを知るには、Git に「トピックブランチの最新のコミット」と「トピックブランチと master ブランチの直近の共通の先祖」とを比較させます。 +////////////////////////// Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: +////////////////////////// +共通の先祖を見つけだしてそこからの diff を取得するには、このようにします。 [source,console] ----- @@ -275,105 +453,213 @@ $ git merge-base contrib master $ git diff 36c7db ----- +////////////////////////// However, that isn't convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you're on and its common ancestor with another branch: +////////////////////////// +しかし、これでは不便です。そこで Git には、同じことをより手短にやるための手段としてトリプルドット構文が用意されています。 +`diff` コマンドを実行するときにピリオドを三つ打った後に別のブランチを指定すると、「現在いるブランチの最新のコミット」と「指定した二つのブランチの共通の先祖」とを比較するようになります。 [source,console] ----- $ git diff master...contrib ----- +////////////////////////// This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. +////////////////////////// +このコマンドは、master との共通の先祖から分岐した現在のトピックブランチで変更された内容のみを表示します。 +この構文は、覚えやすいので非常に便利です。 +////////////////////////// ==== Integrating Contributed Work +////////////////////////// +==== 提供された作業の取り込み (((integrating work))) +////////////////////////// When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so we'll cover a few of them. +////////////////////////// +トピックブランチでの作業をメインブランチに取り込む準備ができたら、どのように取り込むかを考えることになります。 +さらに、プロジェクトを運営していくにあたっての全体的な作業の流れはどのようにしたらいいでしょうか? +さまざまな方法がありますが、ここではそのうちのいくつかを紹介します。 +////////////////////////// ===== Merging Workflows +////////////////////////// +===== マージのワークフロー (((workflows, merging))) +////////////////////////// One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you've done or that someone has contributed and you've verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like <> and merge `ruby_client` first and then `php_client` next, then your history will end up looking like <>. +////////////////////////// +シンプルなワークフローのひとつとして、作業を自分の `master` ブランチに取り込むことを考えます。 +ここでは、`master` ブランチで安定版のコードを管理しているものとします。 +トピックブランチでの作業が一段落したら (あるいは誰かから受け取ったパッチをトピックブランチ上で検証し終えたら)、それを master ブランチにマージしてからトピックブランチを削除し、作業を進めることになります。 +`ruby_client` および `php_client` の二つのブランチを持つ <> のようなリポジトリでまず `ruby_client` をマージしてから `php_client` もマージすると、歴史は <> のようになります。 [[merwf_a]] +////////////////////////// .History with several topic branches. image::images/merging-workflows-1.png[History with several topic branches.] +////////////////////////// +.いくつかのトピックブランチを含む履歴 +image::images/merging-workflows-1.png[いくつかのトピックブランチを含む履歴] [[merwf_b]] +////////////////////////// .After a topic branch merge. image::images/merging-workflows-2.png[After a topic branch merge.] +////////////////////////// +.トピックブランチをマージした後の状態 +image::images/merging-workflows-2.png[トピックブランチをマージした後の状態] +////////////////////////// That is probably the simplest workflow, but it can possibly be problematic if you're dealing with larger or more stable projects where you want to be really careful about what you introduce. +////////////////////////// +これがおそらく一番シンプルなワークフローでしょう。ただし、それが問題になることもあります。大規模プロジェクトや安定しているプロジェクトのように、何を受け入れるかを慎重に決めなければいけない場合です。 +////////////////////////// If you have a more important project, you might want to use a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (<>), you merge it into `develop` (<>); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (<>). +////////////////////////// +より重要なプロジェクトの場合は、二段階のマージサイクルを使うこともあるでしょう。 +ここでは、長期間運用するブランチが `master` と `develop` のふたつあるものとします。`master` が更新されるのは安定版がリリースされるときだけで、新しいコードはずべて `develop` ブランチに統合されるという流れです。 +これらのブランチは、両方とも定期的に公開リポジトリにプッシュすることになります。 +新しいトピックブランチをマージする準備ができたら (<>)、それを `develop` にマージします (<>)。そしてリリースタグを打つときに、`master` を現在の `develop` ブランチが指す位置に進めます (<>)。 [[merwf_c]] +////////////////////////// .Before a topic branch merge. image::images/merging-workflows-3.png[Before a topic branch merge.] +////////////////////////// +.トピックブランチのマージ前 +image::images/merging-workflows-3.png[トピックブランチのマージ前] [[merwf_d]] +////////////////////////// .After a topic branch merge. image::images/merging-workflows-4.png[After a topic branch merge.] +////////////////////////// +.トピックブランチのマージ後 +image::images/merging-workflows-4.png[トピックブランチのマージ後] [[merwf_e]] +////////////////////////// .After a project release. image::images/merging-workflows-5.png[After a topic branch release.] +////////////////////////// +.プロジェクトのリリース後 +image::images/merging-workflows-5.png[トピックブランチのリリース後] +////////////////////////// This way, when people clone your project's repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. +////////////////////////// +他の人があなたのプロジェクトをクローンするときには、master をチェックアウトすれば最新の安定版をビルドすることができ、その後の更新を追いかけるのも容易にできるようになります。一方 develop をチェックアウトすれば、さらに最先端の状態を取得することができます。 +この考え方を推し進めると、統合用のブランチを用意してすべての作業をいったんそこにマージするようにもできます。 +統合ブランチ上のコードが安定してテストを通過すれば、それを develop ブランチにマージします。そしてそれが安定していることが確認できたら master ブランチを先に進めるということになります。 +////////////////////////// ===== Large-Merging Workflows +////////////////////////// +===== 大規模マージのワークフロー (((workflows, "merging (large)"))) +////////////////////////// The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it's collected into topic branches in the maintainer's repository in a manner similar to what we've described (see <>). At this point, the topics are evaluated to determine whether they're safe and ready for consumption or whether they need more work. If they're safe, they're merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. +////////////////////////// +Git 開発プロジェクトには、常時稼働するブランチが四つあります。`master`、`next`、そして新しい作業用の `pu` (proposed updates) とメンテナンスバックポート用の `maint` です。 +新しいコードを受け取ったメンテナは、まず自分のリポジトリのトピックブランチにそれを格納します。先ほど説明したのと同じ方式です ( <> を参照ください)。 +そしてその内容を検証し、安全に取り込める状態かさらなる作業が必要かを見極めます。 +だいじょうぶだと判断したらそれを `next` にマージします。このブランチをプッシュすれば、すべてのメンバーがそれを試せるようになります。 [[merwf_f]] +////////////////////////// .Managing a complex series of parallel contributed topic branches. image::images/large-merges-1.png[Managing a complex series of parallel contributed topic branches.] +////////////////////////// +.複数のトピックブランチの並行管理 +image::images/large-merges-1.png[複数のトピックブランチの並行管理] +////////////////////////// If the topics still need work, they're merged into `pu` instead. When it's determined that they're totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn't yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often: +////////////////////////// +さらに作業が必要なトピックについては、`pu` にマージします。 +完全に安定していると判断されたトピックについては改めて `master` にマージされ、`next` にあるトピックのうちまだ `master` に入っていないものを再構築します。 +つまり、`master` はほぼ常に前に進み、`next` は時々リベースされ、`pu` はそれ以上の頻度でリベースされることになります。 +////////////////////////// .Merging contributed topic branches into long-term integration branches. image::images/large-merges-2.png[Merging contributed topic branches into long-term integration branches.] +////////////////////////// +.常時稼働する統合用ブランチへのトピックブランチのマージ +image::images/large-merges-2.png[常時稼働する統合用ブランチへのトピックブランチのマージ] +////////////////////////// When a topic branch has finally been merged into `master`, it's removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. +////////////////////////// +最終的に `master` にマージされたトピックブランチは、リポジトリから削除します。 +Git 開発プロジェクトでは `maint` ブランチも管理しています。これは最新のリリースからフォークしたもので、メンテナンスリリースに必要なバックポート用のパッチを管理します。 +つまり、Git のリポジトリをクローンするとあなたは四つのブランチをチェックアウトすることができるということです。これらのブランチはどれも異なる開発段階を表し、「どこまで最先端を追いかけたいか」「どのように Git プロジェクトに貢献したいか」によって使い分けることになります。メンテナ側では、新たな貢献を受け入れるためのワークフローが整っています。 [[_rebase_cherry_pick]] +////////////////////////// ===== Rebasing and Cherry Picking Workflows +////////////////////////// +===== リベースとチェリーピックのワークフロー (((workflows, rebasing and cherry-picking))) +////////////////////////// Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you'll end up with a linear project history. +////////////////////////// +受け取った作業を master ブランチにマージするのではなく、リベースやチェリーピックを使って master ブランチの先端につなげていく方法を好むメンテナもいます。そのほうがほぼ直線的な歴史を保てるからです。 +トピックブランチでの作業を終えて統合できる状態になったと判断したら、そのブランチで rebase コマンドを実行し、その変更を現在の master (あるいは `develop` などの) ブランチの先端につなげます。 +うまくいけば、`master` ブランチをそのまま前に進めてることでプロジェクトの歴史を直線的に進めることができます。 (((git commands, cherry-pick))) +////////////////////////// The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you're currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you'd prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like this: - +////////////////////////// +あるブランチの作業を別のブランチに移すための手段として、他にチェリーピック (つまみぐい) という方法があります。 +Git におけるチェリーピックとは、コミット単位でのリベースのようなものです。 +あるコミットによって変更された内容をパッチとして受け取り、それを現在のブランチに再適用します。 +トピックブランチでいくつかコミットしたうちのひとつだけを統合したい場合、あるいはトピックブランチで一回だけコミットしたけれどそれをリベースではなくチェリーピックで取り込みたい場合などにこの方法を使用します。 +以下のようなプロジェクトを例にとって考えましょう。 + +////////////////////////// .Example history before a cherry-pick. image::images/rebasing-1.png[Example history before a cherry-pick.] +////////////////////////// +.チェリーピック前の歴史 +image::images/rebasing-1.png[チェリーピック前の歴史] +////////////////////////// If you want to pull commit `e43a6` into your master branch, you can run +////////////////////////// +コミット `e43a6` を master ブランチに取り込むには、次のようにします。 [source,console] ----- @@ -383,13 +669,24 @@ Finished one cherry-pick. 3 files changed, 17 insertions(+), 3 deletions(-) ----- +////////////////////////// This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like this: +////////////////////////// +これは `e43a6` と同じ内容の変更を施しますが、コミットの SHA-1 値は新しくなります。適用した日時が異なるからです。 +これで、歴史は次のように変わりました。 +////////////////////////// .History after cherry-picking a commit on a topic branch. image::images/rebasing-2.png[History after cherry-picking a commit on a topic branch.] +////////////////////////// +.トピックブランチのコミットをチェリーピックした後の歴史 +image::images/rebasing-2.png[トピックブランチのコミットをチェリーピックした後の歴史] +////////////////////////// Now you can remove your topic branch and drop the commits you didn't want to pull in. +////////////////////////// +あとは、このトピックブランチを削除すれば取り込みたくない変更を消してしまうことができます。 ===== Rerere @@ -414,12 +711,20 @@ When it's invoked alone, Git checks its database of resolutions and tries to fin There are also subcommands to see what will be recorded, to erase specific resolution from the cache, and to clear the entire cache. We will cover rerere in more detail in <<_rerere>>. [[_tagging_releases]] +////////////////////////// ==== Tagging Your Releases +////////////////////////// +==== リリース用のタグ付け +////////////////////////// (((tags)))(((tags, signing))) When you've decided to cut a release, you'll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as discussed in <<_git_basics_chapter>>. If you decide to sign the tag as the maintainer, the tagging may look something like this: +////////////////////////// +いよいよリリースする時がきました。おそらく、後からいつでもこのリリースを取得できるようにタグを打っておくことになるでしょう。 +新しいタグを打つ方法は <<_git_basics_chapter>> で説明しました。 +タグにメンテナの署名を入れておきたい場合は、このようにします。 [source,console] ----- @@ -429,9 +734,14 @@ user: "Scott Chacon " 1024-bit DSA key, ID F721C45A, created 2009-02-09 ----- +////////////////////////// If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: +////////////////////////// +タグに署名した場合、署名に使用した PGP 鍵ペアの公開鍵をどのようにして配布するかが問題になるかもしれません。 +Git 開発プロジェクトのメンテナ達がこの問題をどのように解決したかというと、自分たちの公開鍵を blob としてリポジトリに含め、それを直接指すタグを追加することにしました。 +この方法を使うには、まずどの鍵を使うかを決めるために `gpg --list-keys` を実行します。 [source,console] ----- @@ -443,7 +753,10 @@ uid Scott Chacon sub 2048g/45D02282 2009-02-09 [expires: 2010-02-09] ----- +////////////////////////// Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: +////////////////////////// +鍵を直接 Git データベースにインポートするには、鍵をエクスポートしてそれをパイプで `git hash-object` に渡します。これは、鍵の中身を新しい blob として Git に書き込み、その blob の SHA-1 を返します。 [source,console] ----- @@ -451,30 +764,46 @@ $ gpg -a --export F721C45A | git hash-object -w --stdin 659ef797d181633c87ec71ac3f9ba29fe5775b92 ----- +////////////////////////// Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: +////////////////////////// +鍵の中身を Git に取り込めたので、この鍵を直接指定するタグを作成できるようになりました。`hash-object` コマンドで知った SHA-1 値を指定すればいいのです。 [source,console] ----- $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 ----- +////////////////////////// If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: +////////////////////////// +`git push --tags` を実行すると、`maintainer-pgp-pub` タグをみんなと共有できるようになります。誰かがタグを検証したい場合は、あなたの PGP 鍵が入った blob をデータベースから直接プルで取得し、それを PGP にインポートすればいいのです。 [source,console] ----- $ git show maintainer-pgp-pub | gpg --import ----- +////////////////////////// They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show ` will let you give the end user more specific instructions about tag verification. +////////////////////////// +この鍵をインポートした人は、あなたが署名したすべてのタグを検証できるようになります。タグのメッセージに検証手順の説明を含めておけば、`git show ` でエンドユーザー向けに詳しい検証手順を示すことができます。 [[_build_number]] +////////////////////////// ==== Generating a Build Number +////////////////////////// +==== ビルド番号の生成 (((build numbers)))(((git commands, describe))) +////////////////////////// Because Git doesn't have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you're describing: +////////////////////////// +Git では、コミットごとに 'v123' のような単調な番号を振っていくことはありません。もし特定のコミットに対して人間がわかりやすい名前がほしければ、そのコミットに対して `git describe` を実行します。 +Git は、そのコミットに最も近いタグの名前とそのタグからのコミット数、そしてそのコミットの SHA-1 値の一部を使った名前を作成します。 [source,console] ----- @@ -482,21 +811,39 @@ $ git describe master v1.6.2-rc1-20-g8c5b85c ----- +////////////////////////// This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you're describing a commit that you have directly tagged, it gives you the tag name. +////////////////////////// +これで、スナップショットやビルドを公開するときにわかりやすい名前をつけられるようになります。 +実際、Git そのもののソースコードを Git リポジトリからクローンしてビルドすると、`git --version` が返す結果はこの形式になります。 +タグが打たれているコミットを直接指定した場合は、タグの名前が返されます。 +////////////////////////// The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you're using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. +////////////////////////// +`git describe` コマンドは注釈付きのタグ (`-a` あるいは `-s` フラグをつけて作成したタグ) を使います。したがって、`git describe` を使うならリリースタグは注釈付きのタグとしなければなりません。そうすれば、describe したときにコミットの名前を適切につけることができます。 +この文字列を checkout コマンドや show コマンドでの対象の指定に使うこともできますが、これは末尾にある SHA-1 値の省略形に依存しているので将来にわたってずっと使えるとは限りません。 +たとえば Linux カーネルは、最近 SHA-1 オブジェクトの一意性を確認するための文字数を 8 文字から 10 文字に変更しました。そのため、古い `git describe` の出力での名前はもはや使えません。 [[_preparing_release]] +////////////////////////// ==== Preparing a Release +////////////////////////// +==== リリースの準備 (((releasing)))(((git commands, archive))) +////////////////////////// Now you want to release a build. One of the things you'll want to do is create an archive of the latest snapshot of your code for those poor souls who don't use Git. The command to do this is `git archive`: +////////////////////////// +実際にリリースするにあたって行うであろうことのひとつに、最新のスナップショットのアーカイブを作るという作業があります。 +Git を使っていないというかわいそうな人たちにもコードを提供するために。 +その際に使用するコマンドは `git archive` です。 [source,console] ----- @@ -505,23 +852,38 @@ $ ls *.tar.gz v1.6.2-rc1-20-g8c5b85c.tar.gz ----- +////////////////////////// If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: +////////////////////////// +tarball を開けば、プロジェクトのディレクトリの下に最新のスナップショットが得られます。まったく同じ方法で zip アーカイブを作成することもできます。 +この場合は `git archive` で `--format=zip` オプションを指定します。 [source,console] ----- $ git archive master --prefix='project/' --format=zip > `git describe master`.zip ----- +////////////////////////// You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. +////////////////////////// +これで、あなたのプロジェクトのリリース用にすてきな tarball と zip アーカイブができあがりました。これをウェブサイトにアップロードするなりメールで送ってあげるなりしましょう。 [[_the_shortlog]] +////////////////////////// ==== The Shortlog +////////////////////////// +==== 短いログ (((git commands, shortlog))) +////////////////////////// It's time to e-mail your mailing list of people who want to know what's happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: +////////////////////////// +そろそろメーリングリストにメールを送り、プロジェクトに何が起こったのかをみんなに知らせてあげましょう。 +前回のリリースから何が変わったのかの変更履歴を手軽に取得するには `git shortlog` コマンドを使います。 +これは、指定した範囲のすべてのコミットのまとめを出力します。たとえば、直近のリリースの名前が v1.0.1 だった場合は、次のようにすると前回のリリース以降のすべてのコミットの概要が得られます。 [source,console] ----- @@ -541,4 +903,7 @@ Tom Preston-Werner (4): Regenerated gemspec for version 1.0.2 ----- +////////////////////////// You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. +////////////////////////// +v1.0.1 以降のすべてのコミットの概要が、作者別にまとめて得られました。これをメーリングリストに投稿するといいでしょう。 From 32307af7a5b2dd202b51af64a818bf3117a6dc76 Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Wed, 19 Nov 2014 15:13:14 +0900 Subject: [PATCH 3/6] Translate additional contents --- .../sections/contributing.asc | 6 ++++++ .../sections/distributed-workflows.asc | 3 +++ .../sections/maintaining.asc | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/book/05-distributed-git/sections/contributing.asc b/book/05-distributed-git/sections/contributing.asc index 6dcd75ce..3e1130fb 100644 --- a/book/05-distributed-git/sections/contributing.asc +++ b/book/05-distributed-git/sections/contributing.asc @@ -471,9 +471,15 @@ Date: Fri May 29 16:01:27 2009 -0700 removed invalid default value ----- +////////////////////////// The `issue54..origin/master` syntax is a log filter that asks Git to only show the list of commits that are on the latter branch (in this case `origin/master`) that are not on the first branch (in this case `issue54`). We'll go over this syntax in detail in <<_commit_ranges>>. +////////////////////////// +`issue54..origin/master` という記法はログのフィルター用の書式です。このように書くと、後者のブランチ(この例では `origin/master` )には含まれるが前者のブランチ(この例では `issue54` )には含まれないコミットのログだけを表示します。この記法の詳細は <<_commit_ranges>> で説明します。 +////////////////////////// For now, we can see from the output that there is a single commit that John has made that Jessica has not merged in. If she merges `origin/master`, that is the single commit that will modify her local work. +////////////////////////// +この例では、コマンド出力にあるひとつのコミットが、John が作成して Jessica がまだマージしていないものであることがわかります。仮にここで Jessica が `origin/master` をマージするとしましょう。その場合、Jessica の手元のファイルを変更するのは John が作成したコミットひとつだけ、という状態になります。 ////////////////////////// Now, Jessica can merge her topic work into her master branch, merge John's work (`origin/master`) into her `master` branch, and then push back to the server again. diff --git a/book/05-distributed-git/sections/distributed-workflows.asc b/book/05-distributed-git/sections/distributed-workflows.asc index d2ef33b2..c9324141 100644 --- a/book/05-distributed-git/sections/distributed-workflows.asc +++ b/book/05-distributed-git/sections/distributed-workflows.asc @@ -65,7 +65,10 @@ This workflow is attractive to a lot of people because it's a paradigm that many そして Jessica は、直接プッシュすることはできないのでまずは変更内容をマージする必要があることを Git のエラーメッセージから気づきます。 この方式は多くの人にとって魅力的なものでしょう。これまでにもなじみのある方式だし、今までそれでうまくやってきたからです。 +////////////////////////// This is also not limited to small teams. With Git's branching model, it's possible for hundreds of developers to successfully work on a single project through dozens of branches simultaneously. +////////////////////////// +また、この例は小規模なチームに限った話ではありません。Git のブランチモデルを用いてひとつのプロジェクト上にたくさんのブランチを作れば、何百人もの開発者が同時並行で作業を進めることすらできるのです。 [[_integration_manager]] ////////////////////////// diff --git a/book/05-distributed-git/sections/maintaining.asc b/book/05-distributed-git/sections/maintaining.asc index 21b47f5d..b67e8dda 100644 --- a/book/05-distributed-git/sections/maintaining.asc +++ b/book/05-distributed-git/sections/maintaining.asc @@ -691,24 +691,42 @@ Now you can remove your topic branch and drop the commits you didn't want to pul ===== Rerere (((git commands, rerere)))(((rerere))) +////////////////////////// If you're doing lots of merging and rebasing, or you're maintaining a long-lived topic branch, Git has a feature called ``rerere'' that can help. +////////////////////////// +マージやリベースを頻繁に行っているなら、もしくは長く続いているトピックブランチをメンテナンスしているなら、Git の ``rerere'' という機能が役に立つでしょう。 +////////////////////////// Rerere stands for ``reuse recorded resolution'' – it's a way of shortcutting manual conflict resolution. When rerere is enabled, Git will keep a set of pre- and post-images from successful merges, and if it notices that there's a conflict that looks exactly like one you've already fixed, it'll just use the fix from last time, without bothering you with it. +////////////////////////// +Rerere は ``reuse recorded resolution'' の略で、コンフリクトを手動で解消するための手っ取り早い方法です。 +////////////////////////// This feature comes in two parts: a configuration setting and a command. The configuration setting is `rerere.enabled`, and it's handy enough to put in your global config: +////////////////////////// +この機能で用いるのは、設定とコマンドの2つです。 +まず設定のほうは `rerere.enabled` という項目を用います。Git のグローバル設定に登録しておくとよいでしょう。 [source,console] ---- $ git config --global rerere.enabled true ---- +////////////////////////// Now, whenever you do a merge that resolves conflicts, the resolution will be recorded in the cache in case you need it in the future. +////////////////////////// +一度この設定をしておくと、コンフリクトを手動で解消してマージするたびにその内容がキャッシュに記録され、のちのち使えるようになります。 +////////////////////////// If you need to, you can interact with the rerere cache using the `git rerere` command. When it's invoked alone, Git checks its database of resolutions and tries to find a match with any current merge conflicts and resolve them (although this is done automatically if `rerere.enabled` is set to `true`). There are also subcommands to see what will be recorded, to erase specific resolution from the cache, and to clear the entire cache. We will cover rerere in more detail in <<_rerere>>. +////////////////////////// +必要に応じてキャッシュを操作することもできます。`git rerere` コマンドを使うのです。 +このコマンドをオプションなしで実行するとキャッシュが検索され、コンフリクトの内容に合致するものがある場合は Git がそれを用いてコンフリクトの解消を試みます(ただし、`rerere.enabled` が `true` に設定されている場合、一連の処理は自動で行われます)。 +また、サブコマンドも複数用意されています。それらを使うと、キャッシュされようとしている内容の確認、キャッシュされた内容を指定して削除、キャッシュをすべて削除、などができるようになります。rerere については <<_rerere>> で詳しく説明します。 [[_tagging_releases]] ////////////////////////// From 3d28b3847d6437dac6fb2ddbfdb80890f610e45e Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Tue, 25 Nov 2014 20:27:36 +0900 Subject: [PATCH 4/6] Improve translation of additional contents --- book/05-distributed-git/sections/contributing.asc | 4 ++-- book/05-distributed-git/sections/distributed-workflows.asc | 2 +- book/05-distributed-git/sections/maintaining.asc | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/book/05-distributed-git/sections/contributing.asc b/book/05-distributed-git/sections/contributing.asc index 3e1130fb..dfcdde9d 100644 --- a/book/05-distributed-git/sections/contributing.asc +++ b/book/05-distributed-git/sections/contributing.asc @@ -474,12 +474,12 @@ Date: Fri May 29 16:01:27 2009 -0700 ////////////////////////// The `issue54..origin/master` syntax is a log filter that asks Git to only show the list of commits that are on the latter branch (in this case `origin/master`) that are not on the first branch (in this case `issue54`). We'll go over this syntax in detail in <<_commit_ranges>>. ////////////////////////// -`issue54..origin/master` という記法はログのフィルター用の書式です。このように書くと、後者のブランチ(この例では `origin/master` )には含まれるが前者のブランチ(この例では `issue54` )には含まれないコミットのログだけを表示します。この記法の詳細は <<_commit_ranges>> で説明します。 +`issue54..origin/master` はログのフィルター記法です。このように書くと、後者のブランチ(この例では `origin/master` )には含まれるが前者のブランチ(この例では `issue54` )には含まれないコミットのログだけを表示します。この記法の詳細は <<_commit_ranges>> で説明します。 ////////////////////////// For now, we can see from the output that there is a single commit that John has made that Jessica has not merged in. If she merges `origin/master`, that is the single commit that will modify her local work. ////////////////////////// -この例では、コマンド出力にあるひとつのコミットが、John が作成して Jessica がまだマージしていないものであることがわかります。仮にここで Jessica が `origin/master` をマージするとしましょう。その場合、Jessica の手元のファイルを変更するのは John が作成したコミットひとつだけ、という状態になります。 +この例では、John が作成して Jessica がまだマージしていないコミットがひとつあることがコマンド出力から読み取れます。仮にここで Jessica が `origin/master` をマージするとしましょう。その場合、Jessica の手元のファイルを変更するのは John が作成したコミットひとつだけ、という状態になります。 ////////////////////////// Now, Jessica can merge her topic work into her master branch, merge John's work (`origin/master`) into her `master` branch, and then push back to the server again. diff --git a/book/05-distributed-git/sections/distributed-workflows.asc b/book/05-distributed-git/sections/distributed-workflows.asc index c9324141..2247ba84 100644 --- a/book/05-distributed-git/sections/distributed-workflows.asc +++ b/book/05-distributed-git/sections/distributed-workflows.asc @@ -68,7 +68,7 @@ This workflow is attractive to a lot of people because it's a paradigm that many ////////////////////////// This is also not limited to small teams. With Git's branching model, it's possible for hundreds of developers to successfully work on a single project through dozens of branches simultaneously. ////////////////////////// -また、この例は小規模なチームに限った話ではありません。Git のブランチモデルを用いてひとつのプロジェクト上にたくさんのブランチを作れば、何百人もの開発者が同時並行で作業を進めることすらできるのです。 +また、この例は小規模なチームに限った話ではありません。Git のブランチモデルを用いてひとつのプロジェクト上にたくさんのブランチを作れば、何百人もの開発者が同時並行で作業を進めることだってできるのです。 [[_integration_manager]] ////////////////////////// diff --git a/book/05-distributed-git/sections/maintaining.asc b/book/05-distributed-git/sections/maintaining.asc index b67e8dda..4b898da2 100644 --- a/book/05-distributed-git/sections/maintaining.asc +++ b/book/05-distributed-git/sections/maintaining.asc @@ -700,7 +700,7 @@ If you're doing lots of merging and rebasing, or you're maintaining a long-lived Rerere stands for ``reuse recorded resolution'' – it's a way of shortcutting manual conflict resolution. When rerere is enabled, Git will keep a set of pre- and post-images from successful merges, and if it notices that there's a conflict that looks exactly like one you've already fixed, it'll just use the fix from last time, without bothering you with it. ////////////////////////// -Rerere は ``reuse recorded resolution'' の略で、コンフリクトを手動で解消するための手っ取り早い方法です。 +Rerere は ``reuse recorded resolution'' の略で、コンフリクトを手っ取り早く手動で解消するための方法です。 ////////////////////////// This feature comes in two parts: a configuration setting and a command. @@ -725,7 +725,7 @@ When it's invoked alone, Git checks its database of resolutions and tries to fin There are also subcommands to see what will be recorded, to erase specific resolution from the cache, and to clear the entire cache. We will cover rerere in more detail in <<_rerere>>. ////////////////////////// 必要に応じてキャッシュを操作することもできます。`git rerere` コマンドを使うのです。 -このコマンドをオプションなしで実行するとキャッシュが検索され、コンフリクトの内容に合致するものがある場合は Git がそれを用いてコンフリクトの解消を試みます(ただし、`rerere.enabled` が `true` に設定されている場合、一連の処理は自動で行われます)。 +このコマンドをオプションなしで実行するとキャッシュが検索され、コンフリクトの内容に合致するものがある場合はそれを用いてコンフリクトの解消が試みられます(ただし、`rerere.enabled` が `true` に設定されている場合、一連の処理は自動で行われます)。 また、サブコマンドも複数用意されています。それらを使うと、キャッシュされようとしている内容の確認、キャッシュされた内容を指定して削除、キャッシュをすべて削除、などができるようになります。rerere については <<_rerere>> で詳しく説明します。 [[_tagging_releases]] From fdd1965e587e33d587f001329100cf632e5b9b77 Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Tue, 25 Nov 2014 20:28:31 +0900 Subject: [PATCH 5/6] Complete translation --- .../diff-1-distributed-git.htm | 3775 -------------- .../sections/diff-contributing.htm | 4503 ----------------- .../sections/diff-distributed-workflows.htm | 3843 -------------- .../sections/diff-maintaining.htm | 4375 ---------------- status.json | 8 +- 5 files changed, 4 insertions(+), 16500 deletions(-) delete mode 100644 book/05-distributed-git/diff-1-distributed-git.htm delete mode 100644 book/05-distributed-git/sections/diff-contributing.htm delete mode 100644 book/05-distributed-git/sections/diff-distributed-workflows.htm delete mode 100644 book/05-distributed-git/sections/diff-maintaining.htm diff --git a/book/05-distributed-git/diff-1-distributed-git.htm b/book/05-distributed-git/diff-1-distributed-git.htm deleted file mode 100644 index 326bbfe5..00000000 --- a/book/05-distributed-git/diff-1-distributed-git.htm +++ /dev/null @@ -1,3775 +0,0 @@ - - - - -WinMerge File Compare Report - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\1-distributed-git.asc
. 1[[_distributed_git]]
1# Distributed Git # 2== Distributed Git 
2 3 
. 4(((distributed git)))
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you.5Now that you have a remote Git repository set up as a point for all the developers to share their code, and you're familiar with basic Git commands in a local workflow, you'll look at how to utilize some of the distributed workflows that Git affords you.
4 6 
.5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing.7In this chapter, you'll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you'll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing.
6 8 
.7## Distributed Workflows ## 9include::sections/distributed-workflows.asc[] 
8 10 
.9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub — that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. 11include::sections/contributing.asc[] 
10 12 
.11### Centralized Workflow ### 13include::sections/maintaining.asc[] 
12  
13In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). 
14  
15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
17  
18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. 
19  
20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with. 
22  
23### Integration-Manager Workflow ### 
24  
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2): 
26  
271. The project maintainer pushes to their public repository. 
282. A contributor clones that repository and makes changes. 
293. The contributor pushes to their own public copy. 
304. The contributor sends the maintainer an e-mail asking them to pull changes. 
315. The maintainer adds the contributor’s repo as a remote and merges locally. 
326. The maintainer pushes merged changes to the main repository. 
33  
34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
36  
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. 
38  
39### Dictator and Lieutenants Workflow ### 
40  
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3): 
42  
431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator. 
442. Lieutenants merge the developers’ topic branches into their master branch. 
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 
464. The dictator pushes their master to the reference repository so the other developers can rebase on it. 
47  
48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
50  
51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. 
52  
53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 
54  
55## Contributing to a Project ## 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58  
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method. 
60  
61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid? 
62  
63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 
64  
65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? 
66  
67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. 
68  
69### Commit Guidelines ### 
70  
71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches — you can read it in the Git source code in the `Documentation/SubmittingPatches` file. 
72  
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this — before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 
74  
75    $ git diff --check 
76    lib/simplegit.rb:5: trailing whitespace. 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82  
83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers. 
84  
85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible — don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files — use these tools to help craft a clean and understandable history. 
86  
87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 
88Here is a template originally written by Tim Pope at tpope.net: 
89  
90    Short (50 chars or less) summary of changes 
91  
92    More detailed explanatory text, if necessary.  Wrap it to about 72 
93    characters or so.  In some contexts, the first line is treated as the 
94    subject of an email and the rest of the text as the body.  The blank 
95    line separating the summary from the body is critical (unless you omit 
96    the body entirely); tools like rebase can get confused if you run the 
97    two together. 
98  
99    Further paragraphs come after blank lines. 
100  
101     - Bullet points are okay, too 
102  
103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 
104       single space, with blank lines in between, but conventions vary here 
105  
106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages — I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like. 
107  
108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do. 
109  
110### Private Small Team ### 
111  
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source — not read-accessible to the outside world. You and the other developers all have push access to the repository. 
113  
114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.) 
116  
117    # John's Machine 
118    $ git clone john@githost:simplegit.git 
119    Initialized empty Git repository in /home/john/simplegit/.git/ 
120    ... 
121    $ cd simplegit/ 
122    $ vim lib/simplegit.rb 
123    $ git commit -am 'removed invalid default value' 
124    [master 738ee87] removed invalid default value 
125     1 files changed, 1 insertions(+), 1 deletions(-) 
126  
127The second developer, Jessica, does the same thing — clones the repository and commits a change: 
128  
129    # Jessica's Machine 
130    $ git clone jessica@githost:simplegit.git 
131    Initialized empty Git repository in /home/jessica/simplegit/.git/ 
132    ... 
133    $ cd simplegit/ 
134    $ vim TODO 
135    $ git commit -am 'add reset task' 
136    [master fbff5bc] add reset task 
137     1 files changed, 1 insertions(+), 0 deletions(-) 
138  
139Now, Jessica pushes her work up to the server: 
140  
141    # Jessica's Machine 
142    $ git push origin master 
143    ... 
144    To jessica@githost:simplegit.git 
145       1edee6b..fbff5bc  master -> master 
146  
147John tries to push his change up, too: 
148  
149    # John's Machine 
150    $ git push origin master 
151    To john@githost:simplegit.git 
152     ! [rejected]        master -> master (non-fast forward) 
153    error: failed to push some refs to 'john@githost:simplegit.git' 
154  
155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push: 
156  
157    $ git fetch origin 
158    ... 
159    From john@githost:simplegit 
160     + 049d078...fbff5bc master     -> origin/master 
161  
162At this point, John’s local repository looks something like Figure 5-4. 
163  
164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
166  
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: 
168  
169    $ git merge origin/master 
170    Merge made by recursive. 
171     TODO |    1 + 
172     1 files changed, 1 insertions(+), 0 deletions(-) 
173  
174The merge goes smoothly — John’s commit history now looks like Figure 5-5. 
175  
176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
178  
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: 
180  
181    $ git push origin master 
182    ... 
183    To john@githost:simplegit.git 
184       fbff5bc..72bbc59  master -> master 
185  
186Finally, John’s commit history looks like Figure 5-6. 
187  
188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
190  
191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 
192  
193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
195  
196Jessica wants to sync up with John, so she fetches: 
197  
198    # Jessica's Machine 
199    $ git fetch origin 
200    ... 
201    From jessica@githost:simplegit 
202       fbff5bc..72bbc59  master     -> origin/master 
203  
204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 
205  
206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
208  
209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: 
210  
211    $ git log --no-merges origin/master ^issue54 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016 
213    Author: John Smith <jsmith@example.com> 
214    Date:   Fri May 29 16:01:27 2009 -0700 
215  
216        removed invalid default value 
217  
218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work: 
219  
220    $ git checkout master 
221    Switched to branch "master" 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. 
223  
224She can merge either `origin/master` or `issue54` first — they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: 
225  
226    $ git merge issue54 
227    Updating fbff5bc..4af4298 
228    Fast forward 
229     README           |    1 + 
230     lib/simplegit.rb |    6 +++++- 
231     2 files changed, 6 insertions(+), 1 deletions(-) 
232  
233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`): 
234  
235    $ git merge origin/master 
236    Auto-merging lib/simplegit.rb 
237    Merge made by recursive. 
238     lib/simplegit.rb |    2 +- 
239     1 files changed, 1 insertions(+), 1 deletions(-) 
240  
241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 
242  
243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
245  
246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): 
247  
248    $ git push origin master 
249    ... 
250    To jessica@githost:simplegit.git 
251       72bbc59..8059c15  master -> master 
252  
253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. 
254  
255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
257  
258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 
259  
260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
262  
263### Private Managed Team ### 
264  
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. 
266  
267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. 
268  
269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: 
270  
271    # Jessica's Machine 
272    $ git checkout -b featureA 
273    Switched to a new branch "featureA" 
274    $ vim lib/simplegit.rb 
275    $ git commit -am 'add limit to log function' 
276    [featureA 3300904] add limit to log function 
277     1 files changed, 1 insertions(+), 1 deletions(-) 
278  
279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch — only the integrators do — so she has to push to another branch in order to collaborate with John: 
280  
281    $ git push origin featureA 
282    ... 
283    To jessica@githost:simplegit.git 
284     * [new branch]      featureA -> featureA 
285  
286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch: 
287  
288    # Jessica's Machine 
289    $ git fetch origin 
290    $ git checkout -b featureB origin/master 
291    Switched to a new branch "featureB" 
292  
293Now, Jessica makes a couple of commits on the `featureB` branch: 
294  
295    $ vim lib/simplegit.rb 
296    $ git commit -am 'made the ls-tree function recursive' 
297    [featureB e5b0fdc] made the ls-tree function recursive 
298     1 files changed, 1 insertions(+), 1 deletions(-) 
299    $ vim lib/simplegit.rb 
300    $ git commit -am 'add ls-files' 
301    [featureB 8512791] add ls-files 
302     1 files changed, 5 insertions(+), 0 deletions(-) 
303  
304Jessica’s repository looks like Figure 5-12. 
305  
306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
308  
309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: 
310  
311    $ git fetch origin 
312    ... 
313    From jessica@githost:simplegit 
314     * [new branch]      featureBee -> origin/featureBee 
315  
316Jessica can now merge this into the work she did with `git merge`: 
317  
318    $ git merge origin/featureBee 
319    Auto-merging lib/simplegit.rb 
320    Merge made by recursive. 
321     lib/simplegit.rb |    4 ++++ 
322     1 files changed, 4 insertions(+), 0 deletions(-) 
323  
324There is a bit of a problem — she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: 
325  
326    $ git push origin featureB:featureBee 
327    ... 
328    To jessica@githost:simplegit.git 
329       fba9af8..cd685d1  featureB -> featureBee 
330  
331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 
332  
333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: 
334  
335    $ git fetch origin 
336    ... 
337    From jessica@githost:simplegit 
338       3300904..aad881d  featureA   -> origin/featureA 
339  
340Then, she can see what has been changed with `git log`: 
341  
342    $ git log origin/featureA ^featureA 
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 
344    Author: John Smith <jsmith@example.com> 
345    Date:   Fri May 29 19:57:33 2009 -0700 
346  
347        changed log output to 30 from 25 
348  
349Finally, she merges John’s work into her own `featureA` branch: 
350  
351    $ git checkout featureA 
352    Switched to branch "featureA" 
353    $ git merge origin/featureA 
354    Updating 3300904..aad881d 
355    Fast forward 
356     lib/simplegit.rb |   10 +++++++++- 
357    1 files changed, 9 insertions(+), 1 deletions(-) 
358  
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server: 
360  
361    $ git commit -am 'small tweak' 
362    [featureA 774b3ed] small tweak 
363     1 files changed, 1 insertions(+), 1 deletions(-) 
364    $ git push origin featureA 
365    ... 
366    To jessica@githost:simplegit.git 
367       3300904..774b3ed  featureA -> featureA 
368  
369Jessica’s commit history now looks something like Figure 5-13. 
370  
371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
373  
374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 
375  
376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
378  
379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 
380  
381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
383  
384### Public Small Project ### 
385  
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. 
387  
388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this: 
389  
390    $ git clone (url) 
391    $ cd project 
392    $ git checkout -b featureA 
393    $ (work) 
394    $ git commit 
395    $ (work) 
396    $ git commit 
397  
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review — see Chapter 6 for more information about interactive rebasing. 
399  
400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: 
401  
402    $ git remote add myfork (url) 
403  
404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow: 
405  
406    $ git push myfork featureA 
407  
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website — GitHub has a "pull request" button that automatically messages the maintainer — or run the `git request-pull` command and e-mail the output to the project maintainer manually. 
409  
410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this: 
411  
412    $ git request-pull origin/master myfork 
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: 
414      John Smith (1): 
415            added a new function 
416  
417    are available in the git repository at: 
418  
419      git://githost/simplegit.git featureA 
420  
421    Jessica Smith (2): 
422          add limit to log function 
423          change log output to 30 from 25 
424  
425     lib/simplegit.rb |   10 +++++++++- 
426     1 files changed, 9 insertions(+), 1 deletions(-) 
427  
428The output can be sent to the maintainer—it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. 
429  
430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up — start over from the main repository’s `master` branch: 
431  
432    $ git checkout -b featureB origin/master 
433    $ (work) 
434    $ git commit 
435    $ git push myfork featureB 
436    $ (email maintainer) 
437    $ git fetch origin 
438  
439Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 
440  
441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
443  
444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: 
445  
446    $ git checkout featureA 
447    $ git rebase origin/master 
448    $ git push -f myfork featureA 
449  
450This rewrites your history to now look like Figure 5-17. 
451  
452Insert 18333fig0517.png 
453Figure 5-17. Commit history after featureA work. 
454  
455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). 
456  
457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: 
458  
459    $ git checkout -b featureBv2 origin/master 
460    $ git merge --no-commit --squash featureB 
461    $ (change implementation) 
462    $ git commit 
463    $ git push myfork featureBv2 
464  
465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. 
466  
467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). 
468  
469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
471  
472### Public Large Project ### 
473  
474Many larger projects have established procedures for accepting patches — you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now. 
475  
476The workflow is similar to the previous use case — you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: 
477  
478    $ git checkout -b topicA 
479    $ (work) 
480    $ git commit 
481    $ (work) 
482    $ git commit 
483  
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list — it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 
485  
486    $ git format-patch -M origin/master 
487    0001-add-limit-to-log-function.patch 
488    0002-changed-log-output-to-30-from-25.patch 
489  
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: 
491  
492    $ cat 0001-add-limit-to-log-function.patch 
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
494    From: Jessica Smith <jessica@example.com> 
495    Date: Sun, 6 Apr 2008 10:17:23 -0700 
496    Subject: [PATCH 1/2] add limit to log function 
497  
498    Limit log functionality to the first 20 
499  
500    --- 
501     lib/simplegit.rb |    2 +- 
502     1 files changed, 1 insertions(+), 1 deletions(-) 
503  
504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
505    index 76f47bc..f9815f1 100644 
506    --- a/lib/simplegit.rb 
507    +++ b/lib/simplegit.rb 
508    @@ -14,7 +14,7 @@ class SimpleGit 
509       end 
510  
511       def log(treeish = 'master') 
512    -    command("git log #{treeish}") 
513    +    command("git log -n 20 #{treeish}") 
514       end 
515  
516       def ls_tree(treeish = 'master') 
517    -- 
518    1.6.2.rc1.20.g8c5b.dirty 
519  
520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. 
521  
522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. 
523  
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this: 
525  
526    [imap] 
527      folder = "[Gmail]/Drafts" 
528      host = imaps://imap.gmail.com 
529      user = user@gmail.com 
530      pass = p4ssw0rd 
531      port = 993 
532      sslverify = false 
533  
534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`. 
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: 
536  
537    $ cat *.patch |git imap-send 
538    Resolving imap.gmail.com... ok 
539    Connecting to [74.125.142.109]:993... ok 
540    Logging in... 
541    sending 2 messages 
542    100% (2/2) done 
543  
544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. 
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580  
581### Summary ### 
582  
583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager. 
584  
585## Maintaining a Project ## 
586  
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. 
588  
589### Working in Topic Branches ### 
590  
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. 
592As you’ll remember, you can create the branch based off your master branch like this: 
593  
594    $ git branch sc/ruby_client master 
595  
596Or, if you want to also switch to it immediately, you can use the `checkout -b` command: 
597  
598    $ git checkout -b sc/ruby_client master 
599  
600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. 
601  
602### Applying Patches from E-mail ### 
603  
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. 
605  
606#### Applying a Patch with apply #### 
607  
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: 
609  
610    $ git apply /tmp/patch-ruby-client.patch 
611  
612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you — after running it, you must stage and commit the changes introduced manually. 
613  
614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: 
615  
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch 
617    error: patch failed: ticgit.gemspec:1 
618    error: ticgit.gemspec: patch does not apply 
619  
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. 
621  
622#### Applying a Patch with am #### 
623  
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. 
625  
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: 
627  
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
629    From: Jessica Smith <jessica@example.com> 
630    Date: Sun, 6 Apr 2008 10:17:23 -0700 
631    Subject: [PATCH 1/2] add limit to log function 
632  
633    Limit log functionality to the first 20 
634  
635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time. 
636  
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: 
638  
639    $ git am 0001-limit-log-function.patch 
640    Applying: add limit to log function 
641  
642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: 
643  
644    $ git log --pretty=fuller -1 
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
646    Author:     Jessica Smith <jessica@example.com> 
647    AuthorDate: Sun Apr 6 10:17:23 2008 -0700 
648    Commit:     Scott Chacon <schacon@gmail.com> 
649    CommitDate: Thu Apr 9 09:19:06 2009 -0700 
650  
651       add limit to log function 
652  
653       Limit log functionality to the first 20 
654  
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. 
656  
657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: 
658  
659    $ git am 0001-seeing-if-this-helps-the-gem.patch 
660    Applying: seeing if this helps the gem 
661    error: patch failed: ticgit.gemspec:1 
662    error: ticgit.gemspec: patch does not apply 
663    Patch failed at 0001. 
664    When you have resolved this problem run "git am --resolved". 
665    If you would prefer to skip this patch, instead run "git am --skip". 
666    To restore the original branch and stop patching run "git am --abort". 
667  
668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: 
669  
670    $ (fix the file) 
671    $ git add ticgit.gemspec 
672    $ git am --resolved 
673    Applying: seeing if this helps the gem 
674  
675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: 
676  
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch 
678    Applying: seeing if this helps the gem 
679    error: patch failed: ticgit.gemspec:1 
680    error: ticgit.gemspec: patch does not apply 
681    Using index info to reconstruct a base tree... 
682    Falling back to patching base and 3-way merge... 
683    No changes -- Patch already applied. 
684  
685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict. 
686  
687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: 
688  
689    $ git am -3 -i mbox 
690    Commit Body is: 
691    -------------------------- 
692    seeing if this helps the gem 
693    -------------------------- 
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all 
695  
696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. 
697  
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. 
699  
700### Checking Out Remote Branches ### 
701  
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. 
703  
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: 
705  
706    $ git remote add jessica git://github.com/jessica/myproject.git 
707    $ git fetch jessica 
708    $ git checkout -b rubyclient jessica/ruby-client 
709  
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. 
711  
712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier — it depends largely on how you develop and how your contributors develop. 
713  
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. 
715  
716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference: 
717  
718    $ git pull git://github.com/onetimeguy/project.git 
719    From git://github.com/onetimeguy/project 
720     * branch            HEAD       -> FETCH_HEAD 
721    Merge made by recursive. 
722  
723### Determining What Is Introduced ### 
724  
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch. 
726  
727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: 
728  
729    $ git log contrib --not master 
730    commit 5b6235bd297351589efc4d73316f0a68d484f118 
731    Author: Scott Chacon <schacon@gmail.com> 
732    Date:   Fri Oct 24 09:53:59 2008 -0700 
733  
734        seeing if this helps the gem 
735  
736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 
737    Author: Scott Chacon <schacon@gmail.com> 
738    Date:   Mon Oct 22 19:38:36 2008 -0700 
739  
740        updated the gemspec to hopefully work better 
741  
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. 
743  
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: 
745  
746    $ git diff master 
747  
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. 
749  
750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch. 
751  
752What you really want to see are the changes added to the topic branch — the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. 
753  
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: 
755  
756    $ git merge-base contrib master 
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 
758    $ git diff 36c7db 
759  
760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: 
761  
762    $ git diff master...contrib 
763  
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. 
765  
766### Integrating Contributed Work ### 
767  
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them. 
769  
770#### Merging Workflows #### 
771  
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. 
773  
774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
776  
777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
779  
780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. 
781  
782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). 
783  
784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
786  
787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
789  
790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
792  
793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. 
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. 
795  
796#### Large-Merging Workflows #### 
797  
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. 
799  
800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
802  
803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 
804  
805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
807  
808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 
809  
810#### Rebasing and Cherry Picking Workflows #### 
811  
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history. 
813  
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 
815  
816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
818  
819If you want to pull commit `e43a6` into your master branch, you can run 
820  
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf 
822    Finished one cherry-pick. 
823    [master]: created a0a41a9: "More friendly message when locking the index fails." 
824     3 files changed, 17 insertions(+), 3 deletions(-) 
825  
826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 
827  
828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
830  
831Now you can remove your topic branch and drop the commits you didn’t want to pull in. 
832  
833### Tagging Your Releases ### 
834  
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this: 
836  
837    $ git tag -s v1.5 -m 'my signed 1.5 tag' 
838    You need a passphrase to unlock the secret key for 
839    user: "Scott Chacon <schacon@gmail.com>" 
840    1024-bit DSA key, ID F721C45A, created 2009-02-09 
841  
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: 
843  
844    $ gpg --list-keys 
845    /Users/schacon/.gnupg/pubring.gpg 
846    --------------------------------- 
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09] 
848    uid                  Scott Chacon <schacon@gmail.com> 
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09] 
850  
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: 
852  
853    $ gpg -a --export F721C45A | git hash-object -w --stdin 
854    659ef797d181633c87ec71ac3f9ba29fe5775b92 
855  
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: 
857  
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 
859  
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: 
861  
862    $ git show maintainer-pgp-pub | gpg --import 
863  
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification. 
865  
866### Generating a Build Number ### 
867  
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing: 
869  
870    $ git describe master 
871    v1.6.2-rc1-20-g8c5b85c 
872  
873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name. 
874  
875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. 
876  
877### Preparing a Release ### 
878  
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`: 
880  
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz 
882    $ ls *.tar.gz 
883    v1.6.2-rc1-20-g8c5b85c.tar.gz 
884  
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: 
886  
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip 
888  
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. 
890  
891### The Shortlog ### 
892  
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: 
894  
895    $ git shortlog --no-merges master --not v1.0.1 
896    Chris Wanstrath (8): 
897          Add support for annotated tags to Grit::Tag 
898          Add packed-refs annotated tag support. 
899          Add Grit::Commit#to_patch 
900          Update version and History.txt 
901          Remove stray `puts` 
902          Make ls_tree ignore nils 
903  
904    Tom Preston-Werner (4): 
905          fix dates in history 
906          dynamic version method 
907          Version bump to 1.0.2 
908          Regenerated gemspec for version 1.0.2 
909  
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. 
911 14 
.912## Summary ## 15=== Summary 
913 16 
.914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master.17You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users' contributions. Congratulations on being an effective Git developer! In the next chapter, you'll learn about how to use the largest and most popular Git hosting service, GitHub.
915 18 
-
- diff --git a/book/05-distributed-git/sections/diff-contributing.htm b/book/05-distributed-git/sections/diff-contributing.htm deleted file mode 100644 index 127282c2..00000000 --- a/book/05-distributed-git/sections/diff-contributing.htm +++ /dev/null @@ -1,4503 +0,0 @@ - - - - -WinMerge File Compare Report - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\sections\contributing.asc
.1# Distributed Git # 1[[_contributing_project]] 
2  
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you. 
4  
5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. 
6  
7## Distributed Workflows ## 
8  
9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub — that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. 
10  
11### Centralized Workflow ### 
12  
13In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). 
14  
15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
17  
18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. 
19  
20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with. 
22  
23### Integration-Manager Workflow ### 
24  
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2): 
26  
271. The project maintainer pushes to their public repository. 
282. A contributor clones that repository and makes changes. 
293. The contributor pushes to their own public copy. 
304. The contributor sends the maintainer an e-mail asking them to pull changes. 
315. The maintainer adds the contributor’s repo as a remote and merges locally. 
326. The maintainer pushes merged changes to the main repository. 
33  
34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
36  
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. 
38  
39### Dictator and Lieutenants Workflow ### 
40  
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3): 
42  
431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator. 
442. Lieutenants merge the developers’ topic branches into their master branch. 
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 
464. The dictator pushes their master to the reference repository so the other developers can rebase on it. 
47  
48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
50  
51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. 
52  
53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 
54  
55## Contributing to a Project ## 2=== Contributing to a Project 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58 3 
. 4(((contributing)))
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method.5The main difficulty with describing how to contribute to a project is that there are a huge number of variations on how it's done. Because Git is very flexible, people can and do work together in many ways, and it's problematic to describe how you should contribute every project is a bit different. Some of the variables involved are active contributor count, chosen workflow, your commit access, and possibly the external contribution method.
60 6 
.61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid?7The first variable is active contributor count how many users are actively contributing code to this project, and how often? In many instances, you'll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For larger companies or projects, the number of developers could be in the thousands, with hundreds or thousands of commits coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your commits valid?
62 8 
.63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 9The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first?  
64 10 
.65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute?11The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don't. If you don't have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute?
66 12 
.67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples.13All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. We'll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples.
68 14 
. 15[[_commit_guidelines]]
69### Commit Guidelines ### 16==== Commit Guidelines 
70 17 
.71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches you can read it in the Git source code in the `Documentation/SubmittingPatches` file.18Before we start looking at the specific use cases, here's a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches you can read it in the Git source code in the `Documentation/SubmittingPatches` file.
72 19 
. 20(((git commands, diff, check)))
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 21First, you don't want to submit any whitespace errors. Git provides an easy way to check for this before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. 
74 22 
.75    $ git diff --check 23.Output of `git diff --check`. 
76    lib/simplegit.rb:5: trailing whitespace. 24image::images/git-diff-check.png[Output of `git diff --check`.] 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82 25 
.83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers.26If you run that command before committing, you can tell if you're about to commit whitespace issues that may annoy other developers.
84 27 
.85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files use these tools to help craft a clean and understandable history.28Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible don't code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don't commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in <<_interactive_staging>>). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. <<_rewriting_history>> describes a number of useful Git tricks for rewriting history and interactively staging files use these tools to help craft a clean and understandable history before sending the work to someone else.
86 29 
.87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 30The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that's no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior this is a good guideline to follow. It's also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of ``I added tests for'' or ``Adding tests for,'' use ``Add tests for.'' 
88Here is a template originally written by Tim Pope at tpope.net:31Here is a template originally written by Tim Pope:
89 32 
. 33[source,text]
 34-----
90    Short (50 chars or less) summary of changes35Short (50 chars or less) summary of changes
91 36 
.92    More detailed explanatory text, if necessary.  Wrap it to about 72 37More detailed explanatory text, if necessary.  Wrap it to 
93    characters or so.  In some contexts, the first line is treated as the 38about 72 characters or so.  In some contexts, the first 
 39line is treated as the subject of an email and the rest of
94    subject of an email and the rest of the text as the body.  The blank 40the text as the body.  The blank line separating the 
95    line separating the summary from the body is critical (unless you omit 41summary from the body is critical (unless you omit the body 
96    the body entirely); tools like rebase can get confused if you run the 42entirely); tools like rebase can get confused if you run 
97    two together.43the two together.
98 44 
.99    Further paragraphs come after blank lines.45Further paragraphs come after blank lines.
100 46 
.101     - Bullet points are okay, too47  - Bullet points are okay, too
102 48 
.103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 49  - Typically a hyphen or asterisk is used for the bullet, 
104       single space, with blank lines in between, but conventions vary here 50    preceded by a single space, with blank lines in 
 51    between, but conventions vary here
 52-----
105 53 
.106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like.54If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages try running `git log --no-merges` there to see what a nicely formatted project-commit history looks like.
107 55 
.108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do.56In the following examples, and throughout most of this book, for the sake of brevity this book doesn't have nicely-formatted messages like this; instead, we use the `-m` option to `git commit`. Do as we say, not as we do.
109 57 
. 58[[_private_team]]
110### Private Small Team ### 59==== Private Small Team 
111 60 
. 61(((contributing, private small team)))
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source not read-accessible to the outside world. You and the other developers all have push access to the repository.62The simplest setup you're likely to encounter is a private project with one or two other developers. ``Private,'' in this context, means closed-source not accessible to the outside world. You and the other developers all have push access to the repository.
113 63 
.114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 64In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time.  
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.)65Let's see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (The protocol messages have been replaced with `...` in these examples to shorten them somewhat.)
116 66 
. 67[source,console]
 68-----
117    # John's Machine69# John's Machine
118    $ git clone john@githost:simplegit.git70$ git clone john@githost:simplegit.git
119    Initialized empty Git repository in /home/john/simplegit/.git/71Initialized empty Git repository in /home/john/simplegit/.git/
120    ...72...
121    $ cd simplegit/73$ cd simplegit/
122    $ vim lib/simplegit.rb74$ vim lib/simplegit.rb
123    $ git commit -am 'removed invalid default value'75$ git commit -am 'removed invalid default value'
124    [master 738ee87] removed invalid default value76[master 738ee87] removed invalid default value
125     1 files changed, 1 insertions(+), 1 deletions(-)77 1 files changed, 1 insertions(+), 1 deletions(-)
 78-----
126 79 
.127The second developer, Jessica, does the same thing clones the repository and commits a change:80The second developer, Jessica, does the same thing clones the repository and commits a change:
128 81 
. 82[source,console]
 83-----
129    # Jessica's Machine84# Jessica's Machine
130    $ git clone jessica@githost:simplegit.git85$ git clone jessica@githost:simplegit.git
131    Initialized empty Git repository in /home/jessica/simplegit/.git/86Initialized empty Git repository in /home/jessica/simplegit/.git/
132    ...87...
133    $ cd simplegit/88$ cd simplegit/
134    $ vim TODO89$ vim TODO
135    $ git commit -am 'add reset task'90$ git commit -am 'add reset task'
136    [master fbff5bc] add reset task91[master fbff5bc] add reset task
137     1 files changed, 1 insertions(+), 0 deletions(-)92 1 files changed, 1 insertions(+), 0 deletions(-)
 93-----
138 94 
139Now, Jessica pushes her work up to the server:95Now, Jessica pushes her work up to the server:
140 96 
. 97[source,console]
 98-----
141    # Jessica's Machine99# Jessica's Machine
142    $ git push origin master100$ git push origin master
143    ...101...
144    To jessica@githost:simplegit.git102To jessica@githost:simplegit.git
145       1edee6b..fbff5bc  master -> master103   1edee6b..fbff5bc  master -> master
 104-----
146 105 
147John tries to push his change up, too:106John tries to push his change up, too:
148 107 
. 108[source,console]
 109-----
149    # John's Machine110# John's Machine
150    $ git push origin master111$ git push origin master
151    To john@githost:simplegit.git112To john@githost:simplegit.git
152     ! [rejected]        master -> master (non-fast forward)113 ! [rejected]        master -> master (non-fast forward)
153    error: failed to push some refs to 'john@githost:simplegit.git'114error: failed to push some refs to 'john@githost:simplegit.git'
 115-----
154 116 
.155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push:117John isn't allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you're used to Subversion, because you'll notice that the two developers didn't edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica's changes and merge them in before he will be allowed to push:
156 118 
. 119[source,console]
 120-----
157    $ git fetch origin121$ git fetch origin
158    ...122...
159    From john@githost:simplegit123From john@githost:simplegit
160     + 049d078...fbff5bc master     -> origin/master124 + 049d078...fbff5bc master     -> origin/master
 125-----
161 126 
.162At this point, John’s local repository looks something like Figure 5-4. 127At this point, John's local repository looks something like this: 
163 128 
.164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
 129.John's divergent history.
 130image::images/small-team-1.png[John's divergent history.]
166 131 
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push:132John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push:
168 133 
. 134[source,console]
 135-----
169    $ git merge origin/master136$ git merge origin/master
170    Merge made by recursive.137Merge made by recursive.
171     TODO |    1 +138 TODO |    1 +
172     1 files changed, 1 insertions(+), 0 deletions(-)139 1 files changed, 1 insertions(+), 0 deletions(-)
 140-----
173 141 
.174The merge goes smoothly John’s commit history now looks like Figure 5-5. 142The merge goes smoothly John's commit history now looks like this: 
175 143 
.176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
 144.John's repository after merging `origin/master`.
 145image::images/small-team-2.png[John's repository after merging `origin/master`.]
178 146 
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server:147Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server:
180 148 
. 149[source,console]
 150-----
181    $ git push origin master151$ git push origin master
182    ...152...
183    To john@githost:simplegit.git153To john@githost:simplegit.git
184       fbff5bc..72bbc59  master -> master154   fbff5bc..72bbc59  master -> master
 155-----
185 156 
.186Finally, John’s commit history looks like Figure 5-6. 157Finally, John's commit history looks like this: 
187 158 
.188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
 159.John's history after pushing to the `origin` server.
 160image::images/small-team-3.png[John's history after pushing to the `origin` server.]
190 161 
.191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 162In the meantime, Jessica has been working on a topic branch. She's created a topic branch called `issue54` and done three commits on that branch. She hasn't fetched John's changes yet, so her commit history looks like this: 
192 163 
.193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
 164.Jessica's topic branch.
 165image::images/small-team-4.png[Jessica's topic branch.]
195 166 
196Jessica wants to sync up with John, so she fetches:167Jessica wants to sync up with John, so she fetches:
197 168 
. 169[source,console]
 170-----
198    # Jessica's Machine171# Jessica's Machine
199    $ git fetch origin172$ git fetch origin
200    ...173...
201    From jessica@githost:simplegit174From jessica@githost:simplegit
202       fbff5bc..72bbc59  master     -> origin/master175   fbff5bc..72bbc59  master     -> origin/master
 176-----
203 177 
.204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 178That pulls down the work John has pushed up in the meantime. Jessica's history now looks like this: 
205 179 
.206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
 180.Jessica's history after fetching John's changes.
 181image::images/small-team-5.png[Jessica's history after fetching John's changes.]
208 182 
.209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out:183Jessica thinks her topic branch is ready, but she wants to know what she has to merge into her work so that she can push. She runs `git log` to find out:
210 184 
. 185[source,console]
 186-----
211    $ git log --no-merges origin/master ^issue54 187$ git log --no-merges issue54..origin/master 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016188commit 738ee872852dfaa9d6634e0dea7a324040193016
213    Author: John Smith <jsmith@example.com>189Author: John Smith <jsmith@example.com>
214    Date:   Fri May 29 16:01:27 2009 -0700190Date:   Fri May 29 16:01:27 2009 -0700
215 191 
.216        removed invalid default value192   removed invalid default value
 193-----
 194 
 195The `issue54..origin/master` syntax is a log filter that asks Git to only show the list of commits that are on the latter branch (in this case `origin/master`) that are not on the first branch (in this case `issue54`). We'll go over this syntax in detail in <<_commit_ranges>>.
 196 
 197For now, we can see from the output that there is a single commit that John has made that Jessica has not merged in. If she merges `origin/master`, that is the single commit that will modify her local work.
217 198 
.218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work:199Now, Jessica can merge her topic work into her master branch, merge John's work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her master branch to integrate all this work:
219 200 
. 201[source,console]
 202-----
220    $ git checkout master203$ git checkout master
221    Switched to branch "master" 204Switched to branch 'master' 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.205Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.
 206-----
223 207 
.224She can merge either `origin/master` or `issue54` first they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first:208She can merge either `origin/master` or `issue54` first they're both upstream, so the order doesn't matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first:
225 209 
. 210[source,console]
 211-----
226    $ git merge issue54212$ git merge issue54
227    Updating fbff5bc..4af4298213Updating fbff5bc..4af4298
228    Fast forward214Fast forward
229     README           |    1 +215 README           |    1 +
230     lib/simplegit.rb |    6 +++++-216 lib/simplegit.rb |    6 +++++-
231     2 files changed, 6 insertions(+), 1 deletions(-)217 2 files changed, 6 insertions(+), 1 deletions(-)
 218-----
232 219 
.233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`):220No problems occur; as you can see it was a simple fast-forward. Now Jessica merges in John's work (`origin/master`):
234 221 
. 222[source,console]
 223-----
235    $ git merge origin/master224$ git merge origin/master
236    Auto-merging lib/simplegit.rb225Auto-merging lib/simplegit.rb
237    Merge made by recursive.226Merge made by recursive.
238     lib/simplegit.rb |    2 +-227 lib/simplegit.rb |    2 +-
239     1 files changed, 1 insertions(+), 1 deletions(-)228 1 files changed, 1 insertions(+), 1 deletions(-)
 229-----
240 230 
.241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 231Everything merges cleanly, and Jessica's history looks like this: 
242 232 
.243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
 233.Jessica's history after merging John's changes.
 234image::images/small-team-6.png[Jessica's history after merging John's changes.]
245 235 
.246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime):236Now `origin/master` is reachable from Jessica's `master` branch, so she should be able to successfully push (assuming John hasn't pushed again in the meantime):
247 237 
. 238[source,console]
 239-----
248    $ git push origin master240$ git push origin master
249    ...241...
250    To jessica@githost:simplegit.git242To jessica@githost:simplegit.git
251       72bbc59..8059c15  master -> master243   72bbc59..8059c15  master -> master
 244-----
252 245 
.253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10.246Each developer has committed a few times and merged each other's work successfully.
254 247 
.255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
 248.Jessica's history after pushing all changes back to the server.
 249image::images/small-team-7.png[Jessica's history after pushing all changes back to the server.]
257 250 
.258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 251That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it's ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like this: 
259 252 
.260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
 253.General sequence of events for a simple multiple-developer Git workflow.
 254image::images/small-team-flow.png[General sequence of events for a simple multiple-developer Git workflow.]
262 255 
.263### Private Managed Team ### 256==== Private Managed Team 
264 257 
. 258(((contributing, private managed team)))
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party.259In this next scenario, you'll look at contributor roles in a larger private group. You'll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party.
266 260 
.267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later.261Let's say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later.
268 262 
.269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there:263Let's follow Jessica's workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there:
270 264 
. 265[source,console]
 266-----
271    # Jessica's Machine267# Jessica's Machine
272    $ git checkout -b featureA268$ git checkout -b featureA
273    Switched to a new branch "featureA" 269Switched to a new branch 'featureA' 
274    $ vim lib/simplegit.rb270$ vim lib/simplegit.rb
275    $ git commit -am 'add limit to log function'271$ git commit -am 'add limit to log function'
276    [featureA 3300904] add limit to log function272[featureA 3300904] add limit to log function
277     1 files changed, 1 insertions(+), 1 deletions(-)273 1 files changed, 1 insertions(+), 1 deletions(-)
 274-----
278 275 
.279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch only the integrators do so she has to push to another branch in order to collaborate with John:276At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn't have push access to the `master` branch only the integrators do so she has to push to another branch in order to collaborate with John:
280 277 
. 278[source,console]
 279-----
281    $ git push origin featureA280$ git push -u origin featureA
282    ...281...
283    To jessica@githost:simplegit.git282To jessica@githost:simplegit.git
284     * [new branch]      featureA -> featureA283 * [new branch]      featureA -> featureA
 284-----
285 285 
.286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch:286Jessica e-mails John to tell him that she's pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server's `master` branch:
287 287 
. 288[source,console]
 289-----
288    # Jessica's Machine290# Jessica's Machine
289    $ git fetch origin291$ git fetch origin
290    $ git checkout -b featureB origin/master292$ git checkout -b featureB origin/master
291    Switched to a new branch "featureB" 293Switched to a new branch 'featureB' 
 294-----
292 295 
293Now, Jessica makes a couple of commits on the `featureB` branch:296Now, Jessica makes a couple of commits on the `featureB` branch:
294 297 
. 298[source,console]
 299-----
295    $ vim lib/simplegit.rb300$ vim lib/simplegit.rb
296    $ git commit -am 'made the ls-tree function recursive'301$ git commit -am 'made the ls-tree function recursive'
297    [featureB e5b0fdc] made the ls-tree function recursive302[featureB e5b0fdc] made the ls-tree function recursive
298     1 files changed, 1 insertions(+), 1 deletions(-)303 1 files changed, 1 insertions(+), 1 deletions(-)
299    $ vim lib/simplegit.rb304$ vim lib/simplegit.rb
300    $ git commit -am 'add ls-files'305$ git commit -am 'add ls-files'
301    [featureB 8512791] add ls-files306[featureB 8512791] add ls-files
302     1 files changed, 5 insertions(+), 0 deletions(-)307 1 files changed, 5 insertions(+), 0 deletions(-)
 308-----
303 309 
.304Jessica’s repository looks like Figure 5-12. 310Jessica's repository looks like this: 
305 311 
.306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
 312.Jessica's initial commit history.
 313image::images/managed-team-1.png[Jessica's initial commit history.]
308 314 
.309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`:315She's ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie's changes down with `git fetch`:
310 316 
. 317[source,console]
 318-----
311    $ git fetch origin319$ git fetch origin
312    ...320...
313    From jessica@githost:simplegit321From jessica@githost:simplegit
314     * [new branch]      featureBee -> origin/featureBee322 * [new branch]      featureBee -> origin/featureBee
 323-----
315 324 
316Jessica can now merge this into the work she did with `git merge`:325Jessica can now merge this into the work she did with `git merge`:
317 326 
. 327[source,console]
 328-----
318    $ git merge origin/featureBee329$ git merge origin/featureBee
319    Auto-merging lib/simplegit.rb330Auto-merging lib/simplegit.rb
320    Merge made by recursive.331Merge made by recursive.
321     lib/simplegit.rb |    4 ++++332 lib/simplegit.rb |    4 ++++
322     1 files changed, 4 insertions(+), 0 deletions(-)333 1 files changed, 4 insertions(+), 0 deletions(-)
 334-----
323 335 
.324There is a bit of a problem she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command:336There is a bit of a problem she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command:
325 337 
. 338[source,console]
 339-----
326    $ git push origin featureB:featureBee340$ git push -u origin featureB:featureBee
327    ...341...
328    To jessica@githost:simplegit.git342To jessica@githost:simplegit.git
329       fba9af8..cd685d1  featureB -> featureBee343   fba9af8..cd685d1  featureB -> featureBee
 344-----
330 345 
.331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 346This is called a _refspec_. See <<_refspec>> for a more detailed discussion of Git refspecs and different things you can do with them. Also notice the `-u` flag; this is short for `--set-upstream`, which configures the branches for easier pushing and pulling later. 
332 347 
.333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes:348Next, John e-mails Jessica to say he's pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes:
334 349 
. 350[source,console]
 351-----
335    $ git fetch origin352$ git fetch origin
336    ...353...
337    From jessica@githost:simplegit354From jessica@githost:simplegit
338       3300904..aad881d  featureA   -> origin/featureA355   3300904..aad881d  featureA   -> origin/featureA
 356-----
339 357 
340Then, she can see what has been changed with `git log`:358Then, she can see what has been changed with `git log`:
341 359 
. 360[source,console]
 361-----
342    $ git log origin/featureA ^featureA362$ git log featureA..origin/featureA
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6363commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6
344    Author: John Smith <jsmith@example.com>364Author: John Smith <jsmith@example.com>
345    Date:   Fri May 29 19:57:33 2009 -0700365Date:   Fri May 29 19:57:33 2009 -0700
346 366 
.347        changed log output to 30 from 25367    changed log output to 30 from 25
 368-----
348 369 
.349Finally, she merges John’s work into her own `featureA` branch:370Finally, she merges John's work into her own `featureA` branch:
350 371 
. 372[source,console]
 373-----
351    $ git checkout featureA374$ git checkout featureA
352    Switched to branch "featureA" 375Switched to branch 'featureA' 
353    $ git merge origin/featureA376$ git merge origin/featureA
354    Updating 3300904..aad881d377Updating 3300904..aad881d
355    Fast forward378Fast forward
356     lib/simplegit.rb |   10 +++++++++-379 lib/simplegit.rb |   10 +++++++++-
357    1 files changed, 9 insertions(+), 1 deletions(-)3801 files changed, 9 insertions(+), 1 deletions(-)
 381-----
358 382 
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server:383Jessica wants to tweak something, so she commits again and then pushes this back up to the server:
360 384 
. 385[source,console]
 386-----
361    $ git commit -am 'small tweak'387$ git commit -am 'small tweak'
362    [featureA 774b3ed] small tweak388[featureA 774b3ed] small tweak
363     1 files changed, 1 insertions(+), 1 deletions(-)389 1 files changed, 1 insertions(+), 1 deletions(-)
364    $ git push origin featureA 390$ git push 
365    ...391...
366    To jessica@githost:simplegit.git392To jessica@githost:simplegit.git
367       3300904..774b3ed  featureA -> featureA393   3300904..774b3ed  featureA -> featureA
 394-----
368 395 
.369Jessica’s commit history now looks something like Figure 5-13. 396Jessica's commit history now looks something like this: 
370 397 
.371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
 398.Jessica's history after committing on a feature branch.
 399image::images/managed-team-2.png[Jessica's history after committing on a feature branch.]
373 400 
.374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 401Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After the integrators merge these branches into the mainline, a fetch will bring down the new merge commit, making the history look like this: 
375 402 
.376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
 403.Jessica's history after merging both her topic branches.
 404image::images/managed-team-3.png[Jessica's history after merging both her topic branches.]
378 405 
.379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 406Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like this: 
380 407 
.381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
 408.Basic sequence of this managed-team workflow.
 409image::images/managed-team-flow.png[Basic sequence of this managed-team workflow.]
383 410 
. 411[[_public_project]]
384### Public Small Project ### 412==== Forked Public Project 
385 413 
. 414(((contributing, public small project)))
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail.415Contributing to public projects is a bit different. Because you don't have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking.Many hosting sites support this (including GitHub, BitBucket, Google Code, repo.or.cz, and others), and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail.
387 416 
.388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this:417First, you'll probably want to clone the main repository, create a topic branch for the patch or patch series you're planning to contribute, and do your work there. The sequence looks basically like this:
389 418 
. 419[source,console]
 420-----
390    $ git clone (url)421$ git clone (url)
391    $ cd project422$ cd project
392    $ git checkout -b featureA423$ git checkout -b featureA
393    $ (work)424# (work)
394    $ git commit425$ git commit
395    $ (work)426# (work)
396    $ git commit427$ git commit
 428-----
397 429 
. 430[NOTE]
 431====
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review see Chapter 6 for more information about interactive rebasing.432You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review see <<_rewriting_history>> for more information about interactive rebasing.
 433====
399 434 
.400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`:435When your branch work is finished and you're ready to contribute it back to the maintainers, go to the original project page and click the ``Fork'' button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`:
401 436 
. 437[source,console]
 438-----
402    $ git remote add myfork (url)439$ git remote add myfork (url)
 440-----
403 441 
.404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow:442Then you need to push your work up to it. It's easiest to push the topic branch you're working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn't accepted or is cherry picked, you don't have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you'll eventually get it back via pulling from their repository anyhow:
405 443 
. 444[source,console]
 445-----
406    $ git push myfork featureA446$ git push -u myfork featureA
 447-----
407 448 
. 449(((git commands, request-pull)))
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website GitHub has a "pull request" button that automatically messages the maintainer or run the `git request-pull` command and e-mail the output to the project maintainer manually.450When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website GitHub has it's own Pull Request mechanism that we'll go over in <<_github>> or you can run the `git request-pull` command and e-mail the output to the project maintainer manually.
409 451 
.410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this:452The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you're asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she's done two commits on the topic branch she just pushed up, she can run this:
411 453 
. 454[source,console]
 455-----
412    $ git request-pull origin/master myfork456$ git request-pull origin/master myfork
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:457The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:
414      John Smith (1):458  John Smith (1):
415            added a new function459        added a new function
416 460 
.417    are available in the git repository at:461are available in the git repository at:
418 462 
.419      git://githost/simplegit.git featureA463  git://githost/simplegit.git featureA
420 464 
.421    Jessica Smith (2):465Jessica Smith (2):
422          add limit to log function466      add limit to log function
423          change log output to 30 from 25467      change log output to 30 from 25
424 468 
.425     lib/simplegit.rb |   10 +++++++++-469 lib/simplegit.rb |   10 +++++++++-
426     1 files changed, 9 insertions(+), 1 deletions(-)470 1 files changed, 9 insertions(+), 1 deletions(-)
 471-----
427 472 
.428The output can be sent to the maintainerit tells them where the work was branched from, summarizes the commits, and tells where to pull this work from.473The output can be sent to the maintainerit tells them where the work was branched from, summarizes the commits, and tells where to pull this work from.
429 474 
.430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up start over from the main repository’s `master` branch:475On a project for which you're not the maintainer, it's generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they're rejected. Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don't continue working on the topic branch you just pushed up start over from the main repository's `master` branch:
431 476 
. 477[source,console]
 478-----
432    $ git checkout -b featureB origin/master479$ git checkout -b featureB origin/master
433    $ (work)480# (work)
434    $ git commit481$ git commit
435    $ git push myfork featureB482$ git push myfork featureB
436    $ (email maintainer)483# (email maintainer)
437    $ git fetch origin484$ git fetch origin
 485-----
438 486 
.439Now, each of your topics is contained within a silo similar to a patch queue that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 487Now, each of your topics is contained within a silo similar to a patch queue that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other, like so: 
440 488 
.441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
 489.Initial commit history with `featureB` work.
 490image::images/public-small-1.png[Initial commit history with `featureB` work.]
443 491 
.444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes:492Let's say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes:
445 493 
. 494[source,console]
 495-----
446    $ git checkout featureA496$ git checkout featureA
447    $ git rebase origin/master497$ git rebase origin/master
448    $ git push -f myfork featureA498$ git push -f myfork featureA
 499-----
449 500 
.450This rewrites your history to now look like Figure 5-17.501This rewrites your history to now look like <<psp_b>>.
451 502 
.452Insert 18333fig0517.png 503[[psp_b]] 
453Figure 5-17. Commit history after featureA work.504.Commit history after `featureA` work.
 505image::images/public-small-2.png[Commit history after `featureA` work.]
454 506 
.455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`).507Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn't a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`).
456 508 
.457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch:509Let's look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You'll also take this opportunity to move the work to be based off the project's current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch:
458 510 
. 511(((git commands, merge, squash)))
 512[source,console]
 513-----
459    $ git checkout -b featureBv2 origin/master514$ git checkout -b featureBv2 origin/master
460    $ git merge --no-commit --squash featureB515$ git merge --no-commit --squash featureB
461    $ (change implementation)516# (change implementation)
462    $ git commit517$ git commit
463    $ git push myfork featureBv2518$ git push myfork featureBv2
 519-----
464 520 
.465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit.521The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you're on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit.
466 522 
.467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18).523Now you can send the maintainer a message that you've made the requested changes and they can find those changes in your `featureBv2` branch.
468 524 
.469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
 525.Commit history after `featureBv2` work.
 526image::images/public-small-3.png[Commit history after `featureBv2` work.]
471 527 
. 528[[_project_over_email]]
472### Public Large Project ### 529==== Public Project over E-Mail 
473 530 
. 531(((contributing, public large project)))
474Many larger projects have established procedures for accepting patches you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now.532Many projects have established procedures for accepting patches you'll need to check the specific rules for each project, because they will differ. Since there are several older, larger projects which accept patches via a developer mailing list, we'll go over an example of that now.
475 533 
.476The workflow is similar to the previous use case you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list:534The workflow is similar to the previous use case you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list:
477 535 
. 536[source,console]
 537-----
478    $ git checkout -b topicA538$ git checkout -b topicA
479    $ (work)539# (work)
480    $ git commit540$ git commit
481    $ (work)541# (work)
482    $ git commit542$ git commit
 543-----
483 544 
. 545(((git commands, format-patch)))
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 546Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly. 
485 547 
. 548[source,console]
 549-----
486    $ git format-patch -M origin/master550$ git format-patch -M origin/master
487    0001-add-limit-to-log-function.patch5510001-add-limit-to-log-function.patch
488    0002-changed-log-output-to-30-from-25.patch5520002-changed-log-output-to-30-from-25.patch
 553-----
489 554 
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this:555The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this:
491 556 
. 557[source,console]
 558-----
492    $ cat 0001-add-limit-to-log-function.patch559$ cat 0001-add-limit-to-log-function.patch
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001560From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
494    From: Jessica Smith <jessica@example.com>561From: Jessica Smith <jessica@example.com>
495    Date: Sun, 6 Apr 2008 10:17:23 -0700562Date: Sun, 6 Apr 2008 10:17:23 -0700
496    Subject: [PATCH 1/2] add limit to log function563Subject: [PATCH 1/2] add limit to log function
497 564 
.498    Limit log functionality to the first 20565Limit log functionality to the first 20
499 566 
.500    ---567---
501     lib/simplegit.rb |    2 +-568 lib/simplegit.rb |    2 +-
502     1 files changed, 1 insertions(+), 1 deletions(-)569 1 files changed, 1 insertions(+), 1 deletions(-)
503 570 
.504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb571diff --git a/lib/simplegit.rb b/lib/simplegit.rb
505    index 76f47bc..f9815f1 100644572index 76f47bc..f9815f1 100644
506    --- a/lib/simplegit.rb573--- a/lib/simplegit.rb
507    +++ b/lib/simplegit.rb574+++ b/lib/simplegit.rb
508    @@ -14,7 +14,7 @@ class SimpleGit575@@ -14,7 +14,7 @@ class SimpleGit
509       end576   end
510 577 
.511       def log(treeish = 'master')578   def log(treeish = 'master')
512    -    command("git log #{treeish}")579-    command("git log #{treeish}")
513    +    command("git log -n 20 #{treeish}")580+    command("git log -n 20 #{treeish}")
514       end581   end
515 582 
.516       def ls_tree(treeish = 'master')583   def ls_tree(treeish = 'master')
517    --584--
518    1.6.2.rc1.20.g8c5b.dirty 5852.1.0 
 586-----
519 587 
.520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it.588You can also edit these patch files to add more information for the e-mail list that you don't want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `diff --git` line), then developers can read it; but applying the patch excludes it.
521 589 
.522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code.590To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with ``smarter'' clients that don't preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. We'll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent we know best; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code.
523 591 
. 592(((git commands, config)))(((email)))
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this:593First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually, but in the end your config file should look something like this:
525 594 
. 595[source,ini]
 596-----
526    [imap]597[imap]
527      folder = "[Gmail]/Drafts"598  folder = "[Gmail]/Drafts"
528      host = imaps://imap.gmail.com599  host = imaps://imap.gmail.com
529      user = user@gmail.com600  user = user@gmail.com
530      pass = p4ssw0rd601  pass = p4ssw0rd
531      port = 993602  port = 993
532      sslverify = false603  sslverify = false
 604-----
533 605 
.534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`.606If your IMAP server doesn't use SSL, the last two lines probably aren't necessary, and the host value will be `imap://` instead of `imaps://`.
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server:607When that is set up, you can use `git send-email` to place the patch series in the Drafts folder of the specified IMAP server:
536 608 
.537    $ cat *.patch |git imap-send 609[source,console] 
538    Resolving imap.gmail.com... ok 610----- 
539    Connecting to [74.125.142.109]:993... ok 611$ git send-email *.patch 
540    Logging in... 6120001-added-limit-to-log-function.patch 
541    sending 2 messages 6130002-changed-log-output-to-30-from-25.patch 
542    100% (2/2) done 614Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
 615Emails will be sent from: Jessica Smith <jessica@example.com>
 616Who should the emails be sent to? jessica@example.com
 617Message-ID to be used as In-Reply-To for the first email? y
 618-----
 619 
 620Then, Git spits out a bunch of log information looking something like this for each patch you're sending:
 621 
 622[source,text]
 623-----
 624(mbox) Adding cc: Jessica Smith <jessica@example.com> from
 625  \line 'From: Jessica Smith <jessica@example.com>'
 626OK. Log says:
 627Sendmail: /usr/sbin/sendmail -i jessica@example.com
 628From: Jessica Smith <jessica@example.com>
 629To: jessica@example.com
 630Subject: [PATCH 1/2] added limit to log function
 631Date: Sat, 30 May 2009 13:29:15 -0700
 632Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com>
 633X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty
 634In-Reply-To: <y>
 635References: <y>
 636 
 637Result: OK
 638-----
543 639 
.544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off.640At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you're sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off.
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580 641 
.581### Summary ### 642==== Summary 
582 643 
.583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager.644This section has covered a number of common workflows for dealing with several very different types of Git projects you're likely to encounter, and introduced a couple of new tools to help you manage this process. Next, you'll see how to work the other side of the coin: maintaining a Git project. You'll learn how to be a benevolent dictator or integration manager.
584  
585## Maintaining a Project ## 
586  
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. 
588  
589### Working in Topic Branches ### 
590  
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. 
592As you’ll remember, you can create the branch based off your master branch like this: 
593  
594    $ git branch sc/ruby_client master 
595  
596Or, if you want to also switch to it immediately, you can use the `checkout -b` command: 
597  
598    $ git checkout -b sc/ruby_client master 
599  
600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. 
601  
602### Applying Patches from E-mail ### 
603  
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. 
605  
606#### Applying a Patch with apply #### 
607  
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: 
609  
610    $ git apply /tmp/patch-ruby-client.patch 
611  
612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you — after running it, you must stage and commit the changes introduced manually. 
613  
614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: 
615  
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch 
617    error: patch failed: ticgit.gemspec:1 
618    error: ticgit.gemspec: patch does not apply 
619  
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. 
621  
622#### Applying a Patch with am #### 
623  
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. 
625  
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: 
627  
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
629    From: Jessica Smith <jessica@example.com> 
630    Date: Sun, 6 Apr 2008 10:17:23 -0700 
631    Subject: [PATCH 1/2] add limit to log function 
632  
633    Limit log functionality to the first 20 
634  
635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time. 
636  
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: 
638  
639    $ git am 0001-limit-log-function.patch 
640    Applying: add limit to log function 
641  
642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: 
643  
644    $ git log --pretty=fuller -1 
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
646    Author:     Jessica Smith <jessica@example.com> 
647    AuthorDate: Sun Apr 6 10:17:23 2008 -0700 
648    Commit:     Scott Chacon <schacon@gmail.com> 
649    CommitDate: Thu Apr 9 09:19:06 2009 -0700 
650  
651       add limit to log function 
652  
653       Limit log functionality to the first 20 
654  
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. 
656  
657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: 
658  
659    $ git am 0001-seeing-if-this-helps-the-gem.patch 
660    Applying: seeing if this helps the gem 
661    error: patch failed: ticgit.gemspec:1 
662    error: ticgit.gemspec: patch does not apply 
663    Patch failed at 0001. 
664    When you have resolved this problem run "git am --resolved". 
665    If you would prefer to skip this patch, instead run "git am --skip". 
666    To restore the original branch and stop patching run "git am --abort". 
667  
668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: 
669  
670    $ (fix the file) 
671    $ git add ticgit.gemspec 
672    $ git am --resolved 
673    Applying: seeing if this helps the gem 
674  
675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: 
676  
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch 
678    Applying: seeing if this helps the gem 
679    error: patch failed: ticgit.gemspec:1 
680    error: ticgit.gemspec: patch does not apply 
681    Using index info to reconstruct a base tree... 
682    Falling back to patching base and 3-way merge... 
683    No changes -- Patch already applied. 
684  
685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict. 
686  
687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: 
688  
689    $ git am -3 -i mbox 
690    Commit Body is: 
691    -------------------------- 
692    seeing if this helps the gem 
693    -------------------------- 
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all 
695  
696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. 
697  
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. 
699  
700### Checking Out Remote Branches ### 
701  
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. 
703  
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: 
705  
706    $ git remote add jessica git://github.com/jessica/myproject.git 
707    $ git fetch jessica 
708    $ git checkout -b rubyclient jessica/ruby-client 
709  
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. 
711  
712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier — it depends largely on how you develop and how your contributors develop. 
713  
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. 
715  
716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference: 
717  
718    $ git pull git://github.com/onetimeguy/project.git 
719    From git://github.com/onetimeguy/project 
720     * branch            HEAD       -> FETCH_HEAD 
721    Merge made by recursive. 
722  
723### Determining What Is Introduced ### 
724  
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch. 
726  
727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: 
728  
729    $ git log contrib --not master 
730    commit 5b6235bd297351589efc4d73316f0a68d484f118 
731    Author: Scott Chacon <schacon@gmail.com> 
732    Date:   Fri Oct 24 09:53:59 2008 -0700 
733  
734        seeing if this helps the gem 
735  
736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 
737    Author: Scott Chacon <schacon@gmail.com> 
738    Date:   Mon Oct 22 19:38:36 2008 -0700 
739  
740        updated the gemspec to hopefully work better 
741  
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. 
743  
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: 
745  
746    $ git diff master 
747  
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. 
749  
750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch. 
751  
752What you really want to see are the changes added to the topic branch — the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. 
753  
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: 
755  
756    $ git merge-base contrib master 
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 
758    $ git diff 36c7db 
759  
760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: 
761  
762    $ git diff master...contrib 
763  
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. 
765  
766### Integrating Contributed Work ### 
767  
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them. 
769  
770#### Merging Workflows #### 
771  
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. 
773  
774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
776  
777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
779  
780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. 
781  
782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). 
783  
784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
786  
787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
789  
790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
792  
793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. 
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. 
795  
796#### Large-Merging Workflows #### 
797  
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. 
799  
800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
802  
803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 
804  
805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
807  
808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 
809  
810#### Rebasing and Cherry Picking Workflows #### 
811  
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history. 
813  
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 
815  
816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
818  
819If you want to pull commit `e43a6` into your master branch, you can run 
820  
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf 
822    Finished one cherry-pick. 
823    [master]: created a0a41a9: "More friendly message when locking the index fails." 
824     3 files changed, 17 insertions(+), 3 deletions(-) 
825  
826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 
827  
828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
830  
831Now you can remove your topic branch and drop the commits you didn’t want to pull in. 
832  
833### Tagging Your Releases ### 
834  
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this: 
836  
837    $ git tag -s v1.5 -m 'my signed 1.5 tag' 
838    You need a passphrase to unlock the secret key for 
839    user: "Scott Chacon <schacon@gmail.com>" 
840    1024-bit DSA key, ID F721C45A, created 2009-02-09 
841  
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: 
843  
844    $ gpg --list-keys 
845    /Users/schacon/.gnupg/pubring.gpg 
846    --------------------------------- 
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09] 
848    uid                  Scott Chacon <schacon@gmail.com> 
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09] 
850  
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: 
852  
853    $ gpg -a --export F721C45A | git hash-object -w --stdin 
854    659ef797d181633c87ec71ac3f9ba29fe5775b92 
855  
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: 
857  
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 
859  
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: 
861  
862    $ git show maintainer-pgp-pub | gpg --import 
863  
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification. 
865  
866### Generating a Build Number ### 
867  
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing: 
869  
870    $ git describe master 
871    v1.6.2-rc1-20-g8c5b85c 
872  
873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name. 
874  
875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. 
876  
877### Preparing a Release ### 
878  
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`: 
880  
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz 
882    $ ls *.tar.gz 
883    v1.6.2-rc1-20-g8c5b85c.tar.gz 
884  
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: 
886  
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip 
888  
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. 
890  
891### The Shortlog ### 
892  
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: 
894  
895    $ git shortlog --no-merges master --not v1.0.1 
896    Chris Wanstrath (8): 
897          Add support for annotated tags to Grit::Tag 
898          Add packed-refs annotated tag support. 
899          Add Grit::Commit#to_patch 
900          Update version and History.txt 
901          Remove stray `puts` 
902          Make ls_tree ignore nils 
903  
904    Tom Preston-Werner (4): 
905          fix dates in history 
906          dynamic version method 
907          Version bump to 1.0.2 
908          Regenerated gemspec for version 1.0.2 
909  
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. 
911  
912## Summary ## 
913  
914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master. 
915 645 
-
- diff --git a/book/05-distributed-git/sections/diff-distributed-workflows.htm b/book/05-distributed-git/sections/diff-distributed-workflows.htm deleted file mode 100644 index 79be3f05..00000000 --- a/book/05-distributed-git/sections/diff-distributed-workflows.htm +++ /dev/null @@ -1,3843 +0,0 @@ - - - - -WinMerge File Compare Report - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\sections\distributed-workflows.asc
.1# Distributed Git # 
2  
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you. 
4  
5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. 
6  
7## Distributed Workflows ## 1=== Distributed Workflows 
8 2 
. 3(((workflows)))
9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each.4Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so we'll cover a few common paradigms that take advantage of this flexibility. We'll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each.
10 5 
.11### Centralized Workflow ### 6==== Centralized Workflow 
12 7 
. 8(((workflows, centralized)))
13In centralized systems, there is generally a single collaboration modelthe centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes consumers of that hub and synchronize to that one place (see Figure 5-1).9In centralized systems, there is generally a single collaboration modelthe centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes consumers of that hub and synchronize to that one place.
14 10 
.15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
 11.Centralized workflow.
 12image::images/centralized.png[Centralized workflow.]
17 13 
.18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git.14This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one's work before pushing changes up, so as not to overwrite the first developer's changes. This concept is as true in Git as it is in Subversion(((Subversion))) (or any CVCS), and this model works perfectly well in Git.
19 15 
.20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 16If you are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won't let users overwrite each other. Say John and Jessica both start working at the same time. John finishes his change and pushes it to the server. Then Jessica tries to push her changes, but the server rejects them. She is told that she's trying to push non-fast-forward changes and that she won't be able to do so until she fetches and merges.  
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with.17This workflow is attractive to a lot of people because it's a paradigm that many are familiar and comfortable with.
22 18 
. 19This is also not limited to small teams. With Git's branching model, it's possible for hundreds of developers to successfully work on a single project through dozens of branches simultaneously.
 20 
 21[[_integration_manager]]
23### Integration-Manager Workflow ### 22==== Integration-Manager Workflow 
24 23 
. 24(((workflows, integration manager)))
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2):25Because Git allows you to have multiple remote repositories, it's possible to have a workflow where each developer has write access to their own public repository and read access to everyone else's. This scenario often includes a canonical repository that represents the ``official'' project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. The maintainer can then add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see <<wfdiag_b>>):
26 26 
.271. The project maintainer pushes to their public repository.271.  The project maintainer pushes to their public repository.
282. A contributor clones that repository and makes changes.282.  A contributor clones that repository and makes changes.
293. The contributor pushes to their own public copy.293.  The contributor pushes to their own public copy.
304. The contributor sends the maintainer an e-mail asking them to pull changes.304.  The contributor sends the maintainer an e-mail asking them to pull changes.
315. The maintainer adds the contributor’s repo as a remote and merges locally.315.  The maintainer adds the contributor's repo as a remote and merges locally.
326. The maintainer pushes merged changes to the main repository.326.  The maintainer pushes merged changes to the main repository.
33 33 
.34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
 34[[wfdiag_b]]
 35.Integration-manager workflow.
 36image::images/integration-manager.png[Integration-manager workflow.]
36 37 
. 38(((forking)))
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes each party can work at their own pace.39This is a very common workflow with hub-based tools like GitHub or GitLab, where it's easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don't have to wait for the project to incorporate their changes each party can work at their own pace.
38 40 
.39### Dictator and Lieutenants Workflow ### 41==== Dictator and Lieutenants Workflow 
40 42 
. 43(((workflows, dictator and lieutenants)))
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3):44This is a variant of a multiple-repository workflow. It's generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they're called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator's repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see <<wfdiag_c>>):
42 45 
.431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator.461.  Regular developers work on their topic branch and rebase their work on top of `master`.
 47    The `master` branch is that of the dictator.
442. Lieutenants merge the developers’ topic branches into their master branch.482.  Lieutenants merge the developers' topic branches into their `master` branch.
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch.493.  The dictator merges the lieutenants' `master` branches into the dictator's `master` branch.
464. The dictator pushes their master to the reference repository so the other developers can rebase on it.504.  The dictator pushes their `master` to the reference repository so the other developers can rebase on it.
47 51 
.48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
 52[[wfdiag_c]]
 53.Benevolent dictator workflow.
 54image::images/benevolent-dictator.png[Benevolent dictator workflow.]
50 55 
.51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them.56This kind of workflow isn't common, but can be useful in very big projects, or in highly hierarchical environments. It allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them.
 57 
 58==== Workflows Summary
52 59 
.53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 60These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (hopefully) determine which workflow combination may work for you, we'll cover some more specific examples of how to accomplish the main roles that make up the different flows. In the next section, you'll learn about a few common patterns for contributing to a project. 
54  
55## Contributing to a Project ## 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58  
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method. 
60  
61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid? 
62  
63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 
64  
65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? 
66  
67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. 
68  
69### Commit Guidelines ### 
70  
71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches — you can read it in the Git source code in the `Documentation/SubmittingPatches` file. 
72  
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this — before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 
74  
75    $ git diff --check 
76    lib/simplegit.rb:5: trailing whitespace. 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82  
83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers. 
84  
85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible — don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files — use these tools to help craft a clean and understandable history. 
86  
87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 
88Here is a template originally written by Tim Pope at tpope.net: 
89  
90    Short (50 chars or less) summary of changes 
91  
92    More detailed explanatory text, if necessary.  Wrap it to about 72 
93    characters or so.  In some contexts, the first line is treated as the 
94    subject of an email and the rest of the text as the body.  The blank 
95    line separating the summary from the body is critical (unless you omit 
96    the body entirely); tools like rebase can get confused if you run the 
97    two together. 
98  
99    Further paragraphs come after blank lines. 
100  
101     - Bullet points are okay, too 
102  
103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 
104       single space, with blank lines in between, but conventions vary here 
105  
106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages — I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like. 
107  
108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do. 
109  
110### Private Small Team ### 
111  
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source — not read-accessible to the outside world. You and the other developers all have push access to the repository. 
113  
114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.) 
116  
117    # John's Machine 
118    $ git clone john@githost:simplegit.git 
119    Initialized empty Git repository in /home/john/simplegit/.git/ 
120    ... 
121    $ cd simplegit/ 
122    $ vim lib/simplegit.rb 
123    $ git commit -am 'removed invalid default value' 
124    [master 738ee87] removed invalid default value 
125     1 files changed, 1 insertions(+), 1 deletions(-) 
126  
127The second developer, Jessica, does the same thing — clones the repository and commits a change: 
128  
129    # Jessica's Machine 
130    $ git clone jessica@githost:simplegit.git 
131    Initialized empty Git repository in /home/jessica/simplegit/.git/ 
132    ... 
133    $ cd simplegit/ 
134    $ vim TODO 
135    $ git commit -am 'add reset task' 
136    [master fbff5bc] add reset task 
137     1 files changed, 1 insertions(+), 0 deletions(-) 
138  
139Now, Jessica pushes her work up to the server: 
140  
141    # Jessica's Machine 
142    $ git push origin master 
143    ... 
144    To jessica@githost:simplegit.git 
145       1edee6b..fbff5bc  master -> master 
146  
147John tries to push his change up, too: 
148  
149    # John's Machine 
150    $ git push origin master 
151    To john@githost:simplegit.git 
152     ! [rejected]        master -> master (non-fast forward) 
153    error: failed to push some refs to 'john@githost:simplegit.git' 
154  
155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push: 
156  
157    $ git fetch origin 
158    ... 
159    From john@githost:simplegit 
160     + 049d078...fbff5bc master     -> origin/master 
161  
162At this point, John’s local repository looks something like Figure 5-4. 
163  
164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
166  
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: 
168  
169    $ git merge origin/master 
170    Merge made by recursive. 
171     TODO |    1 + 
172     1 files changed, 1 insertions(+), 0 deletions(-) 
173  
174The merge goes smoothly — John’s commit history now looks like Figure 5-5. 
175  
176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
178  
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: 
180  
181    $ git push origin master 
182    ... 
183    To john@githost:simplegit.git 
184       fbff5bc..72bbc59  master -> master 
185  
186Finally, John’s commit history looks like Figure 5-6. 
187  
188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
190  
191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 
192  
193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
195  
196Jessica wants to sync up with John, so she fetches: 
197  
198    # Jessica's Machine 
199    $ git fetch origin 
200    ... 
201    From jessica@githost:simplegit 
202       fbff5bc..72bbc59  master     -> origin/master 
203  
204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 
205  
206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
208  
209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: 
210  
211    $ git log --no-merges origin/master ^issue54 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016 
213    Author: John Smith <jsmith@example.com> 
214    Date:   Fri May 29 16:01:27 2009 -0700 
215  
216        removed invalid default value 
217  
218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work: 
219  
220    $ git checkout master 
221    Switched to branch "master" 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. 
223  
224She can merge either `origin/master` or `issue54` first — they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: 
225  
226    $ git merge issue54 
227    Updating fbff5bc..4af4298 
228    Fast forward 
229     README           |    1 + 
230     lib/simplegit.rb |    6 +++++- 
231     2 files changed, 6 insertions(+), 1 deletions(-) 
232  
233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`): 
234  
235    $ git merge origin/master 
236    Auto-merging lib/simplegit.rb 
237    Merge made by recursive. 
238     lib/simplegit.rb |    2 +- 
239     1 files changed, 1 insertions(+), 1 deletions(-) 
240  
241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 
242  
243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
245  
246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): 
247  
248    $ git push origin master 
249    ... 
250    To jessica@githost:simplegit.git 
251       72bbc59..8059c15  master -> master 
252  
253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. 
254  
255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
257  
258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 
259  
260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
262  
263### Private Managed Team ### 
264  
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. 
266  
267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. 
268  
269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: 
270  
271    # Jessica's Machine 
272    $ git checkout -b featureA 
273    Switched to a new branch "featureA" 
274    $ vim lib/simplegit.rb 
275    $ git commit -am 'add limit to log function' 
276    [featureA 3300904] add limit to log function 
277     1 files changed, 1 insertions(+), 1 deletions(-) 
278  
279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch — only the integrators do — so she has to push to another branch in order to collaborate with John: 
280  
281    $ git push origin featureA 
282    ... 
283    To jessica@githost:simplegit.git 
284     * [new branch]      featureA -> featureA 
285  
286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch: 
287  
288    # Jessica's Machine 
289    $ git fetch origin 
290    $ git checkout -b featureB origin/master 
291    Switched to a new branch "featureB" 
292  
293Now, Jessica makes a couple of commits on the `featureB` branch: 
294  
295    $ vim lib/simplegit.rb 
296    $ git commit -am 'made the ls-tree function recursive' 
297    [featureB e5b0fdc] made the ls-tree function recursive 
298     1 files changed, 1 insertions(+), 1 deletions(-) 
299    $ vim lib/simplegit.rb 
300    $ git commit -am 'add ls-files' 
301    [featureB 8512791] add ls-files 
302     1 files changed, 5 insertions(+), 0 deletions(-) 
303  
304Jessica’s repository looks like Figure 5-12. 
305  
306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
308  
309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: 
310  
311    $ git fetch origin 
312    ... 
313    From jessica@githost:simplegit 
314     * [new branch]      featureBee -> origin/featureBee 
315  
316Jessica can now merge this into the work she did with `git merge`: 
317  
318    $ git merge origin/featureBee 
319    Auto-merging lib/simplegit.rb 
320    Merge made by recursive. 
321     lib/simplegit.rb |    4 ++++ 
322     1 files changed, 4 insertions(+), 0 deletions(-) 
323  
324There is a bit of a problem — she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: 
325  
326    $ git push origin featureB:featureBee 
327    ... 
328    To jessica@githost:simplegit.git 
329       fba9af8..cd685d1  featureB -> featureBee 
330  
331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 
332  
333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: 
334  
335    $ git fetch origin 
336    ... 
337    From jessica@githost:simplegit 
338       3300904..aad881d  featureA   -> origin/featureA 
339  
340Then, she can see what has been changed with `git log`: 
341  
342    $ git log origin/featureA ^featureA 
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 
344    Author: John Smith <jsmith@example.com> 
345    Date:   Fri May 29 19:57:33 2009 -0700 
346  
347        changed log output to 30 from 25 
348  
349Finally, she merges John’s work into her own `featureA` branch: 
350  
351    $ git checkout featureA 
352    Switched to branch "featureA" 
353    $ git merge origin/featureA 
354    Updating 3300904..aad881d 
355    Fast forward 
356     lib/simplegit.rb |   10 +++++++++- 
357    1 files changed, 9 insertions(+), 1 deletions(-) 
358  
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server: 
360  
361    $ git commit -am 'small tweak' 
362    [featureA 774b3ed] small tweak 
363     1 files changed, 1 insertions(+), 1 deletions(-) 
364    $ git push origin featureA 
365    ... 
366    To jessica@githost:simplegit.git 
367       3300904..774b3ed  featureA -> featureA 
368  
369Jessica’s commit history now looks something like Figure 5-13. 
370  
371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
373  
374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 
375  
376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
378  
379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 
380  
381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
383  
384### Public Small Project ### 
385  
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. 
387  
388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this: 
389  
390    $ git clone (url) 
391    $ cd project 
392    $ git checkout -b featureA 
393    $ (work) 
394    $ git commit 
395    $ (work) 
396    $ git commit 
397  
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review — see Chapter 6 for more information about interactive rebasing. 
399  
400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: 
401  
402    $ git remote add myfork (url) 
403  
404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow: 
405  
406    $ git push myfork featureA 
407  
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website — GitHub has a "pull request" button that automatically messages the maintainer — or run the `git request-pull` command and e-mail the output to the project maintainer manually. 
409  
410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this: 
411  
412    $ git request-pull origin/master myfork 
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: 
414      John Smith (1): 
415            added a new function 
416  
417    are available in the git repository at: 
418  
419      git://githost/simplegit.git featureA 
420  
421    Jessica Smith (2): 
422          add limit to log function 
423          change log output to 30 from 25 
424  
425     lib/simplegit.rb |   10 +++++++++- 
426     1 files changed, 9 insertions(+), 1 deletions(-) 
427  
428The output can be sent to the maintainer—it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. 
429  
430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up — start over from the main repository’s `master` branch: 
431  
432    $ git checkout -b featureB origin/master 
433    $ (work) 
434    $ git commit 
435    $ git push myfork featureB 
436    $ (email maintainer) 
437    $ git fetch origin 
438  
439Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 
440  
441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
443  
444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: 
445  
446    $ git checkout featureA 
447    $ git rebase origin/master 
448    $ git push -f myfork featureA 
449  
450This rewrites your history to now look like Figure 5-17. 
451  
452Insert 18333fig0517.png 
453Figure 5-17. Commit history after featureA work. 
454  
455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). 
456  
457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: 
458  
459    $ git checkout -b featureBv2 origin/master 
460    $ git merge --no-commit --squash featureB 
461    $ (change implementation) 
462    $ git commit 
463    $ git push myfork featureBv2 
464  
465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. 
466  
467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). 
468  
469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
471  
472### Public Large Project ### 
473  
474Many larger projects have established procedures for accepting patches — you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now. 
475  
476The workflow is similar to the previous use case — you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: 
477  
478    $ git checkout -b topicA 
479    $ (work) 
480    $ git commit 
481    $ (work) 
482    $ git commit 
483  
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list — it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 
485  
486    $ git format-patch -M origin/master 
487    0001-add-limit-to-log-function.patch 
488    0002-changed-log-output-to-30-from-25.patch 
489  
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: 
491  
492    $ cat 0001-add-limit-to-log-function.patch 
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
494    From: Jessica Smith <jessica@example.com> 
495    Date: Sun, 6 Apr 2008 10:17:23 -0700 
496    Subject: [PATCH 1/2] add limit to log function 
497  
498    Limit log functionality to the first 20 
499  
500    --- 
501     lib/simplegit.rb |    2 +- 
502     1 files changed, 1 insertions(+), 1 deletions(-) 
503  
504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
505    index 76f47bc..f9815f1 100644 
506    --- a/lib/simplegit.rb 
507    +++ b/lib/simplegit.rb 
508    @@ -14,7 +14,7 @@ class SimpleGit 
509       end 
510  
511       def log(treeish = 'master') 
512    -    command("git log #{treeish}") 
513    +    command("git log -n 20 #{treeish}") 
514       end 
515  
516       def ls_tree(treeish = 'master') 
517    -- 
518    1.6.2.rc1.20.g8c5b.dirty 
519  
520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. 
521  
522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. 
523  
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this: 
525  
526    [imap] 
527      folder = "[Gmail]/Drafts" 
528      host = imaps://imap.gmail.com 
529      user = user@gmail.com 
530      pass = p4ssw0rd 
531      port = 993 
532      sslverify = false 
533  
534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`. 
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: 
536  
537    $ cat *.patch |git imap-send 
538    Resolving imap.gmail.com... ok 
539    Connecting to [74.125.142.109]:993... ok 
540    Logging in... 
541    sending 2 messages 
542    100% (2/2) done 
543  
544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. 
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580  
581### Summary ### 
582  
583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager. 
584  
585## Maintaining a Project ## 
586  
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. 
588  
589### Working in Topic Branches ### 
590  
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. 
592As you’ll remember, you can create the branch based off your master branch like this: 
593  
594    $ git branch sc/ruby_client master 
595  
596Or, if you want to also switch to it immediately, you can use the `checkout -b` command: 
597  
598    $ git checkout -b sc/ruby_client master 
599  
600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. 
601  
602### Applying Patches from E-mail ### 
603  
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. 
605  
606#### Applying a Patch with apply #### 
607  
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: 
609  
610    $ git apply /tmp/patch-ruby-client.patch 
611  
612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you — after running it, you must stage and commit the changes introduced manually. 
613  
614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: 
615  
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch 
617    error: patch failed: ticgit.gemspec:1 
618    error: ticgit.gemspec: patch does not apply 
619  
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. 
621  
622#### Applying a Patch with am #### 
623  
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. 
625  
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: 
627  
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
629    From: Jessica Smith <jessica@example.com> 
630    Date: Sun, 6 Apr 2008 10:17:23 -0700 
631    Subject: [PATCH 1/2] add limit to log function 
632  
633    Limit log functionality to the first 20 
634  
635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time. 
636  
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: 
638  
639    $ git am 0001-limit-log-function.patch 
640    Applying: add limit to log function 
641  
642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: 
643  
644    $ git log --pretty=fuller -1 
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
646    Author:     Jessica Smith <jessica@example.com> 
647    AuthorDate: Sun Apr 6 10:17:23 2008 -0700 
648    Commit:     Scott Chacon <schacon@gmail.com> 
649    CommitDate: Thu Apr 9 09:19:06 2009 -0700 
650  
651       add limit to log function 
652  
653       Limit log functionality to the first 20 
654  
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. 
656  
657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: 
658  
659    $ git am 0001-seeing-if-this-helps-the-gem.patch 
660    Applying: seeing if this helps the gem 
661    error: patch failed: ticgit.gemspec:1 
662    error: ticgit.gemspec: patch does not apply 
663    Patch failed at 0001. 
664    When you have resolved this problem run "git am --resolved". 
665    If you would prefer to skip this patch, instead run "git am --skip". 
666    To restore the original branch and stop patching run "git am --abort". 
667  
668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: 
669  
670    $ (fix the file) 
671    $ git add ticgit.gemspec 
672    $ git am --resolved 
673    Applying: seeing if this helps the gem 
674  
675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: 
676  
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch 
678    Applying: seeing if this helps the gem 
679    error: patch failed: ticgit.gemspec:1 
680    error: ticgit.gemspec: patch does not apply 
681    Using index info to reconstruct a base tree... 
682    Falling back to patching base and 3-way merge... 
683    No changes -- Patch already applied. 
684  
685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict. 
686  
687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: 
688  
689    $ git am -3 -i mbox 
690    Commit Body is: 
691    -------------------------- 
692    seeing if this helps the gem 
693    -------------------------- 
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all 
695  
696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. 
697  
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. 
699  
700### Checking Out Remote Branches ### 
701  
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. 
703  
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: 
705  
706    $ git remote add jessica git://github.com/jessica/myproject.git 
707    $ git fetch jessica 
708    $ git checkout -b rubyclient jessica/ruby-client 
709  
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. 
711  
712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier — it depends largely on how you develop and how your contributors develop. 
713  
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. 
715  
716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference: 
717  
718    $ git pull git://github.com/onetimeguy/project.git 
719    From git://github.com/onetimeguy/project 
720     * branch            HEAD       -> FETCH_HEAD 
721    Merge made by recursive. 
722  
723### Determining What Is Introduced ### 
724  
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch. 
726  
727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: 
728  
729    $ git log contrib --not master 
730    commit 5b6235bd297351589efc4d73316f0a68d484f118 
731    Author: Scott Chacon <schacon@gmail.com> 
732    Date:   Fri Oct 24 09:53:59 2008 -0700 
733  
734        seeing if this helps the gem 
735  
736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 
737    Author: Scott Chacon <schacon@gmail.com> 
738    Date:   Mon Oct 22 19:38:36 2008 -0700 
739  
740        updated the gemspec to hopefully work better 
741  
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. 
743  
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: 
745  
746    $ git diff master 
747  
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. 
749  
750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch. 
751  
752What you really want to see are the changes added to the topic branch — the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. 
753  
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: 
755  
756    $ git merge-base contrib master 
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 
758    $ git diff 36c7db 
759  
760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: 
761  
762    $ git diff master...contrib 
763  
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. 
765  
766### Integrating Contributed Work ### 
767  
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them. 
769  
770#### Merging Workflows #### 
771  
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. 
773  
774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
776  
777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
779  
780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. 
781  
782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). 
783  
784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
786  
787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
789  
790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
792  
793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. 
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. 
795  
796#### Large-Merging Workflows #### 
797  
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. 
799  
800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
802  
803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 
804  
805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
807  
808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 
809  
810#### Rebasing and Cherry Picking Workflows #### 
811  
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history. 
813  
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 
815  
816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
818  
819If you want to pull commit `e43a6` into your master branch, you can run 
820  
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf 
822    Finished one cherry-pick. 
823    [master]: created a0a41a9: "More friendly message when locking the index fails." 
824     3 files changed, 17 insertions(+), 3 deletions(-) 
825  
826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 
827  
828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
830  
831Now you can remove your topic branch and drop the commits you didn’t want to pull in. 
832  
833### Tagging Your Releases ### 
834  
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this: 
836  
837    $ git tag -s v1.5 -m 'my signed 1.5 tag' 
838    You need a passphrase to unlock the secret key for 
839    user: "Scott Chacon <schacon@gmail.com>" 
840    1024-bit DSA key, ID F721C45A, created 2009-02-09 
841  
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: 
843  
844    $ gpg --list-keys 
845    /Users/schacon/.gnupg/pubring.gpg 
846    --------------------------------- 
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09] 
848    uid                  Scott Chacon <schacon@gmail.com> 
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09] 
850  
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: 
852  
853    $ gpg -a --export F721C45A | git hash-object -w --stdin 
854    659ef797d181633c87ec71ac3f9ba29fe5775b92 
855  
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: 
857  
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 
859  
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: 
861  
862    $ git show maintainer-pgp-pub | gpg --import 
863  
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification. 
865  
866### Generating a Build Number ### 
867  
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing: 
869  
870    $ git describe master 
871    v1.6.2-rc1-20-g8c5b85c 
872  
873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name. 
874  
875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. 
876  
877### Preparing a Release ### 
878  
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`: 
880  
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz 
882    $ ls *.tar.gz 
883    v1.6.2-rc1-20-g8c5b85c.tar.gz 
884  
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: 
886  
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip 
888  
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. 
890  
891### The Shortlog ### 
892  
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: 
894  
895    $ git shortlog --no-merges master --not v1.0.1 
896    Chris Wanstrath (8): 
897          Add support for annotated tags to Grit::Tag 
898          Add packed-refs annotated tag support. 
899          Add Grit::Commit#to_patch 
900          Update version and History.txt 
901          Remove stray `puts` 
902          Make ls_tree ignore nils 
903  
904    Tom Preston-Werner (4): 
905          fix dates in history 
906          dynamic version method 
907          Version bump to 1.0.2 
908          Regenerated gemspec for version 1.0.2 
909  
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. 
911  
912## Summary ## 
913  
914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master. 
915 61 
-
- diff --git a/book/05-distributed-git/sections/diff-maintaining.htm b/book/05-distributed-git/sections/diff-maintaining.htm deleted file mode 100644 index a25a869b..00000000 --- a/book/05-distributed-git/sections/diff-maintaining.htm +++ /dev/null @@ -1,4375 +0,0 @@ - - - - -WinMerge File Compare Report - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
C:\Users\15625\Documents\Git\progit\en\05-distributed-git\01-chapter5.markdownC:\Users\15625\Documents\Git\progit2-ja\book\05-distributed-git\sections\maintaining.asc
.1# Distributed Git # 
2  
3Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you. 
4  
5In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. 
6  
7## Distributed Workflows ## 
8  
9Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub — that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. 
10  
11### Centralized Workflow ### 
12  
13In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). 
14  
15Insert 18333fig0501.png 
16Figure 5-1. Centralized workflow. 
17  
18This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. 
19  
20If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. 
21This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with. 
22  
23### Integration-Manager Workflow ### 
24  
25Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follows (see Figure 5-2): 
26  
271. The project maintainer pushes to their public repository. 
282. A contributor clones that repository and makes changes. 
293. The contributor pushes to their own public copy. 
304. The contributor sends the maintainer an e-mail asking them to pull changes. 
315. The maintainer adds the contributor’s repo as a remote and merges locally. 
326. The maintainer pushes merged changes to the main repository. 
33  
34Insert 18333fig0502.png 
35Figure 5-2. Integration-manager workflow. 
36  
37This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. 
38  
39### Dictator and Lieutenants Workflow ### 
40  
41This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3): 
42  
431. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator. 
442. Lieutenants merge the developers’ topic branches into their master branch. 
453. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 
464. The dictator pushes their master to the reference repository so the other developers can rebase on it. 
47  
48Insert 18333fig0503.png 
49Figure 5-3. Benevolent dictator workflow. 
50  
51This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. 
52  
53These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. 
54  
55## Contributing to a Project ## 
56  
57You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. 
58  
59The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method. 
60  
61The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid? 
62  
63The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? 
64  
65The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? 
66  
67All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. 
68  
69### Commit Guidelines ### 
70  
71Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches — you can read it in the Git source code in the `Documentation/SubmittingPatches` file. 
72  
73First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this — before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: 
74  
75    $ git diff --check 
76    lib/simplegit.rb:5: trailing whitespace. 
77    +    @git_dir = File.expand_path(git_dir)XX 
78    lib/simplegit.rb:7: trailing whitespace. 
79    + XXXXXXXXXXX 
80    lib/simplegit.rb:26: trailing whitespace. 
81    +    def command(git_cmd)XXXX 
82  
83If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers. 
84  
85Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible — don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files — use these tools to help craft a clean and understandable history. 
86  
87The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." 
88Here is a template originally written by Tim Pope at tpope.net: 
89  
90    Short (50 chars or less) summary of changes 
91  
92    More detailed explanatory text, if necessary.  Wrap it to about 72 
93    characters or so.  In some contexts, the first line is treated as the 
94    subject of an email and the rest of the text as the body.  The blank 
95    line separating the summary from the body is critical (unless you omit 
96    the body entirely); tools like rebase can get confused if you run the 
97    two together. 
98  
99    Further paragraphs come after blank lines. 
100  
101     - Bullet points are okay, too 
102  
103     - Typically a hyphen or asterisk is used for the bullet, preceded by a 
104       single space, with blank lines in between, but conventions vary here 
105  
106If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages — I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like. 
107  
108In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do. 
109  
110### Private Small Team ### 
111  
112The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source — not read-accessible to the outside world. You and the other developers all have push access to the repository. 
113  
114In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. 
115Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.) 
116  
117    # John's Machine 
118    $ git clone john@githost:simplegit.git 
119    Initialized empty Git repository in /home/john/simplegit/.git/ 
120    ... 
121    $ cd simplegit/ 
122    $ vim lib/simplegit.rb 
123    $ git commit -am 'removed invalid default value' 
124    [master 738ee87] removed invalid default value 
125     1 files changed, 1 insertions(+), 1 deletions(-) 
126  
127The second developer, Jessica, does the same thing — clones the repository and commits a change: 
128  
129    # Jessica's Machine 
130    $ git clone jessica@githost:simplegit.git 
131    Initialized empty Git repository in /home/jessica/simplegit/.git/ 
132    ... 
133    $ cd simplegit/ 
134    $ vim TODO 
135    $ git commit -am 'add reset task' 
136    [master fbff5bc] add reset task 
137     1 files changed, 1 insertions(+), 0 deletions(-) 
138  
139Now, Jessica pushes her work up to the server: 
140  
141    # Jessica's Machine 
142    $ git push origin master 
143    ... 
144    To jessica@githost:simplegit.git 
145       1edee6b..fbff5bc  master -> master 
146  
147John tries to push his change up, too: 
148  
149    # John's Machine 
150    $ git push origin master 
151    To john@githost:simplegit.git 
152     ! [rejected]        master -> master (non-fast forward) 
153    error: failed to push some refs to 'john@githost:simplegit.git' 
154  
155John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push: 
156  
157    $ git fetch origin 
158    ... 
159    From john@githost:simplegit 
160     + 049d078...fbff5bc master     -> origin/master 
161  
162At this point, John’s local repository looks something like Figure 5-4. 
163  
164Insert 18333fig0504.png 
165Figure 5-4. John’s initial repository. 
166  
167John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: 
168  
169    $ git merge origin/master 
170    Merge made by recursive. 
171     TODO |    1 + 
172     1 files changed, 1 insertions(+), 0 deletions(-) 
173  
174The merge goes smoothly — John’s commit history now looks like Figure 5-5. 
175  
176Insert 18333fig0505.png 
177Figure 5-5. John’s repository after merging `origin/master`. 
178  
179Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: 
180  
181    $ git push origin master 
182    ... 
183    To john@githost:simplegit.git 
184       fbff5bc..72bbc59  master -> master 
185  
186Finally, John’s commit history looks like Figure 5-6. 
187  
188Insert 18333fig0506.png 
189Figure 5-6. John’s history after pushing to the origin server. 
190  
191In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. 
192  
193Insert 18333fig0507.png 
194Figure 5-7. Jessica’s initial commit history. 
195  
196Jessica wants to sync up with John, so she fetches: 
197  
198    # Jessica's Machine 
199    $ git fetch origin 
200    ... 
201    From jessica@githost:simplegit 
202       fbff5bc..72bbc59  master     -> origin/master 
203  
204That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. 
205  
206Insert 18333fig0508.png 
207Figure 5-8. Jessica’s history after fetching John’s changes. 
208  
209Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: 
210  
211    $ git log --no-merges origin/master ^issue54 
212    commit 738ee872852dfaa9d6634e0dea7a324040193016 
213    Author: John Smith <jsmith@example.com> 
214    Date:   Fri May 29 16:01:27 2009 -0700 
215  
216        removed invalid default value 
217  
218Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work: 
219  
220    $ git checkout master 
221    Switched to branch "master" 
222    Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. 
223  
224She can merge either `origin/master` or `issue54` first — they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: 
225  
226    $ git merge issue54 
227    Updating fbff5bc..4af4298 
228    Fast forward 
229     README           |    1 + 
230     lib/simplegit.rb |    6 +++++- 
231     2 files changed, 6 insertions(+), 1 deletions(-) 
232  
233No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`): 
234  
235    $ git merge origin/master 
236    Auto-merging lib/simplegit.rb 
237    Merge made by recursive. 
238     lib/simplegit.rb |    2 +- 
239     1 files changed, 1 insertions(+), 1 deletions(-) 
240  
241Everything merges cleanly, and Jessica’s history looks like Figure 5-9. 
242  
243Insert 18333fig0509.png 
244Figure 5-9. Jessica’s history after merging John’s changes. 
245  
246Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): 
247  
248    $ git push origin master 
249    ... 
250    To jessica@githost:simplegit.git 
251       72bbc59..8059c15  master -> master 
252  
253Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. 
254  
255Insert 18333fig0510.png 
256Figure 5-10. Jessica’s history after pushing all changes back to the server. 
257  
258That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. 
259  
260Insert 18333fig0511.png 
261Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. 
262  
263### Private Managed Team ### 
264  
265In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. 
266  
267Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. 
268  
269Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: 
270  
271    # Jessica's Machine 
272    $ git checkout -b featureA 
273    Switched to a new branch "featureA" 
274    $ vim lib/simplegit.rb 
275    $ git commit -am 'add limit to log function' 
276    [featureA 3300904] add limit to log function 
277     1 files changed, 1 insertions(+), 1 deletions(-) 
278  
279At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch — only the integrators do — so she has to push to another branch in order to collaborate with John: 
280  
281    $ git push origin featureA 
282    ... 
283    To jessica@githost:simplegit.git 
284     * [new branch]      featureA -> featureA 
285  
286Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch: 
287  
288    # Jessica's Machine 
289    $ git fetch origin 
290    $ git checkout -b featureB origin/master 
291    Switched to a new branch "featureB" 
292  
293Now, Jessica makes a couple of commits on the `featureB` branch: 
294  
295    $ vim lib/simplegit.rb 
296    $ git commit -am 'made the ls-tree function recursive' 
297    [featureB e5b0fdc] made the ls-tree function recursive 
298     1 files changed, 1 insertions(+), 1 deletions(-) 
299    $ vim lib/simplegit.rb 
300    $ git commit -am 'add ls-files' 
301    [featureB 8512791] add ls-files 
302     1 files changed, 5 insertions(+), 0 deletions(-) 
303  
304Jessica’s repository looks like Figure 5-12. 
305  
306Insert 18333fig0512.png 
307Figure 5-12. Jessica’s initial commit history. 
308  
309She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: 
310  
311    $ git fetch origin 
312    ... 
313    From jessica@githost:simplegit 
314     * [new branch]      featureBee -> origin/featureBee 
315  
316Jessica can now merge this into the work she did with `git merge`: 
317  
318    $ git merge origin/featureBee 
319    Auto-merging lib/simplegit.rb 
320    Merge made by recursive. 
321     lib/simplegit.rb |    4 ++++ 
322     1 files changed, 4 insertions(+), 0 deletions(-) 
323  
324There is a bit of a problem — she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: 
325  
326    $ git push origin featureB:featureBee 
327    ... 
328    To jessica@githost:simplegit.git 
329       fba9af8..cd685d1  featureB -> featureBee 
330  
331This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. 
332  
333Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: 
334  
335    $ git fetch origin 
336    ... 
337    From jessica@githost:simplegit 
338       3300904..aad881d  featureA   -> origin/featureA 
339  
340Then, she can see what has been changed with `git log`: 
341  
342    $ git log origin/featureA ^featureA 
343    commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 
344    Author: John Smith <jsmith@example.com> 
345    Date:   Fri May 29 19:57:33 2009 -0700 
346  
347        changed log output to 30 from 25 
348  
349Finally, she merges John’s work into her own `featureA` branch: 
350  
351    $ git checkout featureA 
352    Switched to branch "featureA" 
353    $ git merge origin/featureA 
354    Updating 3300904..aad881d 
355    Fast forward 
356     lib/simplegit.rb |   10 +++++++++- 
357    1 files changed, 9 insertions(+), 1 deletions(-) 
358  
359Jessica wants to tweak something, so she commits again and then pushes this back up to the server: 
360  
361    $ git commit -am 'small tweak' 
362    [featureA 774b3ed] small tweak 
363     1 files changed, 1 insertions(+), 1 deletions(-) 
364    $ git push origin featureA 
365    ... 
366    To jessica@githost:simplegit.git 
367       3300904..774b3ed  featureA -> featureA 
368  
369Jessica’s commit history now looks something like Figure 5-13. 
370  
371Insert 18333fig0513.png 
372Figure 5-13. Jessica’s history after committing on a feature branch. 
373  
374Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. 
375  
376Insert 18333fig0514.png 
377Figure 5-14. Jessica’s history after merging both her topic branches. 
378  
379Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. 
380  
381Insert 18333fig0515.png 
382Figure 5-15. Basic sequence of this managed-team workflow. 
383  
384### Public Small Project ### 
385  
386Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. 
387  
388First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this: 
389  
390    $ git clone (url) 
391    $ cd project 
392    $ git checkout -b featureA 
393    $ (work) 
394    $ git commit 
395    $ (work) 
396    $ git commit 
397  
398You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review — see Chapter 6 for more information about interactive rebasing. 
399  
400When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: 
401  
402    $ git remote add myfork (url) 
403  
404You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow: 
405  
406    $ git push myfork featureA 
407  
408When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website — GitHub has a "pull request" button that automatically messages the maintainer — or run the `git request-pull` command and e-mail the output to the project maintainer manually. 
409  
410The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this: 
411  
412    $ git request-pull origin/master myfork 
413    The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: 
414      John Smith (1): 
415            added a new function 
416  
417    are available in the git repository at: 
418  
419      git://githost/simplegit.git featureA 
420  
421    Jessica Smith (2): 
422          add limit to log function 
423          change log output to 30 from 25 
424  
425     lib/simplegit.rb |   10 +++++++++- 
426     1 files changed, 9 insertions(+), 1 deletions(-) 
427  
428The output can be sent to the maintainer—it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. 
429  
430On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected.  Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up — start over from the main repository’s `master` branch: 
431  
432    $ git checkout -b featureB origin/master 
433    $ (work) 
434    $ git commit 
435    $ git push myfork featureB 
436    $ (email maintainer) 
437    $ git fetch origin 
438  
439Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. 
440  
441Insert 18333fig0516.png 
442Figure 5-16. Initial commit history with featureB work. 
443  
444Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: 
445  
446    $ git checkout featureA 
447    $ git rebase origin/master 
448    $ git push -f myfork featureA 
449  
450This rewrites your history to now look like Figure 5-17. 
451  
452Insert 18333fig0517.png 
453Figure 5-17. Commit history after featureA work. 
454  
455Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). 
456  
457Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: 
458  
459    $ git checkout -b featureBv2 origin/master 
460    $ git merge --no-commit --squash featureB 
461    $ (change implementation) 
462    $ git commit 
463    $ git push myfork featureBv2 
464  
465The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. 
466  
467Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). 
468  
469Insert 18333fig0518.png 
470Figure 5-18. Commit history after featureBv2 work. 
471  
472### Public Large Project ### 
473  
474Many larger projects have established procedures for accepting patches — you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now. 
475  
476The workflow is similar to the previous use case — you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: 
477  
478    $ git checkout -b topicA 
479    $ (work) 
480    $ git commit 
481    $ (work) 
482    $ git commit 
483  
484Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list — it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: 
485  
486    $ git format-patch -M origin/master 
487    0001-add-limit-to-log-function.patch 
488    0002-changed-log-output-to-30-from-25.patch 
489  
490The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: 
491  
492    $ cat 0001-add-limit-to-log-function.patch 
493    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 
494    From: Jessica Smith <jessica@example.com> 
495    Date: Sun, 6 Apr 2008 10:17:23 -0700 
496    Subject: [PATCH 1/2] add limit to log function 
497  
498    Limit log functionality to the first 20 
499  
500    --- 
501     lib/simplegit.rb |    2 +- 
502     1 files changed, 1 insertions(+), 1 deletions(-) 
503  
504    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
505    index 76f47bc..f9815f1 100644 
506    --- a/lib/simplegit.rb 
507    +++ b/lib/simplegit.rb 
508    @@ -14,7 +14,7 @@ class SimpleGit 
509       end 
510  
511       def log(treeish = 'master') 
512    -    command("git log #{treeish}") 
513    +    command("git log -n 20 #{treeish}") 
514       end 
515  
516       def ls_tree(treeish = 'master') 
517    -- 
518    1.6.2.rc1.20.g8c5b.dirty 
519  
520You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. 
521  
522To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. 
523  
524First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this: 
525  
526    [imap] 
527      folder = "[Gmail]/Drafts" 
528      host = imaps://imap.gmail.com 
529      user = user@gmail.com 
530      pass = p4ssw0rd 
531      port = 993 
532      sslverify = false 
533  
534If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`. 
535When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: 
536  
537    $ cat *.patch |git imap-send 
538    Resolving imap.gmail.com... ok 
539    Connecting to [74.125.142.109]:993... ok 
540    Logging in... 
541    sending 2 messages 
542    100% (2/2) done 
543  
544At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. 
545  
546You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: 
547  
548    [sendemail] 
549      smtpencryption = tls 
550      smtpserver = smtp.gmail.com 
551      smtpuser = user@gmail.com 
552      smtpserverport = 587 
553  
554After this is done, you can use `git send-email` to send your patches: 
555  
556    $ git send-email *.patch 
557    0001-added-limit-to-log-function.patch 
558    0002-changed-log-output-to-30-from-25.patch 
559    Who should the emails appear to be from? [Jessica Smith <jessica@example.com>] 
560    Emails will be sent from: Jessica Smith <jessica@example.com> 
561    Who should the emails be sent to? jessica@example.com 
562    Message-ID to be used as In-Reply-To for the first email? y 
563  
564Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: 
565  
566    (mbox) Adding cc: Jessica Smith <jessica@example.com> from 
567      \line 'From: Jessica Smith <jessica@example.com>' 
568    OK. Log says: 
569    Sendmail: /usr/sbin/sendmail -i jessica@example.com 
570    From: Jessica Smith <jessica@example.com> 
571    To: jessica@example.com 
572    Subject: [PATCH 1/2] added limit to log function 
573    Date: Sat, 30 May 2009 13:29:15 -0700 
574    Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> 
575    X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty 
576    In-Reply-To: <y> 
577    References: <y> 
578  
579    Result: OK 
580  
581### Summary ### 
582  
583This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager. 
584  
585## Maintaining a Project ## 1=== Maintaining a Project 
586 2 
. 3(((maintaining a project)))
587In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run.4In addition to knowing how to effectively contribute to a project, you'll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you've added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run.
588 5 
.589### Working in Topic Branches ### 6==== Working in Topic Branches 
590 7 
. 8(((branches, topic)))
591When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well such as `sc/ruby_client`, where `sc` is short for the person who contributed the work.9When you're thinking of integrating new work, it's generally a good idea to try it out in a topic branch a temporary branch specifically made to try out that new work. This way, it's easy to tweak a patch individually and leave it if it's not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you're going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well such as `sc/ruby_client`, where `sc` is short for the person who contributed the work.
592As you’ll remember, you can create the branch based off your master branch like this:10As you'll remember, you can create the branch based off your master branch like this:
593 11 
. 12[source,console]
 13-----
594    $ git branch sc/ruby_client master14$ git branch sc/ruby_client master
 15-----
595 16 
.596Or, if you want to also switch to it immediately, you can use the `checkout -b` command:17Or, if you want to also switch to it immediately, you can use the `checkout -b` option:
597 18 
. 19[source,console]
 20-----
598    $ git checkout -b sc/ruby_client master21$ git checkout -b sc/ruby_client master
 22-----
599 23 
.600Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches.24Now you're ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches.
601 25 
. 26[[_patches_from_email]]
602### Applying Patches from E-mail ### 27==== Applying Patches from E-mail 
603 28 
. 29(((email, applying patches from)))
604If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`.30If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`.
605 31 
.606#### Applying a Patch with apply #### 32===== Applying a Patch with apply 
607 33 
. 34(((git commands, apply)))
608If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this:35If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command (which is not recommended; see the next section), you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this:
609 36 
. 37[source,console]
 38-----
610    $ git apply /tmp/patch-ruby-client.patch39$ git apply /tmp/patch-ruby-client.patch
 40-----
611 41 
.612This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you after running it, you must stage and commit the changes introduced manually.42This modifies the files in your working directory. It's almost identical to running a `patch -p1` command to apply the patch, although it's more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they're described in the `git diff` format, which `patch` won't do. Finally, `git apply` is an ``apply all or abort all'' model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more conservative than `patch`. It won't create a commit for you after running it, you must stage and commit the changes introduced manually.
613 43 
.614You can also use `git apply` to see if a patch applies cleanly before you try actually applying it you can run `git apply --check` with the patch:44You can also use git apply to see if a patch applies cleanly before you try actually applying it you can run `git apply --check` with the patch:
615 45 
. 46[source,console]
 47-----
616    $ git apply --check 0001-seeing-if-this-helps-the-gem.patch48$ git apply --check 0001-seeing-if-this-helps-the-gem.patch
617    error: patch failed: ticgit.gemspec:149error: patch failed: ticgit.gemspec:1
618    error: ticgit.gemspec: patch does not apply50error: ticgit.gemspec: patch does not apply
 51-----
619 52 
620If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want.53If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want.
621 54 
. 55[[_git_am]]
622#### Applying a Patch with am #### 56===== Applying a Patch with `am` 
623 57 
. 58(((git commands, am)))
624If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that.59If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that.
625 60 
626To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this:61To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this:
627 62 
. 63[source,console]
 64-----
628    From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 200165From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
629    From: Jessica Smith <jessica@example.com>66From: Jessica Smith <jessica@example.com>
630    Date: Sun, 6 Apr 2008 10:17:23 -070067Date: Sun, 6 Apr 2008 10:17:23 -0700
631    Subject: [PATCH 1/2] add limit to log function68Subject: [PATCH 1/2] add limit to log function
632 69 
.633    Limit log functionality to the first 2070Limit log functionality to the first 20
 71-----
634 72 
.635This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using `git send-email`, and you download that into an mbox format, then you can point `git am` to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use `git am` to apply them one at a time.73This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time.
636 74 
637However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it:75However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it:
638 76 
. 77[source,console]
 78-----
639    $ git am 0001-limit-log-function.patch79$ git am 0001-limit-log-function.patch
640    Applying: add limit to log function80Applying: add limit to log function
 81-----
641 82 
.642You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this:83You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail's `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example above, the commit generated would look something like this:
643 84 
. 85-----
644    $ git log --pretty=fuller -186$ git log --pretty=fuller -1
645    commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e087commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
646    Author:     Jessica Smith <jessica@example.com>88Author:     Jessica Smith <jessica@example.com>
647    AuthorDate: Sun Apr 6 10:17:23 2008 -070089AuthorDate: Sun Apr 6 10:17:23 2008 -0700
648    Commit:     Scott Chacon <schacon@gmail.com>90Commit:     Scott Chacon <schacon@gmail.com>
649    CommitDate: Thu Apr 9 09:19:06 2009 -070091CommitDate: Thu Apr 9 09:19:06 2009 -0700
650 92 
.651       add limit to log function93   add limit to log function
652 94 
.653       Limit log functionality to the first 2095   Limit log functionality to the first 20
 96-----
654 97 
655The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created.98The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created.
656 99 
.657But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do:100But it's possible that the patch won't apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven't applied yet. In that case, the `git am` process will fail and ask you what you want to do:
658 101 
. 102[source,console]
 103-----
659    $ git am 0001-seeing-if-this-helps-the-gem.patch104$ git am 0001-seeing-if-this-helps-the-gem.patch
660    Applying: seeing if this helps the gem105Applying: seeing if this helps the gem
661    error: patch failed: ticgit.gemspec:1106error: patch failed: ticgit.gemspec:1
662    error: ticgit.gemspec: patch does not apply107error: ticgit.gemspec: patch does not apply
663    Patch failed at 0001.108Patch failed at 0001.
664    When you have resolved this problem run "git am --resolved".109When you have resolved this problem run "git am --resolved".
665    If you would prefer to skip this patch, instead run "git am --skip".110If you would prefer to skip this patch, instead run "git am --skip".
666    To restore the original branch and stop patching run "git am --abort".111To restore the original branch and stop patching run "git am --abort".
 112-----
667 113 
.668This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch:114This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch:
669 115 
. 116[source,console]
 117-----
670    $ (fix the file)118$ (fix the file)
671    $ git add ticgit.gemspec119$ git add ticgit.gemspec
672    $ git am --resolved120$ git am --resolved
673    Applying: seeing if this helps the gem121Applying: seeing if this helps the gem
 122-----
674 123 
.675If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit if the patch was based on a public commit then the `-3` option is generally much smarter about applying a conflicting patch:124If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn't on by default because it doesn't work if the commit the patch says it was based on isn't in your repository. If you do have that commit if the patch was based on a public commit then the `-3` option is generally much smarter about applying a conflicting patch:
676 125 
. 126[source,console]
 127-----
677    $ git am -3 0001-seeing-if-this-helps-the-gem.patch128$ git am -3 0001-seeing-if-this-helps-the-gem.patch
678    Applying: seeing if this helps the gem129Applying: seeing if this helps the gem
679    error: patch failed: ticgit.gemspec:1130error: patch failed: ticgit.gemspec:1
680    error: ticgit.gemspec: patch does not apply131error: ticgit.gemspec: patch does not apply
681    Using index info to reconstruct a base tree...132Using index info to reconstruct a base tree...
682    Falling back to patching base and 3-way merge...133Falling back to patching base and 3-way merge...
683    No changes -- Patch already applied.134No changes -- Patch already applied.
 135-----
684 136 
.685In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict.137In this case, this patch had already been applied. Without the `-3` option, it looks like a conflict.
686 138 
.687If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it:139If you're applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it:
688 140 
. 141[source,console]
 142-----
689    $ git am -3 -i mbox143$ git am -3 -i mbox
690    Commit Body is:144Commit Body is:
691    --------------------------145--------------------------
692    seeing if this helps the gem146seeing if this helps the gem
693    --------------------------147--------------------------
694    Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all148Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all
 149-----
695 150 
.696This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so.151This is nice if you have a number of patches saved, because you can view the patch first if you don't remember what it is, or not apply the patch if you've already done so.
697 152 
698When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch.153When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch.
699 154 
. 155[[_checking_out_remotes]]
700### Checking Out Remote Branches ### 156==== Checking Out Remote Branches 
701 157 
. 158(((branches, remote)))
702If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally.159If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally.
703 160 
704For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally:161For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally:
705 162 
. 163[source,console]
 164-----
706    $ git remote add jessica git://github.com/jessica/myproject.git165$ git remote add jessica git://github.com/jessica/myproject.git
707    $ git fetch jessica166$ git fetch jessica
708    $ git checkout -b rubyclient jessica/ruby-client167$ git checkout -b rubyclient jessica/ruby-client
 168-----
709 169 
710If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup.170If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup.
711 171 
.712This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier it depends largely on how you develop and how your contributors develop.172This is most useful if you're working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You're also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier it depends largely on how you develop and how your contributors develop.
713 173 
714The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access.174The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access.
715 175 
.716If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference:176If you aren't working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn't save the URL as a remote reference:
717 177 
. 178[source,console]
 179-----
718    $ git pull git://github.com/onetimeguy/project.git180$ git pull https://github.com/onetimeguy/project
719    From git://github.com/onetimeguy/project181From https://github.com/onetimeguy/project
720     * branch            HEAD       -> FETCH_HEAD182 * branch            HEAD       -> FETCH_HEAD
721    Merge made by recursive.183Merge made by recursive.
 184-----
722 185 
. 186[[_what_is_introduced]]
723### Determining What Is Introduced ### 187==== Determining What Is Introduced 
724 188 
. 189(((branches, diffing)))
725Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch.190Now you have a topic branch that contains contributed work. At this point, you can determine what you'd like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you'll be introducing if you merge this into your main branch.
726 191 
.727It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this:192It's often helpful to get a review of all the commits that are in this branch but that aren't in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. This does the same thing as the `master..contrib` format that we used earlier. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this:
728 193 
. 194[source,console]
 195-----
729    $ git log contrib --not master196$ git log contrib --not master
730    commit 5b6235bd297351589efc4d73316f0a68d484f118197commit 5b6235bd297351589efc4d73316f0a68d484f118
731    Author: Scott Chacon <schacon@gmail.com>198Author: Scott Chacon <schacon@gmail.com>
732    Date:   Fri Oct 24 09:53:59 2008 -0700199Date:   Fri Oct 24 09:53:59 2008 -0700
733 200 
.734        seeing if this helps the gem201    seeing if this helps the gem
735 202 
.736    commit 7482e0d16d04bea79d0dba8988cc78df655f16a0203commit 7482e0d16d04bea79d0dba8988cc78df655f16a0
737    Author: Scott Chacon <schacon@gmail.com>204Author: Scott Chacon <schacon@gmail.com>
738    Date:   Mon Oct 22 19:38:36 2008 -0700205Date:   Mon Oct 22 19:38:36 2008 -0700
739 206 
.740        updated the gemspec to hopefully work better207    updated the gemspec to hopefully work better
 208-----
741 209 
742To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit.210To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit.
743 211 
744To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this:212To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this:
745 213 
. 214[source,console]
 215-----
746    $ git diff master216$ git diff master
 217-----
747 218 
. 219This command gives you a diff, but it may be misleading.
748This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line.220If your `master` branch has moved forward since you created the topic branch from it, then you'll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you're on and the snapshot of the last commit on the `master` branch. For example, if you've added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line.
749 221 
.750If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch.222If `master` is a direct ancestor of your topic branch, this isn't a problem; but if the two histories have diverged, the diff will look like you're adding all the new stuff in your topic branch and removing everything unique to the `master` branch.
751 223 
.752What you really want to see are the changes added to the topic branch the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch.224What you really want to see are the changes added to the topic branch the work you'll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch.
753 225 
754Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it:226Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it:
755 227 
. 228[source,console]
 229-----
756    $ git merge-base contrib master230$ git merge-base contrib master
757    36c7dba2c95e6bbb78dfa822519ecfec6e1ca64923136c7dba2c95e6bbb78dfa822519ecfec6e1ca649
758    $ git diff 36c7db232$ git diff 36c7db
 233-----
759 234 
.760However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch:235However, that isn't convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you're on and its common ancestor with another branch:
761 236 
. 237[source,console]
 238-----
762    $ git diff master...contrib239$ git diff master...contrib
 240-----
763 241 
764This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember.242This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember.
765 243 
.766### Integrating Contributed Work ### 244==== Integrating Contributed Work 
767 245 
. 246(((integrating work)))
768When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them.247When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so we'll cover a few of them.
769 248 
.770#### Merging Workflows #### 249===== Merging Workflows 
771 250 
. 251(((workflows, merging)))
772One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process.  If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20.252One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you've done or that someone has contributed and you've verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like <<merwf_a>> and merge `ruby_client` first and then `php_client` next, then your history will end up looking like <<merwf_b>>.
773 253 
.774Insert 18333fig0519.png 
775Figure 5-19. History with several topic branches. 
 254[[merwf_a]]
 255.History with several topic branches.
 256image::images/merging-workflows-1.png[History with several topic branches.]
776 257 
.777Insert 18333fig0520.png 
778Figure 5-20. After a topic branch merge. 
 258[[merwf_b]]
 259.After a topic branch merge.
 260image::images/merging-workflows-2.png[After a topic branch merge.]
779 261 
.780That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects.262That is probably the simplest workflow, but it can possibly be problematic if you're dealing with larger or more stable projects where you want to be really careful about what you introduce.
781 263 
.782If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23).264If you have a more important project, you might want to use a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (<<merwf_c>>), you merge it into `develop` (<<merwf_d>>); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (<<merwf_e>>).
783 265 
.784Insert 18333fig0521.png 
785Figure 5-21. Before a topic branch merge. 
 266[[merwf_c]]
 267.Before a topic branch merge.
 268image::images/merging-workflows-3.png[Before a topic branch merge.]
786 269 
.787Insert 18333fig0522.png 
788Figure 5-22. After a topic branch merge. 
 270[[merwf_d]]
 271.After a topic branch merge.
 272image::images/merging-workflows-4.png[After a topic branch merge.]
789 273 
.790Insert 18333fig0523.png 
791Figure 5-23. After a topic branch release. 
 274[[merwf_e]]
 275.After a project release.
 276image::images/merging-workflows-5.png[After a topic branch release.]
792 277 
.793This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff.278This way, when people clone your project's repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff.
794You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch.279You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch.
795 280 
.796#### Large-Merging Workflows #### 281===== Large-Merging Workflows 
797 282 
. 283(((workflows, "merging (large)")))
798The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together.284The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it's collected into topic branches in the maintainer's repository in a manner similar to what we've described (see <<merwf_f>>). At this point, the topics are evaluated to determine whether they're safe and ready for consumption or whether they need more work. If they're safe, they're merged into `next`, and that branch is pushed up so everyone can try the topics integrated together.
799 285 
.800Insert 18333fig0524.png 
801Figure 5-24. Managing a complex series of parallel contributed topic branches. 
 286[[merwf_f]]
 287.Managing a complex series of parallel contributed topic branches.
 288image::images/large-merges-1.png[Managing a complex series of parallel contributed topic branches.]
802 289 
.803If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). 290If the topics still need work, they're merged into `pu` instead. When it's determined that they're totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn't yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often: 
804 291 
.805Insert 18333fig0525.png 
806Figure 5-25. Merging contributed topic branches into long-term integration branches. 
 292.Merging contributed topic branches into long-term integration branches.
 293image::images/large-merges-2.png[Merging contributed topic branches into long-term integration branches.]
807 294 
.808When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. 295When a topic branch has finally been merged into `master`, it's removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions.  
809 296 
. 297[[_rebase_cherry_pick]]
810#### Rebasing and Cherry Picking Workflows #### 298===== Rebasing and Cherry Picking Workflows 
811 299 
. 300(((workflows, rebasing and cherry-picking)))
812Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history.301Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you'll end up with a linear project history.
813 302 
. 303(((git commands, cherry-pick)))
814The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. 304The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you're currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you'd prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like this: 
815 305 
.816Insert 18333fig0526.png 
817Figure 5-26. Example history before a cherry pick. 
 306.Example history before a cherry-pick.
 307image::images/rebasing-1.png[Example history before a cherry-pick.]
818 308 
819If you want to pull commit `e43a6` into your master branch, you can run309If you want to pull commit `e43a6` into your master branch, you can run
820 310 
. 311[source,console]
 312-----
821    $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf313$ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf
822    Finished one cherry-pick.314Finished one cherry-pick.
823    [master]: created a0a41a9: "More friendly message when locking the index fails."315[master]: created a0a41a9: "More friendly message when locking the index fails."
824     3 files changed, 17 insertions(+), 3 deletions(-)316 3 files changed, 17 insertions(+), 3 deletions(-)
 317-----
825 318 
.826This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. 319This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like this: 
827 320 
.828Insert 18333fig0527.png 
829Figure 5-27. History after cherry-picking a commit on a topic branch. 
 321.History after cherry-picking a commit on a topic branch.
 322image::images/rebasing-2.png[History after cherry-picking a commit on a topic branch.]
830 323 
.831Now you can remove your topic branch and drop the commits you didn’t want to pull in.324Now you can remove your topic branch and drop the commits you didn't want to pull in.
832 325 
. 326===== Rerere
 327 
 328(((git commands, rerere)))(((rerere)))
 329If you're doing lots of merging and rebasing, or you're maintaining a long-lived topic branch, Git has a feature called ``rerere'' that can help.
 330 
 331Rerere stands for ``reuse recorded resolution'' – it's a way of shortcutting manual conflict resolution.
 332When rerere is enabled, Git will keep a set of pre- and post-images from successful merges, and if it notices that there's a conflict that looks exactly like one you've already fixed, it'll just use the fix from last time, without bothering you with it.
 333 
 334This feature comes in two parts: a configuration setting and a command.
 335The configuration setting is `rerere.enabled`, and it's handy enough to put in your global config:
 336 
 337[source,console]
 338----
 339$ git config --global rerere.enabled true
 340----
 341 
 342Now, whenever you do a merge that resolves conflicts, the resolution will be recorded in the cache in case you need it in the future.
 343 
 344If you need to, you can interact with the rerere cache using the `git rerere` command.
 345When it's invoked alone, Git checks its database of resolutions and tries to find a match with any current merge conflicts and resolve them (although this is done automatically if `rerere.enabled` is set to `true`).
 346There are also subcommands to see what will be recorded, to erase specific resolution from the cache, and to clear the entire cache. We will cover rerere in more detail in <<_rerere>>.
 347 
 348[[_tagging_releases]]
833### Tagging Your Releases ### 349==== Tagging Your Releases 
834 350 
. 351(((tags)))(((tags, signing)))
835When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this:352When you've decided to cut a release, you'll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as discussed in <<_git_basics_chapter>>. If you decide to sign the tag as the maintainer, the tagging may look something like this:
836 353 
. 354[source,console]
 355-----
837    $ git tag -s v1.5 -m 'my signed 1.5 tag'356$ git tag -s v1.5 -m 'my signed 1.5 tag'
838    You need a passphrase to unlock the secret key for357You need a passphrase to unlock the secret key for
839    user: "Scott Chacon <schacon@gmail.com>"358user: "Scott Chacon <schacon@gmail.com>"
840    1024-bit DSA key, ID F721C45A, created 2009-02-093591024-bit DSA key, ID F721C45A, created 2009-02-09
 360-----
841 361 
842If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`:362If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`:
843 363 
. 364[source,console]
 365-----
844    $ gpg --list-keys366$ gpg --list-keys
845    /Users/schacon/.gnupg/pubring.gpg367/Users/schacon/.gnupg/pubring.gpg
846    ---------------------------------368---------------------------------
847    pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09]369pub   1024D/F721C45A 2009-02-09 [expires: 2010-02-09]
848    uid                  Scott Chacon <schacon@gmail.com>370uid                  Scott Chacon <schacon@gmail.com>
849    sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09]371sub   2048g/45D02282 2009-02-09 [expires: 2010-02-09]
 372-----
850 373 
851Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob:374Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob:
852 375 
. 376[source,console]
 377-----
853    $ gpg -a --export F721C45A | git hash-object -w --stdin378$ gpg -a --export F721C45A | git hash-object -w --stdin
854    659ef797d181633c87ec71ac3f9ba29fe5775b92379659ef797d181633c87ec71ac3f9ba29fe5775b92
 380-----
855 381 
856Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you:382Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you:
857 383 
. 384[source,console]
 385-----
858    $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92386$ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92
 387-----
859 388 
860If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG:389If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG:
861 390 
. 391[source,console]
 392-----
862    $ git show maintainer-pgp-pub | gpg --import393$ git show maintainer-pgp-pub | gpg --import
 394-----
863 395 
864They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification.396They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show <tag>` will let you give the end user more specific instructions about tag verification.
865 397 
. 398[[_build_number]]
866### Generating a Build Number ### 399==== Generating a Build Number 
867 400 
. 401(((build numbers)))(((git commands, describe)))
868Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing:402Because Git doesn't have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you're describing:
869 403 
. 404[source,console]
 405-----
870    $ git describe master406$ git describe master
871    v1.6.2-rc1-20-g8c5b85c407v1.6.2-rc1-20-g8c5b85c
 408-----
872 409 
.873This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name.410This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you're describing a commit that you have directly tagged, it gives you the tag name.
874 411 
.875The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated.412The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you're using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated.
876 413 
. 414[[_preparing_release]]
877### Preparing a Release ### 415==== Preparing a Release 
878 416 
. 417(((releasing)))(((git commands, archive)))
879Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`:418Now you want to release a build. One of the things you'll want to do is create an archive of the latest snapshot of your code for those poor souls who don't use Git. The command to do this is `git archive`:
880 419 
. 420[source,console]
 421-----
881    $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz422$ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz
882    $ ls *.tar.gz423$ ls *.tar.gz
883    v1.6.2-rc1-20-g8c5b85c.tar.gz424v1.6.2-rc1-20-g8c5b85c.tar.gz
 425-----
884 426 
885If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`:427If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`:
886 428 
. 429[source,console]
 430-----
887    $ git archive master --prefix='project/' --format=zip > `git describe master`.zip431$ git archive master --prefix='project/' --format=zip > `git describe master`.zip
 432-----
888 433 
889You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people.434You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people.
890 435 
. 436[[_the_shortlog]]
891### The Shortlog ### 437==== The Shortlog 
892 438 
. 439(((git commands, shortlog)))
893It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1:440It's time to e-mail your mailing list of people who want to know what's happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1:
894 441 
. 442[source,console]
 443-----
895    $ git shortlog --no-merges master --not v1.0.1444$ git shortlog --no-merges master --not v1.0.1
896    Chris Wanstrath (8):445Chris Wanstrath (8):
897          Add support for annotated tags to Grit::Tag446      Add support for annotated tags to Grit::Tag
898          Add packed-refs annotated tag support.447      Add packed-refs annotated tag support.
899          Add Grit::Commit#to_patch448      Add Grit::Commit#to_patch
900          Update version and History.txt449      Update version and History.txt
901          Remove stray `puts`450      Remove stray `puts`
902          Make ls_tree ignore nils451      Make ls_tree ignore nils
903 452 
.904    Tom Preston-Werner (4):453Tom Preston-Werner (4):
905          fix dates in history454      fix dates in history
906          dynamic version method455      dynamic version method
907          Version bump to 1.0.2456      Version bump to 1.0.2
908          Regenerated gemspec for version 1.0.2457      Regenerated gemspec for version 1.0.2
 458-----
909 459 
910You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list.460You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list.
.911  
912## Summary ## 
913  
914You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master. 
915 461 
-
- diff --git a/status.json b/status.json index fc15757a..3f5f8987 100644 --- a/status.json +++ b/status.json @@ -45,10 +45,10 @@ "sections/smart-http.asc": 0 }, "05-distributed-git": { - "1-distributed-git.asc": 0, - "sections/contributing.asc": 0, - "sections/distributed-workflows.asc": 0, - "sections/maintaining.asc": 0 + "1-distributed-git.asc": 100, + "sections/contributing.asc": 100, + "sections/distributed-workflows.asc": 100, + "sections/maintaining.asc": 100 }, "06-github": { "1-github.asc": 0, From 78733daf18630264769bb8c74656fa0bddfb37e0 Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Tue, 25 Nov 2014 21:00:47 +0900 Subject: [PATCH 6/6] Fix markup --- book/05-distributed-git/1-distributed-git.asc | 2 +- book/05-distributed-git/sections/maintaining.asc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/book/05-distributed-git/1-distributed-git.asc b/book/05-distributed-git/1-distributed-git.asc index 777072b6..5b27c5e2 100644 --- a/book/05-distributed-git/1-distributed-git.asc +++ b/book/05-distributed-git/1-distributed-git.asc @@ -4,8 +4,8 @@ ////////////////////////// == Git での分散作業 -////////////////////////// (((distributed git))) +////////////////////////// Now that you have a remote Git repository set up as a point for all the developers to share their code, and you're familiar with basic Git commands in a local workflow, you'll look at how to utilize some of the distributed workflows that Git affords you. ////////////////////////// リモート Git リポジトリを用意し、すべての開発者がコードを共有できるようになりました。また、ローカル環境で作業をする際に使う基本的な Git コマンドについても身についたことでしょう。次に、Git を使った分散作業の流れを見ていきましょう。 diff --git a/book/05-distributed-git/sections/maintaining.asc b/book/05-distributed-git/sections/maintaining.asc index 4b898da2..d4997ad4 100644 --- a/book/05-distributed-git/sections/maintaining.asc +++ b/book/05-distributed-git/sections/maintaining.asc @@ -734,8 +734,8 @@ There are also subcommands to see what will be recorded, to erase specific resol ////////////////////////// ==== リリース用のタグ付け -////////////////////////// (((tags)))(((tags, signing))) +////////////////////////// When you've decided to cut a release, you'll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as discussed in <<_git_basics_chapter>>. If you decide to sign the tag as the maintainer, the tagging may look something like this: