From d47981de28d5c09fc8242a4f1fb996f615df62f0 Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Thu, 20 Nov 2014 13:32:43 +0900 Subject: [PATCH 1/8] Translate 1-git-tools.asc --- book/07-git-tools/1-git-tools.asc | 19 + book/07-git-tools/diff-1-git-tools.htm | 4835 ++++++++++++++++++++++++ 2 files changed, 4854 insertions(+) create mode 100644 book/07-git-tools/diff-1-git-tools.htm diff --git a/book/07-git-tools/1-git-tools.asc b/book/07-git-tools/1-git-tools.asc index 073eae5f..229581e3 100644 --- a/book/07-git-tools/1-git-tools.asc +++ b/book/07-git-tools/1-git-tools.asc @@ -1,10 +1,20 @@ [[_git_tools]] +////////////////////////// == Git Tools +////////////////////////// +== Git のさまざまなツール +////////////////////////// By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. +////////////////////////// +Git を使ったソースコード管理のためのリポジトリの管理や保守について、日々使用するコマンドやワークフローの大半を身につけました。 +ファイルの追跡やコミットといった基本的なタスクをこなせるようになっただけではなくステージングエリアの威力もいかせるようになりました。また気軽にトピックブランチを切ってマージする方法も知りました。 +////////////////////////// Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. +////////////////////////// +では、Git の非常に強力な機能の数々をさらに探っていきましょう。日々の作業でこれらを使うことはあまりありませんが、いつかは必要になるかもしれません。 include::sections/revision-selection.asc[] @@ -34,9 +44,18 @@ include::sections/replace.asc[] include::sections/credentials.asc[] +////////////////////////// === Summary +////////////////////////// +=== まとめ +////////////////////////// You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned how to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. +////////////////////////// +さまざまな高度な道具を使い、コミットやステージングエリアをより細やかに操作できる方法をまとめました。 +何か問題が起こったときには、いつ誰がどのコミットでそれを仕込んだのかを容易に見つけられるようになったことでしょう。 +また、プロジェクトの中で別のプロジェクトを使いたくなったときのための方法も紹介しました。 +Git を使った日々のコマンドラインでの作業の大半を、自信を持ってできるようになったことでしょう。 diff --git a/book/07-git-tools/diff-1-git-tools.htm b/book/07-git-tools/diff-1-git-tools.htm new file mode 100644 index 00000000..8e4b5893 --- /dev/null +++ b/book/07-git-tools/diff-1-git-tools.htm @@ -0,0 +1,4835 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\1-git-tools.asc
. 1[[_git_tools]]
 2//////////////////////////
1# Git Tools # 3== Git Tools 
 4//////////////////////////
 5== Git のさまざまなツール
2 6 
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging.7By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging.
4 8 
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point.9Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point.
. 10 
 11include::sections/revision-selection.asc[]
 12 
 13include::sections/interactive-staging.asc[]
 14 
 15include::sections/stashing-cleaning.asc[]
 16 
 17include::sections/signing.asc[]
 18 
 19include::sections/searching.asc[]
 20 
 21include::sections/rewriting-history.asc[]
 22 
 23include::sections/reset.asc[]
 24 
 25include::sections/advanced-merging.asc[]
 26 
 27include::sections/rerere.asc[]
 28 
 29include::sections/debugging.asc[]
 30 
 31include::sections/submodules.asc[]
 32 
 33include::sections/bundling.asc[]
 34 
 35include::sections/replace.asc[]
 36 
6 37include::sections/credentials.asc[] 
7## Revision Selection ## 
8  
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. 
10  
11### Single Revisions ### 
12  
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. 
14  
15### Short SHA ### 
16  
17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. 
18  
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: 
20  
21    $ git log 
22    commit 734713bc047d87bf7eac9674765ae793478c50d3 
23    Author: Scott Chacon <schacon@gmail.com> 
24    Date:   Fri Jan 2 18:32:33 2009 -0800 
25  
26        fixed refs handling, added gc auto, updated tests 
27  
28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
29    Merge: 1c002dd... 35cfb2b... 
30    Author: Scott Chacon <schacon@gmail.com> 
31    Date:   Thu Dec 11 15:08:43 2008 -0800 
32  
33        Merge commit 'phedders/rdocs' 
34  
35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
36    Author: Scott Chacon <schacon@gmail.com> 
37    Date:   Thu Dec 11 14:58:32 2008 -0800 
38  
39        added some blame and merge stuff 
40  
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): 
42  
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
44    $ git show 1c002dd4b536e7479f 
45    $ git show 1c002d 
46  
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: 
48  
49    $ git log --abbrev-commit --pretty=oneline 
50    ca82a6d changed the version number 
51    085bb3b removed unnecessary test code 
52    a11bef0 first commit 
53  
54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 
55  
56### A SHORT NOTE ABOUT SHA-1 ### 
57  
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? 
59  
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. 
61  
62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. 
63  
64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. 
65  
66### Branch References ### 
67  
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: 
69  
70    $ git show ca82a6dff817ec66f44342007202690a93763949 
71    $ git show topic1 
72  
73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. 
74  
75    $ git rev-parse topic1 
76    ca82a6dff817ec66f44342007202690a93763949 
77  
78### RefLog Shortnames ### 
79  
80One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. 
81  
82You can see your reflog by using `git reflog`: 
83  
84    $ git reflog 
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated 
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff 
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 
89    95df984 HEAD@{4}: commit: # This is a combination of two commits. 
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD 
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD 
92  
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: 
94  
95    $ git show HEAD@{5} 
96  
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type 
98  
99    $ git show master@{yesterday} 
100  
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. 
102  
103To see reflog information formatted like the `git log` output, you can run `git log -g`: 
104  
105    $ git log -g master 
106    commit 734713bc047d87bf7eac9674765ae793478c50d3 
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) 
108    Reflog message: commit: fixed refs handling, added gc auto, updated 
109    Author: Scott Chacon <schacon@gmail.com> 
110    Date:   Fri Jan 2 18:32:33 2009 -0800 
111  
112        fixed refs handling, added gc auto, updated tests 
113  
114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>) 
116    Reflog message: merge phedders/rdocs: Merge made by recursive. 
117    Author: Scott Chacon <schacon@gmail.com> 
118    Date:   Thu Dec 11 15:08:43 2008 -0800 
119  
120        Merge commit 'phedders/rdocs' 
121  
122It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. 
123  
124### Ancestry References ### 
125  
126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 
127Suppose you look at the history of your project: 
128  
129    $ git log --pretty=format:'%h %s' --graph 
130    * 734713b fixed refs handling, added gc auto, updated tests 
131    *   d921970 Merge commit 'phedders/rdocs' 
132    |\ 
133    | * 35cfb2b Some rdoc changes 
134    * | 1c002dd added some blame and merge stuff 
135    |/ 
136    * 1c36188 ignore *.gem 
137    * 9b29157 add open3_detach to gemspec file list 
138  
139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": 
140  
141    $ git show HEAD^ 
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
143    Merge: 1c002dd... 35cfb2b... 
144    Author: Scott Chacon <schacon@gmail.com> 
145    Date:   Thu Dec 11 15:08:43 2008 -0800 
146  
147        Merge commit 'phedders/rdocs' 
148  
149You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: 
150  
151    $ git show d921970^ 
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
153    Author: Scott Chacon <schacon@gmail.com> 
154    Date:   Thu Dec 11 14:58:32 2008 -0800 
155  
156        added some blame and merge stuff 
157  
158    $ git show d921970^2 
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 
160    Author: Paul Hedderly <paul+git@mjr.org> 
161    Date:   Wed Dec 10 22:22:03 2008 +0000 
162  
163        Some rdoc changes 
164  
165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be 
166  
167    $ git show HEAD~3 
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
169    Author: Tom Preston-Werner <tom@mojombo.com> 
170    Date:   Fri Nov 7 13:47:59 2008 -0500 
171  
172        ignore *.gem 
173  
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: 
175  
176    $ git show HEAD^^^ 
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
178    Author: Tom Preston-Werner <tom@mojombo.com> 
179    Date:   Fri Nov 7 13:47:59 2008 -0500 
180  
181        ignore *.gem 
182  
183You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. 
184  
185### Commit Ranges ### 
186  
187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 
188  
189#### Double Dot #### 
190  
191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. 
192  
193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
195  
196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: 
197  
198    $ git log master..experiment 
199    D 
200    C 
201  
202If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: 
203  
204    $ git log experiment..master 
205    F 
206    E 
207  
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: 
209  
210    $ git log origin/master..HEAD 
211  
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. 
213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. 
214  
215#### Multiple Points #### 
216  
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: 
218  
219    $ git log refA..refB 
220    $ git log ^refA refB 
221    $ git log refB --not refA 
222  
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: 
224  
225    $ git log refA refB ^refC 
226    $ git log refA refB --not refC 
227  
228This makes for a very powerful revision query system that should help you figure out what is in your branches. 
229  
230#### Triple Dot #### 
231  
232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. 
233If you want to see what is in `master` or `experiment` but not any common references, you can run 
234  
235    $ git log master...experiment 
236    F 
237    E 
238    D 
239    C 
240  
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. 
242  
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: 
244  
245    $ git log --left-right master...experiment 
246    < F 
247    < E 
248    > D 
249    > C 
250  
251With these tools, you can much more easily let Git know what commit or commits you want to inspect. 
252  
253## Interactive Staging ## 
254  
255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257  
258    $ git add -i 
259               staged     unstaged path 
260      1:    unchanged        +0/-1 TODO 
261      2:    unchanged        +1/-1 index.html 
262      3:    unchanged        +5/-1 lib/simplegit.rb 
263  
264    *** Commands *** 
265      1: status     2: update      3: revert     4: add untracked 
266      5: patch      6: diff        7: quit       8: help 
267    What now> 
268  
269You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. 
270  
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. 
272  
273### Staging and Unstaging Files ### 
274  
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: 
276  
277    What now> 2 
278               staged     unstaged path 
279      1:    unchanged        +0/-1 TODO 
280      2:    unchanged        +1/-1 index.html 
281      3:    unchanged        +5/-1 lib/simplegit.rb 
282    Update>> 
283  
284To stage the TODO and index.html files, you can type the numbers: 
285  
286    Update>> 1,2 
287               staged     unstaged path 
288    * 1:    unchanged        +0/-1 TODO 
289    * 2:    unchanged        +1/-1 index.html 
290      3:    unchanged        +5/-1 lib/simplegit.rb 
291    Update>> 
292  
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: 
294  
295    Update>> 
296    updated 2 paths 
297  
298    *** Commands *** 
299      1: status     2: update      3: revert     4: add untracked 
300      5: patch      6: diff        7: quit       8: help 
301    What now> 1 
302               staged     unstaged path 
303      1:        +0/-1      nothing TODO 
304      2:        +1/-1      nothing index.html 
305      3:    unchanged        +5/-1 lib/simplegit.rb 
306  
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: 
308  
309    *** Commands *** 
310      1: status     2: update      3: revert     4: add untracked 
311      5: patch      6: diff        7: quit       8: help 
312    What now> 3 
313               staged     unstaged path 
314      1:        +0/-1      nothing TODO 
315      2:        +1/-1      nothing index.html 
316      3:    unchanged        +5/-1 lib/simplegit.rb 
317    Revert>> 1 
318               staged     unstaged path 
319    * 1:        +0/-1      nothing TODO 
320      2:        +1/-1      nothing index.html 
321      3:    unchanged        +5/-1 lib/simplegit.rb 
322    Revert>> [enter] 
323    reverted one path 
324  
325Looking at your Git status again, you can see that you’ve unstaged the TODO file: 
326  
327    *** Commands *** 
328      1: status     2: update      3: revert     4: add untracked 
329      5: patch      6: diff        7: quit       8: help 
330    What now> 1 
331               staged     unstaged path 
332      1:    unchanged        +0/-1 TODO 
333      2:        +1/-1      nothing index.html 
334      3:    unchanged        +5/-1 lib/simplegit.rb 
335  
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: 
337  
338    *** Commands *** 
339      1: status     2: update      3: revert     4: add untracked 
340      5: patch      6: diff        7: quit       8: help 
341    What now> 6 
342               staged     unstaged path 
343      1:        +1/-1      nothing index.html 
344    Review diff>> 1 
345    diff --git a/index.html b/index.html 
346    index 4d07108..4335f49 100644 
347    --- a/index.html 
348    +++ b/index.html 
349    @@ -16,7 +16,7 @@ Date Finder 
350  
351     <p id="out">...</p> 
352  
353    -<div id="footer">contact : support@github.com</div> 
354    +<div id="footer">contact : email.support@github.com</div> 
355  
356     <script type="text/javascript"> 
357  
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily. 
359  
360### Staging Patches ### 
361  
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: 
363  
364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
365    index dd5ecc4..57399e0 100644 
366    --- a/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 
368    @@ -22,7 +22,7 @@ class SimpleGit 
369       end 
370  
371       def log(treeish = 'master') 
372    -    command("git log -n 25 #{treeish}") 
373    +    command("git log -n 30 #{treeish}") 
374       end 
375  
376       def blame(path) 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 
378  
379You have a lot of options at this point. Typing `?` shows a list of what you can do: 
380  
381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
382    y - stage this hunk 
383    n - do not stage this hunk 
384    a - stage this and all the remaining hunks in the file 
385    d - do not stage this hunk nor any of the remaining hunks in the file 
386    g - select a hunk to go to 
387    / - search for a hunk matching the given regex 
388    j - leave this hunk undecided, see next undecided hunk 
389    J - leave this hunk undecided, see next hunk 
390    k - leave this hunk undecided, see previous undecided hunk 
391    K - leave this hunk undecided, see previous hunk 
392    s - split the current hunk into smaller hunks 
393    e - manually edit the current hunk 
394    ? - print help 
395  
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: 
397  
398    What now> 1 
399               staged     unstaged path 
400      1:    unchanged        +0/-1 TODO 
401      2:        +1/-1      nothing index.html 
402      3:        +1/-1        +4/-0 lib/simplegit.rb 
403  
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. 
405  
406Finally, you don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using `git add -p` or `git add --patch` on the command line. 
407  
408## Stashing ## 
409  
410Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command. 
411  
412Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time. 
413  
414### Stashing Your Work ### 
415  
416To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state: 
417  
418    $ git status 
419    # On branch master 
420    # Changes to be committed: 
421    #   (use "git reset HEAD <file>..." to unstage) 
422    # 
423    #      modified:   index.html 
424    # 
425    # Changes not staged for commit: 
426    #   (use "git add <file>..." to update what will be committed) 
427    # 
428    #      modified:   lib/simplegit.rb 
429    # 
430  
431Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`: 
432  
433    $ git stash 
434    Saved working directory and index state \ 
435      "WIP on master: 049d078 added the index file" 
436    HEAD is now at 049d078 added the index file 
437    (To restore them type "git stash apply") 
438  
439Your working directory is clean: 
440  
441    $ git status 
442    # On branch master 
443    nothing to commit, working directory clean 
444  
445At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: 
446  
447    $ git stash list 
448    stash@{0}: WIP on master: 049d078 added the index file 
449    stash@{1}: WIP on master: c264051 Revert "added file_size" 
450    stash@{2}: WIP on master: 21d80a5 added number to log 
451  
452In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it: 
453  
454    $ git stash apply 
455    # On branch master 
456    # Changes not staged for commit: 
457    #   (use "git add <file>..." to update what will be committed) 
458    # 
459    #      modified:   index.html 
460    #      modified:   lib/simplegit.rb 
461    # 
462  
463You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly. 
464  
465The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position: 
466  
467    $ git stash apply --index 
468    # On branch master 
469    # Changes to be committed: 
470    #   (use "git reset HEAD <file>..." to unstage) 
471    # 
472    #      modified:   index.html 
473    # 
474    # Changes not staged for commit: 
475    #   (use "git add <file>..." to update what will be committed) 
476    # 
477    #      modified:   lib/simplegit.rb 
478    # 
479  
480The apply option only tries to apply the stashed work — you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove: 
481  
482    $ git stash list 
483    stash@{0}: WIP on master: 049d078 added the index file 
484    stash@{1}: WIP on master: c264051 Revert "added file_size" 
485    stash@{2}: WIP on master: 21d80a5 added number to log 
486    $ git stash drop stash@{0} 
487    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) 
488  
489You can also run `git stash pop` to apply the stash and then immediately drop it from your stack. 
490  
491### Un-applying a Stash ### 
492  
493In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
494  
495    $ git stash show -p stash@{0} | git apply -R 
496  
497Again, if you don’t specify a stash, Git assumes the most recent stash: 
498  
499    $ git stash show -p | git apply -R 
500  
501You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
502  
503    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
504    $ git stash apply 
505    $ #... work work work 
506    $ git stash-unapply 
507  
508### Creating a Branch from a Stash ### 
509  
510If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully: 
511  
512    $ git stash branch testchanges 
513    Switched to a new branch "testchanges" 
514    # On branch testchanges 
515    # Changes to be committed: 
516    #   (use "git reset HEAD <file>..." to unstage) 
517    # 
518    #      modified:   index.html 
519    # 
520    # Changes not staged for commit: 
521    #   (use "git add <file>..." to update what will be committed) 
522    # 
523    #      modified:   lib/simplegit.rb 
524    # 
525    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) 
526  
527This is a nice shortcut to recover stashed work easily and work on it in a new branch. 
528  
529## Rewriting History ## 
530  
531Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others. 
532  
533In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. 
534  
535### Changing the Last Commit ### 
536  
537Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 
538  
539If you only want to modify your last commit message, it’s very simple: 
540  
541    $ git commit --amend 
542  
543That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. 
544  
545If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. 
546  
547You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it. 
548  
549### Changing Multiple Commit Messages ### 
550  
551To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. 
552  
553For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: 
554  
555    $ git rebase -i HEAD~3 
556  
557Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change. 
558  
559Running this command gives you a list of commits in your text editor that looks something like this: 
560  
561    pick f7f3f6d changed my name a bit 
562    pick 310154e updated README formatting and added blame 
563    pick a5f4a0d added cat-file 
564  
565    # Rebase 710f0f8..a5f4a0d onto 710f0f8 
566    # 
567    # Commands: 
568    #  p, pick = use commit 
569    #  r, reword = use commit, but edit the commit message 
570    #  e, edit = use commit, but stop for amending 
571    #  s, squash = use commit, but meld into previous commit 
572    #  f, fixup = like "squash", but discard this commit's log message 
573    #  x, exec = run command (the rest of the line) using shell 
574    # 
575    # These lines can be re-ordered; they are executed from top to bottom. 
576    # 
577    # If you remove a line here THAT COMMIT WILL BE LOST. 
578    # 
579    # However, if you remove everything, the rebase will be aborted. 
580    # 
581    # Note that empty commits are commented out 
582  
583It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this: 
584  
585    $ git log --pretty=format:"%h %s" HEAD~3..HEAD 
586    a5f4a0d added cat-file 
587    310154e updated README formatting and added blame 
588    f7f3f6d changed my name a bit 
589  
590Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay. 
591  
592You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this: 
593  
594    edit f7f3f6d changed my name a bit 
595    pick 310154e updated README formatting and added blame 
596    pick a5f4a0d added cat-file 
597  
598When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message: 
599  
600<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  
601nor is the commit message. Please review  
602--> 
603  
604    $ git rebase -i HEAD~3 
605    Stopped at 7482e0d... updated the gemspec to hopefully work better 
606    You can amend the commit now, with 
607  
608           git commit --amend 
609  
610    Once you’re satisfied with your changes, run 
611  
612           git rebase --continue 
613  
614These instructions tell you exactly what to do. Type 
615  
616    $ git commit --amend 
617  
618Change the commit message, and exit the editor. Then, run 
619  
620    $ git rebase --continue 
621  
622This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished. 
623  
624### Reordering Commits ### 
625  
626You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this 
627  
628    pick f7f3f6d changed my name a bit 
629    pick 310154e updated README formatting and added blame 
630    pick a5f4a0d added cat-file 
631  
632to this: 
633  
634    pick 310154e updated README formatting and added blame 
635    pick f7f3f6d changed my name a bit 
636  
637When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely. 
638  
639### Squashing Commits ### 
640  
641It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message: 
642  
643    # 
644    # Commands: 
645    #  p, pick = use commit 
646    #  r, reword = use commit, but edit the commit message 
647    #  e, edit = use commit, but stop for amending 
648    #  s, squash = use commit, but meld into previous commit 
649    #  f, fixup = like "squash", but discard this commit's log message 
650    #  x, exec = run command (the rest of the line) using shell 
651    # 
652    # These lines can be re-ordered; they are executed from top to bottom. 
653    # 
654    # If you remove a line here THAT COMMIT WILL BE LOST. 
655    # 
656    # However, if you remove everything, the rebase will be aborted. 
657    # 
658    # Note that empty commits are commented out 
659  
660If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this: 
661  
662    pick f7f3f6d changed my name a bit 
663    squash 310154e updated README formatting and added blame 
664    squash a5f4a0d added cat-file 
665  
666When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages: 
667  
668    # This is a combination of 3 commits. 
669    # The first commit's message is: 
670    changed my name a bit 
671  
672    # This is the 2nd commit message: 
673  
674    updated README formatting and added blame 
675  
676    # This is the 3rd commit message: 
677  
678    added cat-file 
679  
680When you save that, you have a single commit that introduces the changes of all three previous commits. 
681  
682### Splitting a Commit ### 
683  
684Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit": 
685  
686    pick f7f3f6d changed my name a bit 
687    edit 310154e updated README formatting and added blame 
688    pick a5f4a0d added cat-file 
689  
690When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done: 
691  
692    $ git reset HEAD^ 
693    $ git add README 
694    $ git commit -m 'updated README formatting' 
695    $ git add lib/simplegit.rb 
696    $ git commit -m 'added blame' 
697    $ git rebase --continue 
698  
699Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this: 
700  
701    $ git log -4 --pretty=format:"%h %s" 
702    1c002dd added cat-file 
703    9b29157 added blame 
704    35cfb2b updated README formatting 
705    f3cc40e changed my name a bit 
706  
707Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository. 
708  
709### The Nuclear Option: filter-branch ### 
710  
711There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of. 
712  
713#### Removing a File from Every Commit #### 
714  
715This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`: 
716  
717    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 
718    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) 
719    Ref 'refs/heads/master' was rewritten 
720  
721The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`. 
722  
723You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. 
724  
725#### Making a Subdirectory the New Root #### 
726  
727Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too: 
728  
729    $ git filter-branch --subdirectory-filter trunk HEAD 
730    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) 
731    Ref 'refs/heads/master' was rewritten 
732  
733Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory. 
734  
735#### Changing E-Mail Addresses Globally #### 
736  
737Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`: 
738  
739    $ git filter-branch --commit-filter ' 
740            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; 
741            then 
742                    GIT_AUTHOR_NAME="Scott Chacon"; 
743                    GIT_AUTHOR_EMAIL="schacon@example.com"; 
744                    git commit-tree "$@"; 
745            else 
746                    git commit-tree "$@"; 
747            fi' HEAD 
748  
749This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address. 
750  
751### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
752  
753[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
754  
755See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
756  
757## Debugging with Git ## 
758  
759Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. 
760  
761### File Annotation ### 
762  
763If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: 
764  
765    $ git blame -L 12,22 simplegit.rb 
766    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master') 
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}") 
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end 
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15) 
770    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master') 
771    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}") 
772    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end 
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19) 
774    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path) 
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}") 
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end 
777  
778Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here. 
779  
780Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from: 
781  
782    $ git blame -C -L 141,153 GITPackUpload.m 
783    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
786    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
787    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
793    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 
796  
797This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. 
798  
799### Binary Search ### 
800  
801Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. 
802  
803Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: 
804  
805    $ git bisect start 
806    $ git bisect bad 
807    $ git bisect good v1.0 
808    Bisecting: 6 revisions left to test after this 
809    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo 
810  
811Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: 
812  
813    $ git bisect good 
814    Bisecting: 3 revisions left to test after this 
815    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing 
816  
817Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: 
818  
819    $ git bisect bad 
820    Bisecting: 1 revisions left to test after this 
821    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table 
822  
823This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: 
824  
825    $ git bisect good 
826    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit 
827    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 
828    Author: PJ Hyett <pjhyett@example.com> 
829    Date:   Tue Jan 27 14:48:32 2009 -0800 
830  
831        secure this thing 
832  
833    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 
834    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config 
835  
836When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: 
837  
838    $ git bisect reset 
839  
840This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: 
841  
842    $ git bisect start HEAD v1.0 
843    $ git bisect run test-error.sh 
844  
845Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. 
846  
847## Submodules ## 
848  
849It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. 
850  
851Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available. 
852  
853Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate. 
854  
855### Starting with Submodules ### 
856  
857Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
858  
859    $ git submodule add git://github.com/chneukirchen/rack.git rack 
860    Initialized empty Git repository in /opt/subtest/rack/.git/ 
861    remote: Counting objects: 3181, done. 
862    remote: Compressing objects: 100% (1534/1534), done. 
863    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
864    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. 
865    Resolving deltas: 100% (1951/1951), done. 
866  
867Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
868  
869    $ git status 
870    # On branch master 
871    # Changes to be committed: 
872    #   (use "git reset HEAD <file>..." to unstage) 
873    # 
874    #      new file:   .gitmodules 
875    #      new file:   rack 
876    # 
877  
878First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into: 
879  
880    $ cat .gitmodules 
881    [submodule "rack"] 
882          path = rack 
883          url = git://github.com/chneukirchen/rack.git 
884  
885If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. 
886  
887The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting: 
888  
889    $ git diff --cached rack 
890    diff --git a/rack b/rack 
891    new file mode 160000 
892    index 0000000..08d709f 
893    --- /dev/null 
894    +++ b/rack 
895    @@ -0,0 +1 @@ 
896    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
897  
898Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 
899  
900This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
901  
902When you commit, you see something like this: 
903  
904    $ git commit -m 'first commit with submodule rack' 
905    [master 0550271] first commit with submodule rack 
906     2 files changed, 4 insertions(+), 0 deletions(-) 
907     create mode 100644 .gitmodules 
908     create mode 160000 rack 
909  
910Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file. 
911  
912You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
913  
914    $ git log -1 
915    commit 0550271328a0038865aad6331e620cd7238601bb 
916    Author: Scott Chacon <schacon@gmail.com> 
917    Date:   Thu Apr 9 09:03:56 2009 -0700 
918  
919        first commit with submodule rack 
920    $ cd rack/ 
921    $ git log -1 
922    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
923    Author: Christian Neukirchen <chneukirchen@gmail.com> 
924    Date:   Wed Mar 25 14:49:04 2009 +0100 
925  
926        Document version change 
927  
928### Cloning a Project with Submodules ### 
929  
930Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet: 
931  
932    $ git clone git://github.com/schacon/myproject.git 
933    Initialized empty Git repository in /opt/myproject/.git/ 
934    remote: Counting objects: 6, done. 
935    remote: Compressing objects: 100% (4/4), done. 
936    remote: Total 6 (delta 0), reused 0 (delta 0) 
937    Receiving objects: 100% (6/6), done. 
938    $ cd myproject 
939    $ ls -l 
940    total 8 
941    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 
942    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 
943    $ ls rack/ 
944    $ 
945  
946The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject: 
947  
948    $ git submodule init 
949    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' 
950    $ git submodule update 
951    Initialized empty Git repository in /opt/myproject/rack/.git/ 
952    remote: Counting objects: 3181, done. 
953    remote: Compressing objects: 100% (1534/1534), done. 
954    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
955    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. 
956    Resolving deltas: 100% (1951/1951), done. 
957    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' 
958  
959Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 
960  
961    $ git merge origin/master 
962    Updating 0550271..85a3eee 
963    Fast forward 
964     rack |    2 +- 
965     1 files changed, 1 insertions(+), 1 deletions(-) 
966    [master*]$ git status 
967    # On branch master 
968    # Changes not staged for commit: 
969    #   (use "git add <file>..." to update what will be committed) 
970    #   (use "git checkout -- <file>..." to discard changes in working directory) 
971    # 
972    #      modified:   rack 
973    # 
974  
975You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
976  
977    $ git diff 
978    diff --git a/rack b/rack 
979    index 6c5e70b..08d709f 160000 
980    --- a/rack 
981    +++ b/rack 
982    @@ -1 +1 @@ 
983    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
984    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
985  
986This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
987  
988    $ git submodule update 
989    remote: Counting objects: 5, done. 
990    remote: Compressing objects: 100% (3/3), done. 
991    remote: Total 3 (delta 1), reused 2 (delta 0) 
992    Unpacking objects: 100% (3/3), done. 
993    From git@github.com:schacon/rack 
994       08d709f..6c5e70b  master     -> origin/master 
995    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
996  
997You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
998  
999One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1000  
1001    $ git submodule update 
1002    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1003    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1004  
1005You have to see who last changed the submodule: 
1006  
1007    $ git log -1 rack 
1008    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1009    Author: Scott Chacon <schacon@gmail.com> 
1010    Date:   Thu Apr 9 09:19:14 2009 -0700 
1011  
1012        added a submodule reference I will never make public. hahahahaha! 
1013  
1014Then, you e-mail that guy and yell at him. 
1015  
1016### Superprojects ### 
1017  
1018Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1019  
1020A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1021  
1022### Issues with Submodules ### 
1023  
1024Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 
1025  
1026To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1027  
1028Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory: 
1029  
1030    $ git checkout -b rack 
1031    Switched to a new branch "rack" 
1032    $ git submodule add git@github.com:schacon/rack.git rack 
1033    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1034    ... 
1035    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1036    Resolving deltas: 100% (1952/1952), done. 
1037    $ git commit -am 'added rack submodule' 
1038    [rack cc49a69] added rack submodule 
1039     2 files changed, 4 insertions(+), 0 deletions(-) 
1040     create mode 100644 .gitmodules 
1041     create mode 160000 rack 
1042    $ git checkout master 
1043    Switched to branch "master" 
1044    $ git status 
1045    # On branch master 
1046    # Untracked files: 
1047    #   (use "git add <file>..." to include in what will be committed) 
1048    # 
1049    #      rack/ 
1050  
1051You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 
1052  
1053The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you: 
1054  
1055    $ rm -Rf rack/ 
1056    $ git submodule add git@github.com:schacon/rack.git rack 
1057    'rack' already exists in the index 
1058  
1059You have to unstage the `rack` directory first. Then you can add the submodule: 
1060  
1061    $ git rm -r rack 
1062    $ git submodule add git@github.com:schacon/rack.git rack 
1063    Initialized empty Git repository in /opt/testsub/rack/.git/ 
1064    remote: Counting objects: 3184, done. 
1065    remote: Compressing objects: 100% (1465/1465), done. 
1066    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1067    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. 
1068    Resolving deltas: 100% (1952/1952), done. 
1069  
1070Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule — you get this error: 
1071  
1072    $ git checkout master 
1073    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 
1074  
1075You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1076  
1077    $ mv rack /tmp/ 
1078    $ git checkout master 
1079    Switched to branch "master" 
1080    $ ls 
1081    README  rack 
1082  
1083Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory. 
1084  
1085## Subtree Merging ## 
1086  
1087Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1088  
1089However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1090  
1091The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing. 
1092  
1093You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch: 
1094  
1095    $ git remote add rack_remote git@github.com:schacon/rack.git 
1096    $ git fetch rack_remote 
1097    warning: no common commits 
1098    remote: Counting objects: 3184, done. 
1099    remote: Compressing objects: 100% (1465/1465), done. 
1100    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1101    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. 
1102    Resolving deltas: 100% (1952/1952), done. 
1103    From git@github.com:schacon/rack 
1104     * [new branch]      build      -> rack_remote/build 
1105     * [new branch]      master     -> rack_remote/master 
1106     * [new branch]      rack-0.4   -> rack_remote/rack-0.4 
1107     * [new branch]      rack-0.9   -> rack_remote/rack-0.9 
1108    $ git checkout -b rack_branch rack_remote/master 
1109    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. 
1110    Switched to a new branch "rack_branch" 
1111  
1112Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots: 
1113  
1114    $ ls 
1115    AUTHORS        KNOWN-ISSUES   Rakefile      contrib        lib 
1116    COPYING        README         bin           example        test 
1117    $ git checkout master 
1118    Switched to branch "master" 
1119    $ ls 
1120    README 
1121  
1122You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: 
1123  
1124    $ git read-tree --prefix=rack/ -u rack_branch 
1125  
1126When you commit, it looks like you have all the Rack files under that subdirectory — as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling: 
1127  
1128    $ git checkout rack_branch 
1129    $ git pull 
1130  
1131Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option: 
1132  
1133    $ git checkout master 
1134    $ git merge --squash -s subtree --no-commit rack_branch 
1135    Squash commit -- not updating HEAD 
1136    Automatic merge went well; stopped before committing as requested 
1137  
1138All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite — make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream. 
1139  
1140To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch — to see if you need to merge them — you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to: 
1141  
1142    $ git diff-tree -p rack_branch 
1143  
1144Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run 
1145  
1146    $ git diff-tree -p rack_remote/master 
1147 38 
.1148## Summary ## 39=== Summary 
1149 40 
.1150You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so.41You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned how to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so.
1151 42 
+
+ From 48a14a7d711ef85f04b95f13aebb7ba79d8160ff Mon Sep 17 00:00:00 2001 From: Haruo Nakayama Date: Thu, 27 Nov 2014 10:52:19 +0900 Subject: [PATCH 2/8] Apply existing translations --- book/07-git-tools/sections/debugging.asc | 81 +- book/07-git-tools/sections/diff-debugging.htm | 4815 +++++++++++ .../sections/diff-interactive-staging.htm | 4835 +++++++++++ .../sections/diff-revision-selection.htm | 5011 +++++++++++ .../sections/diff-rewriting-history.htm | 4955 +++++++++++ book/07-git-tools/sections/diff-signing.htm | 5567 ++++++++++++ .../sections/diff-stashing-cleaning.htm | 5275 ++++++++++++ .../07-git-tools/sections/diff-submodules.htm | 7427 +++++++++++++++++ .../sections/diff-subtree-merges.htm | 4815 +++++++++++ .../sections/interactive-staging.asc | 67 + .../sections/revision-selection.asc | 195 +- .../sections/rewriting-history.asc | 187 +- book/07-git-tools/sections/signing.asc | 21 + .../sections/stashing-cleaning.asc | 63 + book/07-git-tools/sections/submodules.asc | 85 +- book/07-git-tools/sections/subtree-merges.asc | 41 + 16 files changed, 43435 insertions(+), 5 deletions(-) create mode 100644 book/07-git-tools/sections/diff-debugging.htm create mode 100644 book/07-git-tools/sections/diff-interactive-staging.htm create mode 100644 book/07-git-tools/sections/diff-revision-selection.htm create mode 100644 book/07-git-tools/sections/diff-rewriting-history.htm create mode 100644 book/07-git-tools/sections/diff-signing.htm create mode 100644 book/07-git-tools/sections/diff-stashing-cleaning.htm create mode 100644 book/07-git-tools/sections/diff-submodules.htm create mode 100644 book/07-git-tools/sections/diff-subtree-merges.htm diff --git a/book/07-git-tools/sections/debugging.asc b/book/07-git-tools/sections/debugging.asc index bf65ddf8..233ab5e7 100644 --- a/book/07-git-tools/sections/debugging.asc +++ b/book/07-git-tools/sections/debugging.asc @@ -1,15 +1,31 @@ +////////////////////////// === Debugging with Git +////////////////////////// +=== Git によるデバッグ +////////////////////////// Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. +////////////////////////// +Git には、プロジェクトで発生した問題をデバッグするためのツールも用意されています。 +Git はほとんどあらゆる種類のプロジェクトで使えるように設計されているので、このツールも非常に汎用的なものです。しかし、バグを見つけたり不具合の原因を探したりするための助けとなるでしょう。 [[_file_annotation]] +////////////////////////// ==== File Annotation +////////////////////////// +==== ファイルの注記 +////////////////////////// If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: +////////////////////////// +コードのバグを追跡しているときに「それが、いつどんな理由で追加されたのか」が知りたくなることがあるでしょう。そんな場合にもっとも便利なのが、ファイルの注記です。 +これは、ファイルの各行について、その行を最後に更新したのがどのコミットかを表示します。 +もしコードの中の特定のメソッドにバグがあることを見つけたら、そのファイルを `git blame` しましょう。そうすれば、そのメソッドの各行がいつ誰によって更新されたのかがわかります。 +この例では、`-L` オプションを使って 12 行目から 22 行目までに出力を限定しています。 [source,console] ---- @@ -27,19 +43,35 @@ $ git blame -L 12,22 simplegit.rb 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end ---- +////////////////////////// Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit–the author name and the authored date of that commit – so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA-1, but that is what it means here. - +////////////////////////// +最初の項目は、その行を最後に更新したコミットの SHA-1 の一部です。 +次のふたつの項目は、そのコミットから抽出した作者情報とコミット日時です。これで、いつ誰がその行を更新したのかが簡単にわかります。 +それに続いて、行番号とファイルの中身が表示されます。 +`^4832fe2` のコミットに関する行に注目しましょう。これらの行は、ファイルが最初にコミットされたときのままであることを表します。 +このコミットはファイルがプロジェクトに最初に追加されたときのものであり、これらの行はそれ以降変更されていません。 +これはちょっと戸惑うかも知れません。Git では、これまで紹介してきただけで少なくとも三種類以上の意味で `^` を使っていますからね。しかし、ここではそういう意味になるのです。 + +////////////////////////// Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. For example, say you are refactoring a file named `GITServerHandler.m` into multiple files, one of which is `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, you can see where sections of the code originally came from: +////////////////////////// +Git のすばらしいところのひとつに、ファイルのリネームを明示的には追跡しないということがあります。 +スナップショットだけを記録し、もしリネームされていたのなら暗黙のうちにそれを検出します。 +この機能の興味深いところは、ファイルのリネームだけでなくコードの移動についても検出できるということです。 +`git blame` に `-C` を渡すと Git はそのファイルを解析し、別のところからコピーされたコード片がないかどうかを探します。 +例えば、`GITServerHandler.m` というファイルをリファクタリングで複数のファイルに分割したとしましょう。そのうちのひとつが `GITPackUpload.m` です。 +ここで `-C` オプションをつけて `GITPackUpload.m` を調べると、コードのどの部分をどのファイルからコピーしたのかを知ることができます。 [source,console] ---- @@ -59,22 +91,42 @@ ad11ac80 GITPackUpload.m (Scott 2009-03-24 150) 56ef2caf GITServerHandler.m (Scott 2009-01-05 153) ---- +////////////////////////// This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. +////////////////////////// +これはほんとうに便利です。 +通常は、そのファイルがコピーされたときのコミットを知ることになります。コピー先のファイルにおいて最初にその行をさわったのが、その内容をコピーしてきたときだからです。 +Git は、その行が本当に書かれたコミットがどこであったのかを (たとえ別のファイルであったとしても) 教えてくれるのです。 [[_binary_search]] +////////////////////////// ==== Binary Search +////////////////////////// +==== 二分探索 +////////////////////////// Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. +////////////////////////// +ファイルの注記を使えば、その問題がどの時点で始まったのかを知ることができます。 +何がおかしくなったのかがわからず、最後にうまく動作していたときから何十何百ものコミットが行われている場合などは、`git bisect` に頼ることになるでしょう。 +`bisect` コマンドはコミットの歴史に対して二分探索を行い、どのコミットで問題が混入したのかを可能な限り手早く見つけ出せるようにします。 +////////////////////////// Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: +////////////////////////// +自分のコードをリリースして運用環境にプッシュしたあとに、バグ報告を受け取ったと仮定しましょう。そのバグは開発環境では再現せず、なぜそんなことになるのか想像もつきません。 +コードをよく調べて問題を再現させることはできましたが、何が悪かったのかがわかりません。 +こんな場合に、二分探索で原因を特定することができます。 +まず、`git bisect start` を実行します。そして次に `git bisect bad` を使って、現在のコミットが壊れた状態であることをシステムに伝えます。 +次に、まだ壊れていなかったとわかっている直近のコミットを `git bisect good [good_commit]` で伝えます。 [source,console] ---- @@ -85,10 +137,16 @@ Bisecting: 6 revisions left to test after this [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo ---- +////////////////////////// Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: +////////////////////////// +Git は、まだうまく動いていたと指定されたコミット (v1.0) と現在の壊れたバージョンの間には 12 のコミットがあるということを検出しました。そして、そのちょうど真ん中にあるコミットをチェックアウトしました。 +ここでテストを実行すれば、このコミットで同じ問題が発生するかどうかがわかります。 +もし問題が発生したなら、実際に問題が混入したのはそれより前のコミットだということになります。そうでなければ、それ以降のコミットで問題が混入したのでしょう。 +ここでは、問題が発生しなかったものとします。`git bisect good` で Git にその旨を伝え、旅を続けましょう。 [source,console] ---- @@ -97,8 +155,12 @@ Bisecting: 3 revisions left to test after this [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing ---- +////////////////////////// Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: +////////////////////////// +また別のコミットがやってきました。先ほど調べたコミットと「壊れている」と伝えたコミットの真ん中にあるものです。 +ふたたびテストを実行し、今度はこのコミットで問題が再現したものとします。それを Git に伝えるには `git bisect bad` を使います。 [source,console] ---- @@ -107,8 +169,12 @@ Bisecting: 1 revisions left to test after this [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table ---- +////////////////////////// This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: +////////////////////////// +このコミットはうまく動きました。というわけで、問題が混入したコミットを特定するための情報がこれですべて整いました。 +Git は問題が混入したコミットの SHA-1 を示し、そのコミット情報とどのファイルが変更されたのかを表示します。これを使って、いったい何が原因でバグが発生したのかを突き止めます。 [source,console] ---- @@ -124,17 +190,26 @@ Date: Tue Jan 27 14:48:32 2009 -0800 f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config ---- +////////////////////////// When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: +////////////////////////// +原因がわかったら、作業を始める前に `git bisect reset` を実行して HEAD を作業前の状態に戻さなければなりません。そうしないと面倒なことになってしまいます。 [source,console] ---- $ git bisect reset ---- +////////////////////////// This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: +////////////////////////// +この強力なツールを使えば、何百ものコミットの中からバグの原因となるコミットを数分で見つけだせるようになります。 +実際、プロジェクトが正常なときに 0 を返してどこかおかしいときに 0 以外を返すスクリプトを用意しておけば、`git bisect` を完全に自動化することもできます。 +まず、先ほどと同じく、壊れているコミットと正しく動作しているコミットを指定します。 +これは `bisect start` コマンドで行うこともできます。まず最初に壊れているコミット、そしてその後に正しく動作しているコミットを指定します。 [source,console] ---- @@ -142,5 +217,9 @@ $ git bisect start HEAD v1.0 $ git bisect run test-error.sh ---- +////////////////////////// Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. +////////////////////////// +こうすると、チェックアウトされたコミットに対して自動的に `test-error.sh` を実行し、壊れる原因となるコミットを見つけ出すまで自動的に処理を続けます。 +`make` や `make tests`、その他自動テストを実行するためのプログラムなどをここで実行させることもできます。 diff --git a/book/07-git-tools/sections/diff-debugging.htm b/book/07-git-tools/sections/diff-debugging.htm new file mode 100644 index 00000000..794433c5 --- /dev/null +++ b/book/07-git-tools/sections/diff-debugging.htm @@ -0,0 +1,4815 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\debugging.asc
.1# Git Tools # 
2  
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. 
4  
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. 
6  
7## Revision Selection ## 
8  
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. 
10  
11### Single Revisions ### 
12  
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. 
14  
15### Short SHA ### 
16  
17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. 
18  
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: 
20  
21    $ git log 
22    commit 734713bc047d87bf7eac9674765ae793478c50d3 
23    Author: Scott Chacon <schacon@gmail.com> 
24    Date:   Fri Jan 2 18:32:33 2009 -0800 
25  
26        fixed refs handling, added gc auto, updated tests 
27  
28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
29    Merge: 1c002dd... 35cfb2b... 
30    Author: Scott Chacon <schacon@gmail.com> 
31    Date:   Thu Dec 11 15:08:43 2008 -0800 
32  
33        Merge commit 'phedders/rdocs' 
34  
35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
36    Author: Scott Chacon <schacon@gmail.com> 
37    Date:   Thu Dec 11 14:58:32 2008 -0800 
38  
39        added some blame and merge stuff 
40  
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): 
42  
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
44    $ git show 1c002dd4b536e7479f 
45    $ git show 1c002d 
46  
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: 
48  
49    $ git log --abbrev-commit --pretty=oneline 
50    ca82a6d changed the version number 
51    085bb3b removed unnecessary test code 
52    a11bef0 first commit 
53  
54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 
55  
56### A SHORT NOTE ABOUT SHA-1 ### 
57  
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? 
59  
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. 
61  
62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. 
63  
64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. 
65  
66### Branch References ### 
67  
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: 
69  
70    $ git show ca82a6dff817ec66f44342007202690a93763949 
71    $ git show topic1 
72  
73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. 
74  
75    $ git rev-parse topic1 
76    ca82a6dff817ec66f44342007202690a93763949 
77  
78### RefLog Shortnames ### 
79  
80One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. 
81  
82You can see your reflog by using `git reflog`: 
83  
84    $ git reflog 
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated 
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff 
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 
89    95df984 HEAD@{4}: commit: # This is a combination of two commits. 
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD 
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD 
92  
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: 
94  
95    $ git show HEAD@{5} 
96  
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type 
98  
99    $ git show master@{yesterday} 
100  
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. 
102  
103To see reflog information formatted like the `git log` output, you can run `git log -g`: 
104  
105    $ git log -g master 
106    commit 734713bc047d87bf7eac9674765ae793478c50d3 
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) 
108    Reflog message: commit: fixed refs handling, added gc auto, updated 
109    Author: Scott Chacon <schacon@gmail.com> 
110    Date:   Fri Jan 2 18:32:33 2009 -0800 
111  
112        fixed refs handling, added gc auto, updated tests 
113  
114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>) 
116    Reflog message: merge phedders/rdocs: Merge made by recursive. 
117    Author: Scott Chacon <schacon@gmail.com> 
118    Date:   Thu Dec 11 15:08:43 2008 -0800 
119  
120        Merge commit 'phedders/rdocs' 
121  
122It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. 
123  
124### Ancestry References ### 
125  
126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 
127Suppose you look at the history of your project: 
128  
129    $ git log --pretty=format:'%h %s' --graph 
130    * 734713b fixed refs handling, added gc auto, updated tests 
131    *   d921970 Merge commit 'phedders/rdocs' 
132    |\ 
133    | * 35cfb2b Some rdoc changes 
134    * | 1c002dd added some blame and merge stuff 
135    |/ 
136    * 1c36188 ignore *.gem 
137    * 9b29157 add open3_detach to gemspec file list 
138  
139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": 
140  
141    $ git show HEAD^ 
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
143    Merge: 1c002dd... 35cfb2b... 
144    Author: Scott Chacon <schacon@gmail.com> 
145    Date:   Thu Dec 11 15:08:43 2008 -0800 
146  
147        Merge commit 'phedders/rdocs' 
148  
149You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: 
150  
151    $ git show d921970^ 
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
153    Author: Scott Chacon <schacon@gmail.com> 
154    Date:   Thu Dec 11 14:58:32 2008 -0800 
155  
156        added some blame and merge stuff 
157  
158    $ git show d921970^2 
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 
160    Author: Paul Hedderly <paul+git@mjr.org> 
161    Date:   Wed Dec 10 22:22:03 2008 +0000 
162  
163        Some rdoc changes 
164  
165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be 
166  
167    $ git show HEAD~3 
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
169    Author: Tom Preston-Werner <tom@mojombo.com> 
170    Date:   Fri Nov 7 13:47:59 2008 -0500 
171  
172        ignore *.gem 
173  
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: 
175  
176    $ git show HEAD^^^ 
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
178    Author: Tom Preston-Werner <tom@mojombo.com> 
179    Date:   Fri Nov 7 13:47:59 2008 -0500 
180  
181        ignore *.gem 
182  
183You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. 
184  
185### Commit Ranges ### 
186  
187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 
188  
189#### Double Dot #### 
190  
191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. 
192  
193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
195  
196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: 
197  
198    $ git log master..experiment 
199    D 
200    C 
201  
202If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: 
203  
204    $ git log experiment..master 
205    F 
206    E 
207  
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: 
209  
210    $ git log origin/master..HEAD 
211  
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. 
213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. 
214  
215#### Multiple Points #### 
216  
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: 
218  
219    $ git log refA..refB 
220    $ git log ^refA refB 
221    $ git log refB --not refA 
222  
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: 
224  
225    $ git log refA refB ^refC 
226    $ git log refA refB --not refC 
227  
228This makes for a very powerful revision query system that should help you figure out what is in your branches. 
229  
230#### Triple Dot #### 
231  
232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. 
233If you want to see what is in `master` or `experiment` but not any common references, you can run 
234  
235    $ git log master...experiment 
236    F 
237    E 
238    D 
239    C 
240  
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. 
242  
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: 
244  
245    $ git log --left-right master...experiment 
246    < F 
247    < E 
248    > D 
249    > C 
250  
251With these tools, you can much more easily let Git know what commit or commits you want to inspect. 
252  
253## Interactive Staging ## 
254  
255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257  
258    $ git add -i 
259               staged     unstaged path 
260      1:    unchanged        +0/-1 TODO 
261      2:    unchanged        +1/-1 index.html 
262      3:    unchanged        +5/-1 lib/simplegit.rb 
263  
264    *** Commands *** 
265      1: status     2: update      3: revert     4: add untracked 
266      5: patch      6: diff        7: quit       8: help 
267    What now> 
268  
269You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. 
270  
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. 
272  
273### Staging and Unstaging Files ### 
274  
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: 
276  
277    What now> 2 
278               staged     unstaged path 
279      1:    unchanged        +0/-1 TODO 
280      2:    unchanged        +1/-1 index.html 
281      3:    unchanged        +5/-1 lib/simplegit.rb 
282    Update>> 
283  
284To stage the TODO and index.html files, you can type the numbers: 
285  
286    Update>> 1,2 
287               staged     unstaged path 
288    * 1:    unchanged        +0/-1 TODO 
289    * 2:    unchanged        +1/-1 index.html 
290      3:    unchanged        +5/-1 lib/simplegit.rb 
291    Update>> 
292  
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: 
294  
295    Update>> 
296    updated 2 paths 
297  
298    *** Commands *** 
299      1: status     2: update      3: revert     4: add untracked 
300      5: patch      6: diff        7: quit       8: help 
301    What now> 1 
302               staged     unstaged path 
303      1:        +0/-1      nothing TODO 
304      2:        +1/-1      nothing index.html 
305      3:    unchanged        +5/-1 lib/simplegit.rb 
306  
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: 
308  
309    *** Commands *** 
310      1: status     2: update      3: revert     4: add untracked 
311      5: patch      6: diff        7: quit       8: help 
312    What now> 3 
313               staged     unstaged path 
314      1:        +0/-1      nothing TODO 
315      2:        +1/-1      nothing index.html 
316      3:    unchanged        +5/-1 lib/simplegit.rb 
317    Revert>> 1 
318               staged     unstaged path 
319    * 1:        +0/-1      nothing TODO 
320      2:        +1/-1      nothing index.html 
321      3:    unchanged        +5/-1 lib/simplegit.rb 
322    Revert>> [enter] 
323    reverted one path 
324  
325Looking at your Git status again, you can see that you’ve unstaged the TODO file: 
326  
327    *** Commands *** 
328      1: status     2: update      3: revert     4: add untracked 
329      5: patch      6: diff        7: quit       8: help 
330    What now> 1 
331               staged     unstaged path 
332      1:    unchanged        +0/-1 TODO 
333      2:        +1/-1      nothing index.html 
334      3:    unchanged        +5/-1 lib/simplegit.rb 
335  
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: 
337  
338    *** Commands *** 
339      1: status     2: update      3: revert     4: add untracked 
340      5: patch      6: diff        7: quit       8: help 
341    What now> 6 
342               staged     unstaged path 
343      1:        +1/-1      nothing index.html 
344    Review diff>> 1 
345    diff --git a/index.html b/index.html 
346    index 4d07108..4335f49 100644 
347    --- a/index.html 
348    +++ b/index.html 
349    @@ -16,7 +16,7 @@ Date Finder 
350  
351     <p id="out">...</p> 
352  
353    -<div id="footer">contact : support@github.com</div> 
354    +<div id="footer">contact : email.support@github.com</div> 
355  
356     <script type="text/javascript"> 
357  
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily. 
359  
360### Staging Patches ### 
361  
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: 
363  
364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
365    index dd5ecc4..57399e0 100644 
366    --- a/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 
368    @@ -22,7 +22,7 @@ class SimpleGit 
369       end 
370  
371       def log(treeish = 'master') 
372    -    command("git log -n 25 #{treeish}") 
373    +    command("git log -n 30 #{treeish}") 
374       end 
375  
376       def blame(path) 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 
378  
379You have a lot of options at this point. Typing `?` shows a list of what you can do: 
380  
381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
382    y - stage this hunk 
383    n - do not stage this hunk 
384    a - stage this and all the remaining hunks in the file 
385    d - do not stage this hunk nor any of the remaining hunks in the file 
386    g - select a hunk to go to 
387    / - search for a hunk matching the given regex 
388    j - leave this hunk undecided, see next undecided hunk 
389    J - leave this hunk undecided, see next hunk 
390    k - leave this hunk undecided, see previous undecided hunk 
391    K - leave this hunk undecided, see previous hunk 
392    s - split the current hunk into smaller hunks 
393    e - manually edit the current hunk 
394    ? - print help 
395  
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: 
397  
398    What now> 1 
399               staged     unstaged path 
400      1:    unchanged        +0/-1 TODO 
401      2:        +1/-1      nothing index.html 
402      3:        +1/-1        +4/-0 lib/simplegit.rb 
403  
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. 
405  
406Finally, you don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using `git add -p` or `git add --patch` on the command line. 
407  
408## Stashing ## 
409  
410Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command. 
411  
412Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time. 
413  
414### Stashing Your Work ### 
415  
416To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state: 
417  
418    $ git status 
419    # On branch master 
420    # Changes to be committed: 
421    #   (use "git reset HEAD <file>..." to unstage) 
422    # 
423    #      modified:   index.html 
424    # 
425    # Changes not staged for commit: 
426    #   (use "git add <file>..." to update what will be committed) 
427    # 
428    #      modified:   lib/simplegit.rb 
429    # 
430  
431Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`: 
432  
433    $ git stash 
434    Saved working directory and index state \ 
435      "WIP on master: 049d078 added the index file" 
436    HEAD is now at 049d078 added the index file 
437    (To restore them type "git stash apply") 
438  
439Your working directory is clean: 
440  
441    $ git status 
442    # On branch master 
443    nothing to commit, working directory clean 
444  
445At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: 
446  
447    $ git stash list 
448    stash@{0}: WIP on master: 049d078 added the index file 
449    stash@{1}: WIP on master: c264051 Revert "added file_size" 
450    stash@{2}: WIP on master: 21d80a5 added number to log 
451  
452In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it: 
453  
454    $ git stash apply 
455    # On branch master 
456    # Changes not staged for commit: 
457    #   (use "git add <file>..." to update what will be committed) 
458    # 
459    #      modified:   index.html 
460    #      modified:   lib/simplegit.rb 
461    # 
462  
463You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly. 
464  
465The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position: 
466  
467    $ git stash apply --index 
468    # On branch master 
469    # Changes to be committed: 
470    #   (use "git reset HEAD <file>..." to unstage) 
471    # 
472    #      modified:   index.html 
473    # 
474    # Changes not staged for commit: 
475    #   (use "git add <file>..." to update what will be committed) 
476    # 
477    #      modified:   lib/simplegit.rb 
478    # 
479  
480The apply option only tries to apply the stashed work — you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove: 
481  
482    $ git stash list 
483    stash@{0}: WIP on master: 049d078 added the index file 
484    stash@{1}: WIP on master: c264051 Revert "added file_size" 
485    stash@{2}: WIP on master: 21d80a5 added number to log 
486    $ git stash drop stash@{0} 
487    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) 
488  
489You can also run `git stash pop` to apply the stash and then immediately drop it from your stack. 
490  
491### Un-applying a Stash ### 
492  
493In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
494  
495    $ git stash show -p stash@{0} | git apply -R 
496  
497Again, if you don’t specify a stash, Git assumes the most recent stash: 
498  
499    $ git stash show -p | git apply -R 
500  
501You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
502  
503    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
504    $ git stash apply 
505    $ #... work work work 
506    $ git stash-unapply 
507  
508### Creating a Branch from a Stash ### 
509  
510If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully: 
511  
512    $ git stash branch testchanges 
513    Switched to a new branch "testchanges" 
514    # On branch testchanges 
515    # Changes to be committed: 
516    #   (use "git reset HEAD <file>..." to unstage) 
517    # 
518    #      modified:   index.html 
519    # 
520    # Changes not staged for commit: 
521    #   (use "git add <file>..." to update what will be committed) 
522    # 
523    #      modified:   lib/simplegit.rb 
524    # 
525    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) 
526  
527This is a nice shortcut to recover stashed work easily and work on it in a new branch. 
528  
529## Rewriting History ## 
530  
531Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others. 
532  
533In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. 
534  
535### Changing the Last Commit ### 
536  
537Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 
538  
539If you only want to modify your last commit message, it’s very simple: 
540  
541    $ git commit --amend 
542  
543That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. 
544  
545If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. 
546  
547You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it. 
548  
549### Changing Multiple Commit Messages ### 
550  
551To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. 
552  
553For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: 
554  
555    $ git rebase -i HEAD~3 
556  
557Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change. 
558  
559Running this command gives you a list of commits in your text editor that looks something like this: 
560  
561    pick f7f3f6d changed my name a bit 
562    pick 310154e updated README formatting and added blame 
563    pick a5f4a0d added cat-file 
564  
565    # Rebase 710f0f8..a5f4a0d onto 710f0f8 
566    # 
567    # Commands: 
568    #  p, pick = use commit 
569    #  r, reword = use commit, but edit the commit message 
570    #  e, edit = use commit, but stop for amending 
571    #  s, squash = use commit, but meld into previous commit 
572    #  f, fixup = like "squash", but discard this commit's log message 
573    #  x, exec = run command (the rest of the line) using shell 
574    # 
575    # These lines can be re-ordered; they are executed from top to bottom. 
576    # 
577    # If you remove a line here THAT COMMIT WILL BE LOST. 
578    # 
579    # However, if you remove everything, the rebase will be aborted. 
580    # 
581    # Note that empty commits are commented out 
582  
583It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this: 
584  
585    $ git log --pretty=format:"%h %s" HEAD~3..HEAD 
586    a5f4a0d added cat-file 
587    310154e updated README formatting and added blame 
588    f7f3f6d changed my name a bit 
589  
590Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay. 
591  
592You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this: 
593  
594    edit f7f3f6d changed my name a bit 
595    pick 310154e updated README formatting and added blame 
596    pick a5f4a0d added cat-file 
597  
598When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message: 
599  
600<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  
601nor is the commit message. Please review  
602--> 
603  
604    $ git rebase -i HEAD~3 
605    Stopped at 7482e0d... updated the gemspec to hopefully work better 
606    You can amend the commit now, with 
607  
608           git commit --amend 
609  
610    Once you’re satisfied with your changes, run 
611  
612           git rebase --continue 
613  
614These instructions tell you exactly what to do. Type 
615  
616    $ git commit --amend 
617  
618Change the commit message, and exit the editor. Then, run 
619  
620    $ git rebase --continue 
621  
622This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished. 
623  
624### Reordering Commits ### 
625  
626You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this 
627  
628    pick f7f3f6d changed my name a bit 
629    pick 310154e updated README formatting and added blame 
630    pick a5f4a0d added cat-file 
631  
632to this: 
633  
634    pick 310154e updated README formatting and added blame 
635    pick f7f3f6d changed my name a bit 
636  
637When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely. 
638  
639### Squashing Commits ### 
640  
641It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message: 
642  
643    # 
644    # Commands: 
645    #  p, pick = use commit 
646    #  r, reword = use commit, but edit the commit message 
647    #  e, edit = use commit, but stop for amending 
648    #  s, squash = use commit, but meld into previous commit 
649    #  f, fixup = like "squash", but discard this commit's log message 
650    #  x, exec = run command (the rest of the line) using shell 
651    # 
652    # These lines can be re-ordered; they are executed from top to bottom. 
653    # 
654    # If you remove a line here THAT COMMIT WILL BE LOST. 
655    # 
656    # However, if you remove everything, the rebase will be aborted. 
657    # 
658    # Note that empty commits are commented out 
659  
660If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this: 
661  
662    pick f7f3f6d changed my name a bit 
663    squash 310154e updated README formatting and added blame 
664    squash a5f4a0d added cat-file 
665  
666When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages: 
667  
668    # This is a combination of 3 commits. 
669    # The first commit's message is: 
670    changed my name a bit 
671  
672    # This is the 2nd commit message: 
673  
674    updated README formatting and added blame 
675  
676    # This is the 3rd commit message: 
677  
678    added cat-file 
679  
680When you save that, you have a single commit that introduces the changes of all three previous commits. 
681  
682### Splitting a Commit ### 
683  
684Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit": 
685  
686    pick f7f3f6d changed my name a bit 
687    edit 310154e updated README formatting and added blame 
688    pick a5f4a0d added cat-file 
689  
690When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done: 
691  
692    $ git reset HEAD^ 
693    $ git add README 
694    $ git commit -m 'updated README formatting' 
695    $ git add lib/simplegit.rb 
696    $ git commit -m 'added blame' 
697    $ git rebase --continue 
698  
699Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this: 
700  
701    $ git log -4 --pretty=format:"%h %s" 
702    1c002dd added cat-file 
703    9b29157 added blame 
704    35cfb2b updated README formatting 
705    f3cc40e changed my name a bit 
706  
707Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository. 
708  
709### The Nuclear Option: filter-branch ### 
710  
711There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of. 
712  
713#### Removing a File from Every Commit #### 
714  
715This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`: 
716  
717    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 
718    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) 
719    Ref 'refs/heads/master' was rewritten 
720  
721The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`. 
722  
723You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. 
724  
725#### Making a Subdirectory the New Root #### 
726  
727Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too: 
728  
729    $ git filter-branch --subdirectory-filter trunk HEAD 
730    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) 
731    Ref 'refs/heads/master' was rewritten 
732  
733Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory. 
734  
735#### Changing E-Mail Addresses Globally #### 
736  
737Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`: 
738  
739    $ git filter-branch --commit-filter ' 
740            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; 
741            then 
742                    GIT_AUTHOR_NAME="Scott Chacon"; 
743                    GIT_AUTHOR_EMAIL="schacon@example.com"; 
744                    git commit-tree "$@"; 
745            else 
746                    git commit-tree "$@"; 
747            fi' HEAD 
748  
749This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address. 
750  
751### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
752  
753[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
754  
755See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
756  
757## Debugging with Git ## 1=== Debugging with Git 
758 2 
759Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong.3Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong.
760 4 
. 5[[_file_annotation]]
761### File Annotation ### 6==== File Annotation 
762 7 
763If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22:8If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22:
764 9 
. 10[source,console]
 11----
765    $ git blame -L 12,22 simplegit.rb12$ git blame -L 12,22 simplegit.rb
766    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master')13^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master')
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}")14^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}")
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end15^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15)16^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15)
770    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master')179f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master')
771    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}")1879eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}")
772    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end199f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19)209f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19)
774    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path)2142cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path)
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}")2242cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}")
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end2342cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end
 24----
777 25 
.778Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that committhe author name and the authored date of that commit so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here.26Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that committhe author name and the authored date of that commit so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here.
779 27 
.780Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from:28Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. For example, say you are refactoring a file named `GITServerHandler.m` into multiple files, one of which is `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, you can see where sections of the code originally came from:
781 29 
.782    $ git blame -C -L 141,153 GITPackUpload.m 30[source,console] 
783    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 31---- 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 32$ git blame -C -L 141,153 GITPackUpload.m 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 33f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
786    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 34f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
787    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 35f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 3670befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 37ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 38ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 39ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150)40ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148)
793    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 41ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 42ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 4356ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
 4456ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb
 4556ef2caf GITServerHandler.m (Scott 2009-01-05 153)
 46----
796 47 
797This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file.48This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file.
798 49 
. 50[[_binary_search]]
799### Binary Search ### 51==== Binary Search 
800 52 
801Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue.53Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue.
802 54 
803Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`:55Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`:
804 56 
. 57[source,console]
 58----
805    $ git bisect start59$ git bisect start
806    $ git bisect bad60$ git bisect bad
807    $ git bisect good v1.061$ git bisect good v1.0
808    Bisecting: 6 revisions left to test after this62Bisecting: 6 revisions left to test after this
809    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo63[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo
 64----
810 65 
811Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey:66Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey:
812 67 
. 68[source,console]
 69----
813    $ git bisect good70$ git bisect good
814    Bisecting: 3 revisions left to test after this71Bisecting: 3 revisions left to test after this
815    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing72[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing
 73----
816 74 
817Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`:75Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`:
818 76 
. 77[source,console]
 78----
819    $ git bisect bad79$ git bisect bad
820    Bisecting: 1 revisions left to test after this80Bisecting: 1 revisions left to test after this
821    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table81[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table
 82----
822 83 
823This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug:84This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug:
824 85 
. 86[source,console]
 87----
825    $ git bisect good88$ git bisect good
826    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit89b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit
827    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c0490commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04
828    Author: PJ Hyett <pjhyett@example.com>91Author: PJ Hyett <pjhyett@example.com>
829    Date:   Tue Jan 27 14:48:32 2009 -080092Date:   Tue Jan 27 14:48:32 2009 -0800
830 93 
831        secure this thing94    secure this thing
832 95 
833    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d173096:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730
834    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config97f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config
 98----
835 99 
836When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state:100When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state:
837 101 
. 102[source,console]
 103----
838    $ git bisect reset104$ git bisect reset
 105----
839 106 
840This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second:107This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second:
841 108 
. 109[source,console]
 110----
842    $ git bisect start HEAD v1.0111$ git bisect start HEAD v1.0
843    $ git bisect run test-error.sh112$ git bisect run test-error.sh
 113----
844 114 
845Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you.115Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you.
.846  
847## Submodules ## 
848  
849It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. 
850  
851Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available. 
852  
853Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate. 
854  
855### Starting with Submodules ### 
856  
857Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
858  
859    $ git submodule add git://github.com/chneukirchen/rack.git rack 
860    Initialized empty Git repository in /opt/subtest/rack/.git/ 
861    remote: Counting objects: 3181, done. 
862    remote: Compressing objects: 100% (1534/1534), done. 
863    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
864    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. 
865    Resolving deltas: 100% (1951/1951), done. 
866  
867Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
868  
869    $ git status 
870    # On branch master 
871    # Changes to be committed: 
872    #   (use "git reset HEAD <file>..." to unstage) 
873    # 
874    #      new file:   .gitmodules 
875    #      new file:   rack 
876    # 
877  
878First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into: 
879  
880    $ cat .gitmodules 
881    [submodule "rack"] 
882          path = rack 
883          url = git://github.com/chneukirchen/rack.git 
884  
885If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. 
886  
887The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting: 
888  
889    $ git diff --cached rack 
890    diff --git a/rack b/rack 
891    new file mode 160000 
892    index 0000000..08d709f 
893    --- /dev/null 
894    +++ b/rack 
895    @@ -0,0 +1 @@ 
896    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
897  
898Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 
899  
900This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
901  
902When you commit, you see something like this: 
903  
904    $ git commit -m 'first commit with submodule rack' 
905    [master 0550271] first commit with submodule rack 
906     2 files changed, 4 insertions(+), 0 deletions(-) 
907     create mode 100644 .gitmodules 
908     create mode 160000 rack 
909  
910Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file. 
911  
912You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
913  
914    $ git log -1 
915    commit 0550271328a0038865aad6331e620cd7238601bb 
916    Author: Scott Chacon <schacon@gmail.com> 
917    Date:   Thu Apr 9 09:03:56 2009 -0700 
918  
919        first commit with submodule rack 
920    $ cd rack/ 
921    $ git log -1 
922    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
923    Author: Christian Neukirchen <chneukirchen@gmail.com> 
924    Date:   Wed Mar 25 14:49:04 2009 +0100 
925  
926        Document version change 
927  
928### Cloning a Project with Submodules ### 
929  
930Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet: 
931  
932    $ git clone git://github.com/schacon/myproject.git 
933    Initialized empty Git repository in /opt/myproject/.git/ 
934    remote: Counting objects: 6, done. 
935    remote: Compressing objects: 100% (4/4), done. 
936    remote: Total 6 (delta 0), reused 0 (delta 0) 
937    Receiving objects: 100% (6/6), done. 
938    $ cd myproject 
939    $ ls -l 
940    total 8 
941    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 
942    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 
943    $ ls rack/ 
944    $ 
945  
946The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject: 
947  
948    $ git submodule init 
949    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' 
950    $ git submodule update 
951    Initialized empty Git repository in /opt/myproject/rack/.git/ 
952    remote: Counting objects: 3181, done. 
953    remote: Compressing objects: 100% (1534/1534), done. 
954    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
955    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. 
956    Resolving deltas: 100% (1951/1951), done. 
957    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' 
958  
959Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 
960  
961    $ git merge origin/master 
962    Updating 0550271..85a3eee 
963    Fast forward 
964     rack |    2 +- 
965     1 files changed, 1 insertions(+), 1 deletions(-) 
966    [master*]$ git status 
967    # On branch master 
968    # Changes not staged for commit: 
969    #   (use "git add <file>..." to update what will be committed) 
970    #   (use "git checkout -- <file>..." to discard changes in working directory) 
971    # 
972    #      modified:   rack 
973    # 
974  
975You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
976  
977    $ git diff 
978    diff --git a/rack b/rack 
979    index 6c5e70b..08d709f 160000 
980    --- a/rack 
981    +++ b/rack 
982    @@ -1 +1 @@ 
983    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
984    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
985  
986This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
987  
988    $ git submodule update 
989    remote: Counting objects: 5, done. 
990    remote: Compressing objects: 100% (3/3), done. 
991    remote: Total 3 (delta 1), reused 2 (delta 0) 
992    Unpacking objects: 100% (3/3), done. 
993    From git@github.com:schacon/rack 
994       08d709f..6c5e70b  master     -> origin/master 
995    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
996  
997You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
998  
999One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1000  
1001    $ git submodule update 
1002    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1003    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1004  
1005You have to see who last changed the submodule: 
1006  
1007    $ git log -1 rack 
1008    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1009    Author: Scott Chacon <schacon@gmail.com> 
1010    Date:   Thu Apr 9 09:19:14 2009 -0700 
1011  
1012        added a submodule reference I will never make public. hahahahaha! 
1013  
1014Then, you e-mail that guy and yell at him. 
1015  
1016### Superprojects ### 
1017  
1018Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1019  
1020A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1021  
1022### Issues with Submodules ### 
1023  
1024Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 
1025  
1026To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1027  
1028Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory: 
1029  
1030    $ git checkout -b rack 
1031    Switched to a new branch "rack" 
1032    $ git submodule add git@github.com:schacon/rack.git rack 
1033    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1034    ... 
1035    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1036    Resolving deltas: 100% (1952/1952), done. 
1037    $ git commit -am 'added rack submodule' 
1038    [rack cc49a69] added rack submodule 
1039     2 files changed, 4 insertions(+), 0 deletions(-) 
1040     create mode 100644 .gitmodules 
1041     create mode 160000 rack 
1042    $ git checkout master 
1043    Switched to branch "master" 
1044    $ git status 
1045    # On branch master 
1046    # Untracked files: 
1047    #   (use "git add <file>..." to include in what will be committed) 
1048    # 
1049    #      rack/ 
1050  
1051You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 
1052  
1053The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you: 
1054  
1055    $ rm -Rf rack/ 
1056    $ git submodule add git@github.com:schacon/rack.git rack 
1057    'rack' already exists in the index 
1058  
1059You have to unstage the `rack` directory first. Then you can add the submodule: 
1060  
1061    $ git rm -r rack 
1062    $ git submodule add git@github.com:schacon/rack.git rack 
1063    Initialized empty Git repository in /opt/testsub/rack/.git/ 
1064    remote: Counting objects: 3184, done. 
1065    remote: Compressing objects: 100% (1465/1465), done. 
1066    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1067    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. 
1068    Resolving deltas: 100% (1952/1952), done. 
1069  
1070Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule — you get this error: 
1071  
1072    $ git checkout master 
1073    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 
1074  
1075You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1076  
1077    $ mv rack /tmp/ 
1078    $ git checkout master 
1079    Switched to branch "master" 
1080    $ ls 
1081    README  rack 
1082  
1083Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory. 
1084  
1085## Subtree Merging ## 
1086  
1087Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1088  
1089However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1090  
1091The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing. 
1092  
1093You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch: 
1094  
1095    $ git remote add rack_remote git@github.com:schacon/rack.git 
1096    $ git fetch rack_remote 
1097    warning: no common commits 
1098    remote: Counting objects: 3184, done. 
1099    remote: Compressing objects: 100% (1465/1465), done. 
1100    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1101    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. 
1102    Resolving deltas: 100% (1952/1952), done. 
1103    From git@github.com:schacon/rack 
1104     * [new branch]      build      -> rack_remote/build 
1105     * [new branch]      master     -> rack_remote/master 
1106     * [new branch]      rack-0.4   -> rack_remote/rack-0.4 
1107     * [new branch]      rack-0.9   -> rack_remote/rack-0.9 
1108    $ git checkout -b rack_branch rack_remote/master 
1109    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. 
1110    Switched to a new branch "rack_branch" 
1111  
1112Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots: 
1113  
1114    $ ls 
1115    AUTHORS        KNOWN-ISSUES   Rakefile      contrib        lib 
1116    COPYING        README         bin           example        test 
1117    $ git checkout master 
1118    Switched to branch "master" 
1119    $ ls 
1120    README 
1121  
1122You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: 
1123  
1124    $ git read-tree --prefix=rack/ -u rack_branch 
1125  
1126When you commit, it looks like you have all the Rack files under that subdirectory — as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling: 
1127  
1128    $ git checkout rack_branch 
1129    $ git pull 
1130  
1131Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option: 
1132  
1133    $ git checkout master 
1134    $ git merge --squash -s subtree --no-commit rack_branch 
1135    Squash commit -- not updating HEAD 
1136    Automatic merge went well; stopped before committing as requested 
1137  
1138All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite — make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream. 
1139  
1140To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch — to see if you need to merge them — you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to: 
1141  
1142    $ git diff-tree -p rack_branch 
1143  
1144Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run 
1145  
1146    $ git diff-tree -p rack_remote/master 
1147  
1148## Summary ## 
1149  
1150You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. 
1151 116 
+
+ diff --git a/book/07-git-tools/sections/diff-interactive-staging.htm b/book/07-git-tools/sections/diff-interactive-staging.htm new file mode 100644 index 00000000..55d749b3 --- /dev/null +++ b/book/07-git-tools/sections/diff-interactive-staging.htm @@ -0,0 +1,4835 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\interactive-staging.asc
.1# Git Tools # 1[[_interactive_staging]] 
2  
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. 
4  
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. 
6  
7## Revision Selection ## 
8  
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. 
10  
11### Single Revisions ### 
12  
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. 
14  
15### Short SHA ### 
16  
17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. 
18  
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: 
20  
21    $ git log 
22    commit 734713bc047d87bf7eac9674765ae793478c50d3 
23    Author: Scott Chacon <schacon@gmail.com> 
24    Date:   Fri Jan 2 18:32:33 2009 -0800 
25  
26        fixed refs handling, added gc auto, updated tests 
27  
28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
29    Merge: 1c002dd... 35cfb2b... 
30    Author: Scott Chacon <schacon@gmail.com> 
31    Date:   Thu Dec 11 15:08:43 2008 -0800 
32  
33        Merge commit 'phedders/rdocs' 
34  
35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
36    Author: Scott Chacon <schacon@gmail.com> 
37    Date:   Thu Dec 11 14:58:32 2008 -0800 
38  
39        added some blame and merge stuff 
40  
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): 
42  
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
44    $ git show 1c002dd4b536e7479f 
45    $ git show 1c002d 
46  
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: 
48  
49    $ git log --abbrev-commit --pretty=oneline 
50    ca82a6d changed the version number 
51    085bb3b removed unnecessary test code 
52    a11bef0 first commit 
53  
54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 
55  
56### A SHORT NOTE ABOUT SHA-1 ### 
57  
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? 
59  
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. 
61  
62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. 
63  
64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. 
65  
66### Branch References ### 
67  
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: 
69  
70    $ git show ca82a6dff817ec66f44342007202690a93763949 
71    $ git show topic1 
72  
73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. 
74  
75    $ git rev-parse topic1 
76    ca82a6dff817ec66f44342007202690a93763949 
77  
78### RefLog Shortnames ### 
79  
80One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. 
81  
82You can see your reflog by using `git reflog`: 
83  
84    $ git reflog 
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated 
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff 
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 
89    95df984 HEAD@{4}: commit: # This is a combination of two commits. 
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD 
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD 
92  
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: 
94  
95    $ git show HEAD@{5} 
96  
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type 
98  
99    $ git show master@{yesterday} 
100  
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. 
102  
103To see reflog information formatted like the `git log` output, you can run `git log -g`: 
104  
105    $ git log -g master 
106    commit 734713bc047d87bf7eac9674765ae793478c50d3 
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) 
108    Reflog message: commit: fixed refs handling, added gc auto, updated 
109    Author: Scott Chacon <schacon@gmail.com> 
110    Date:   Fri Jan 2 18:32:33 2009 -0800 
111  
112        fixed refs handling, added gc auto, updated tests 
113  
114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>) 
116    Reflog message: merge phedders/rdocs: Merge made by recursive. 
117    Author: Scott Chacon <schacon@gmail.com> 
118    Date:   Thu Dec 11 15:08:43 2008 -0800 
119  
120        Merge commit 'phedders/rdocs' 
121  
122It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. 
123  
124### Ancestry References ### 
125  
126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 
127Suppose you look at the history of your project: 
128  
129    $ git log --pretty=format:'%h %s' --graph 
130    * 734713b fixed refs handling, added gc auto, updated tests 
131    *   d921970 Merge commit 'phedders/rdocs' 
132    |\ 
133    | * 35cfb2b Some rdoc changes 
134    * | 1c002dd added some blame and merge stuff 
135    |/ 
136    * 1c36188 ignore *.gem 
137    * 9b29157 add open3_detach to gemspec file list 
138  
139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": 
140  
141    $ git show HEAD^ 
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
143    Merge: 1c002dd... 35cfb2b... 
144    Author: Scott Chacon <schacon@gmail.com> 
145    Date:   Thu Dec 11 15:08:43 2008 -0800 
146  
147        Merge commit 'phedders/rdocs' 
148  
149You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: 
150  
151    $ git show d921970^ 
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
153    Author: Scott Chacon <schacon@gmail.com> 
154    Date:   Thu Dec 11 14:58:32 2008 -0800 
155  
156        added some blame and merge stuff 
157  
158    $ git show d921970^2 
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 
160    Author: Paul Hedderly <paul+git@mjr.org> 
161    Date:   Wed Dec 10 22:22:03 2008 +0000 
162  
163        Some rdoc changes 
164  
165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be 
166  
167    $ git show HEAD~3 
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
169    Author: Tom Preston-Werner <tom@mojombo.com> 
170    Date:   Fri Nov 7 13:47:59 2008 -0500 
171  
172        ignore *.gem 
173  
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: 
175  
176    $ git show HEAD^^^ 
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
178    Author: Tom Preston-Werner <tom@mojombo.com> 
179    Date:   Fri Nov 7 13:47:59 2008 -0500 
180  
181        ignore *.gem 
182  
183You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. 
184  
185### Commit Ranges ### 
186  
187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 
188  
189#### Double Dot #### 
190  
191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. 
192  
193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
195  
196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: 
197  
198    $ git log master..experiment 
199    D 
200    C 
201  
202If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: 
203  
204    $ git log experiment..master 
205    F 
206    E 
207  
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: 
209  
210    $ git log origin/master..HEAD 
211  
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. 
213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. 
214  
215#### Multiple Points #### 
216  
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: 
218  
219    $ git log refA..refB 
220    $ git log ^refA refB 
221    $ git log refB --not refA 
222  
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: 
224  
225    $ git log refA refB ^refC 
226    $ git log refA refB --not refC 
227  
228This makes for a very powerful revision query system that should help you figure out what is in your branches. 
229  
230#### Triple Dot #### 
231  
232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. 
233If you want to see what is in `master` or `experiment` but not any common references, you can run 
234  
235    $ git log master...experiment 
236    F 
237    E 
238    D 
239    C 
240  
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. 
242  
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: 
244  
245    $ git log --left-right master...experiment 
246    < F 
247    < E 
248    > D 
249    > C 
250  
251With these tools, you can much more easily let Git know what commit or commits you want to inspect. 
252  
253## Interactive Staging ## 2=== Interactive Staging 
254 3 
.255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 4Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257 5 
. 6[source,console]
 7----
258    $ git add -i8$ git add -i
259               staged     unstaged path9           staged     unstaged path
260      1:    unchanged        +0/-1 TODO10  1:    unchanged        +0/-1 TODO
261      2:    unchanged        +1/-1 index.html11  2:    unchanged        +1/-1 index.html
262      3:    unchanged        +5/-1 lib/simplegit.rb12  3:    unchanged        +5/-1 lib/simplegit.rb
263 13 
264    *** Commands ***14*** Commands ***
265      1: status     2: update      3: revert     4: add untracked15  1: status     2: update      3: revert     4: add untracked
266      5: patch      6: diff        7: quit       8: help16  5: patch      6: diff        7: quit       8: help
267    What now>17What now>
 18----
268 19 
.269You can see that this command shows you a much different view of your staging area basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right.20You can see that this command shows you a much different view of your staging area basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right.
270 21 
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged.22After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged.
272 23 
.273### Staging and Unstaging Files ### 24==== Staging and Unstaging Files 
274 25 
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage:26If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage:
276 27 
. 28[source,console]
 29----
277    What now> 230What now> 2
278               staged     unstaged path31           staged     unstaged path
279      1:    unchanged        +0/-1 TODO32  1:    unchanged        +0/-1 TODO
280      2:    unchanged        +1/-1 index.html33  2:    unchanged        +1/-1 index.html
281      3:    unchanged        +5/-1 lib/simplegit.rb34  3:    unchanged        +5/-1 lib/simplegit.rb
282    Update>>35Update>>
 36----
283 37 
284To stage the TODO and index.html files, you can type the numbers:38To stage the TODO and index.html files, you can type the numbers:
285 39 
. 40[source,console]
 41----
286    Update>> 1,242Update>> 1,2
287               staged     unstaged path43           staged     unstaged path
288    * 1:    unchanged        +0/-1 TODO44* 1:    unchanged        +0/-1 TODO
289    * 2:    unchanged        +1/-1 index.html45* 2:    unchanged        +1/-1 index.html
290      3:    unchanged        +5/-1 lib/simplegit.rb46  3:    unchanged        +5/-1 lib/simplegit.rb
291    Update>>47Update>>
 48----
292 49 
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you:50The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you:
294 51 
. 52[source,console]
 53----
295    Update>>54Update>>
296    updated 2 paths55updated 2 paths
297 56 
298    *** Commands ***57*** Commands ***
299      1: status     2: update      3: revert     4: add untracked58  1: status     2: update      3: revert     4: add untracked
300      5: patch      6: diff        7: quit       8: help59  5: patch      6: diff        7: quit       8: help
301    What now> 160What now> 1
302               staged     unstaged path61           staged     unstaged path
303      1:        +0/-1      nothing TODO62  1:        +0/-1      nothing TODO
304      2:        +1/-1      nothing index.html63  2:        +1/-1      nothing index.html
305      3:    unchanged        +5/-1 lib/simplegit.rb64  3:    unchanged        +5/-1 lib/simplegit.rb
 65----
306 66 
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option:67Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option:
308 68 
.309    *** Commands *** 69[source,console] 
310      1: status     2: update      3: revert     4: add untracked 70---- 
311      5: patch      6: diff        7: quit       8: help 71*** Commands *** 
312    What now> 3 72  1: status     2: update      3: revert     4: add untracked 
313               staged     unstaged path 73  5: patch      6: diff        7: quit       8: help 
314      1:        +0/-1      nothing TODO 74What now> 3 
315      2:        +1/-1      nothing index.html 75           staged     unstaged path 
316      3:    unchanged        +5/-1 lib/simplegit.rb 76  1:        +0/-1      nothing TODO 
317    Revert>> 1 77  2:        +1/-1      nothing index.html 
318               staged     unstaged path 78  3:    unchanged        +5/-1 lib/simplegit.rb 
319    * 1:        +0/-1      nothing TODO 79Revert>> 1 
320      2:        +1/-1      nothing index.html 80           staged     unstaged path 
321      3:    unchanged        +5/-1 lib/simplegit.rb 81* 1:        +0/-1      nothing TODO 
322    Revert>> [enter] 82  2:        +1/-1      nothing index.html 
323    reverted one path 83  3:    unchanged        +5/-1 lib/simplegit.rb 
 84Revert>> [enter]
 85reverted one path
 86----
324 87 
325Looking at your Git status again, you can see that you’ve unstaged the TODO file:88Looking at your Git status again, you can see that you’ve unstaged the TODO file:
326 89 
. 90[source,console]
 91----
327    *** Commands ***92*** Commands ***
328      1: status     2: update      3: revert     4: add untracked93  1: status     2: update      3: revert     4: add untracked
329      5: patch      6: diff        7: quit       8: help94  5: patch      6: diff        7: quit       8: help
330    What now> 195What now> 1
331               staged     unstaged path96           staged     unstaged path
332      1:    unchanged        +0/-1 TODO97  1:    unchanged        +0/-1 TODO
333      2:        +1/-1      nothing index.html98  2:        +1/-1      nothing index.html
334      3:    unchanged        +5/-1 lib/simplegit.rb99  3:    unchanged        +5/-1 lib/simplegit.rb
 100----
335 101 
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line:102To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line:
337 103 
. 104[source,console]
 105----
338    *** Commands ***106*** Commands ***
339      1: status     2: update      3: revert     4: add untracked107  1: status     2: update      3: revert     4: add untracked
340      5: patch      6: diff        7: quit       8: help108  5: patch      6: diff        7: quit       8: help
341    What now> 6109What now> 6
342               staged     unstaged path110           staged     unstaged path
343      1:        +1/-1      nothing index.html111  1:        +1/-1      nothing index.html
344    Review diff>> 1112Review diff>> 1
345    diff --git a/index.html b/index.html113diff --git a/index.html b/index.html
346    index 4d07108..4335f49 100644114index 4d07108..4335f49 100644
347    --- a/index.html115--- a/index.html
348    +++ b/index.html116+++ b/index.html
349    @@ -16,7 +16,7 @@ Date Finder117@@ -16,7 +16,7 @@ Date Finder
350 118 
.351     <p id="out">...</p>119 <p id="out">...</p>
352 120 
.353    -<div id="footer">contact : support@github.com</div>121-<div id="footer">contact : support@github.com</div>
354    +<div id="footer">contact : email.support@github.com</div>122+<div id="footer">contact : email.support@github.com</div>
355 123 
.356     <script type="text/javascript">124 <script type="text/javascript">
 125----
357 126 
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily.127With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily.
359 128 
.360### Staging Patches ### 129==== Staging Patches 
361 130 
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one:131It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one:
363 132 
.364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 133[source,console] 
365    index dd5ecc4..57399e0 100644 134---- 
366    --- a/lib/simplegit.rb 135diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 136index dd5ecc4..57399e0 100644 
368    @@ -22,7 +22,7 @@ class SimpleGit 137--- a/lib/simplegit.rb 
369       end 138+++ b/lib/simplegit.rb 
370 139@@ -22,7 +22,7 @@ class SimpleGit 
371       def log(treeish = 'master') 140   end 
372    -    command("git log -n 25 #{treeish}") 141 
373    +    command("git log -n 30 #{treeish}")142   def log(treeish = 'master')
374       end 143-    command("git log -n 25 #{treeish}") 
375 144+    command("git log -n 30 #{treeish}") 
376       def blame(path) 145   end 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 146 
 147   def blame(path)
 148Stage this hunk [y,n,a,d,/,j,J,g,e,?]?
 149----
378 150 
379You have a lot of options at this point. Typing `?` shows a list of what you can do:151You have a lot of options at this point. Typing `?` shows a list of what you can do:
380 152 
.381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 153[source,console] 
382    y - stage this hunk 154---- 
383    n - do not stage this hunk 155Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
384    a - stage this and all the remaining hunks in the file 156y - stage this hunk 
385    d - do not stage this hunk nor any of the remaining hunks in the file 157n - do not stage this hunk 
386    g - select a hunk to go to 158a - stage this and all the remaining hunks in the file 
387    / - search for a hunk matching the given regex 159d - do not stage this hunk nor any of the remaining hunks in the file 
388    j - leave this hunk undecided, see next undecided hunk 160g - select a hunk to go to 
389    J - leave this hunk undecided, see next hunk 161/ - search for a hunk matching the given regex 
390    k - leave this hunk undecided, see previous undecided hunk162j - leave this hunk undecided, see next undecided hunk
391    K - leave this hunk undecided, see previous hunk163J - leave this hunk undecided, see next hunk
392    s - split the current hunk into smaller hunks 164k - leave this hunk undecided, see previous undecided hunk 
393    e - manually edit the current hunk165K - leave this hunk undecided, see previous hunk
394    ? - print help 166s - split the current hunk into smaller hunks 
 167e - manually edit the current hunk
 168? - print help
 169----
395 170 
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this:171Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this:
397 172 
. 173[source,console]
 174----
398    What now> 1175What now> 1
399               staged     unstaged path176           staged     unstaged path
400      1:    unchanged        +0/-1 TODO177  1:    unchanged        +0/-1 TODO
401      2:        +1/-1      nothing index.html178  2:        +1/-1      nothing index.html
402      3:        +1/-1        +4/-0 lib/simplegit.rb179  3:        +1/-1        +4/-0 lib/simplegit.rb
 180----
403 181 
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files.182The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files.
405 183 
.406Finally, you don’t need to be in interactive add mode to do the partial-file staging you can start the same script by using `git add -p` or `git add --patch` on the command line.184You also don’t need to be in interactive add mode to do the partial-file staging you can start the same script by using `git add -p` or `git add --patch` on the command line.
407 185 
.408 186Furthermore, you can use patch mode for partially resetting files with the `reset --patch` command, for checking out parts of files with the `checkout --patch` command and for stashing parts of files with the `stash save --patch` command. We'll go into more details on each of these as we get to more advanced usages of these commands. 
409## Stashing ## 
410  
411Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command. 
412  
413Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time. 
414  
415### Stashing Your Work ### 
416  
417To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state: 
418  
419    $ git status 
420    # On branch master 
421    # Changes to be committed: 
422    #   (use "git reset HEAD <file>..." to unstage) 
423    # 
424    #      modified:   index.html 
425    # 
426    # Changes not staged for commit: 
427    #   (use "git add <file>..." to update what will be committed) 
428    # 
429    #      modified:   lib/simplegit.rb 
430    # 
431  
432Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`: 
433  
434    $ git stash 
435    Saved working directory and index state \ 
436      "WIP on master: 049d078 added the index file" 
437    HEAD is now at 049d078 added the index file 
438    (To restore them type "git stash apply") 
439  
440Your working directory is clean: 
441  
442    $ git status 
443    # On branch master 
444    nothing to commit, working directory clean 
445  
446At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: 
447  
448    $ git stash list 
449    stash@{0}: WIP on master: 049d078 added the index file 
450    stash@{1}: WIP on master: c264051 Revert "added file_size" 
451    stash@{2}: WIP on master: 21d80a5 added number to log 
452  
453In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it: 
454  
455    $ git stash apply 
456    # On branch master 
457    # Changes not staged for commit: 
458    #   (use "git add <file>..." to update what will be committed) 
459    # 
460    #      modified:   index.html 
461    #      modified:   lib/simplegit.rb 
462    # 
463  
464You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly. 
465  
466The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position: 
467  
468    $ git stash apply --index 
469    # On branch master 
470    # Changes to be committed: 
471    #   (use "git reset HEAD <file>..." to unstage) 
472    # 
473    #      modified:   index.html 
474    # 
475    # Changes not staged for commit: 
476    #   (use "git add <file>..." to update what will be committed) 
477    # 
478    #      modified:   lib/simplegit.rb 
479    # 
480  
481The apply option only tries to apply the stashed work — you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove: 
482  
483    $ git stash list 
484    stash@{0}: WIP on master: 049d078 added the index file 
485    stash@{1}: WIP on master: c264051 Revert "added file_size" 
486    stash@{2}: WIP on master: 21d80a5 added number to log 
487    $ git stash drop stash@{0} 
488    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) 
489  
490You can also run `git stash pop` to apply the stash and then immediately drop it from your stack. 
491  
492### Un-applying a Stash ### 
493  
494In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
495  
496    $ git stash show -p stash@{0} | git apply -R 
497  
498Again, if you don’t specify a stash, Git assumes the most recent stash: 
499  
500    $ git stash show -p | git apply -R 
501  
502You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
503  
504    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
505    $ git stash apply 
506    $ #... work work work 
507    $ git stash-unapply 
508  
509### Creating a Branch from a Stash ### 
510  
511If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully: 
512  
513    $ git stash branch testchanges 
514    Switched to a new branch "testchanges" 
515    # On branch testchanges 
516    # Changes to be committed: 
517    #   (use "git reset HEAD <file>..." to unstage) 
518    # 
519    #      modified:   index.html 
520    # 
521    # Changes not staged for commit: 
522    #   (use "git add <file>..." to update what will be committed) 
523    # 
524    #      modified:   lib/simplegit.rb 
525    # 
526    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) 
527  
528This is a nice shortcut to recover stashed work easily and work on it in a new branch. 
529  
530## Rewriting History ## 
531  
532Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others. 
533  
534In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. 
535  
536### Changing the Last Commit ### 
537  
538Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 
539  
540If you only want to modify your last commit message, it’s very simple: 
541  
542    $ git commit --amend 
543  
544That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. 
545  
546If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. 
547  
548You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it. 
549  
550### Changing Multiple Commit Messages ### 
551  
552To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. 
553  
554For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: 
555  
556    $ git rebase -i HEAD~3 
557  
558Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change. 
559  
560Running this command gives you a list of commits in your text editor that looks something like this: 
561  
562    pick f7f3f6d changed my name a bit 
563    pick 310154e updated README formatting and added blame 
564    pick a5f4a0d added cat-file 
565  
566    # Rebase 710f0f8..a5f4a0d onto 710f0f8 
567    # 
568    # Commands: 
569    #  p, pick = use commit 
570    #  r, reword = use commit, but edit the commit message 
571    #  e, edit = use commit, but stop for amending 
572    #  s, squash = use commit, but meld into previous commit 
573    #  f, fixup = like "squash", but discard this commit's log message 
574    #  x, exec = run command (the rest of the line) using shell 
575    # 
576    # These lines can be re-ordered; they are executed from top to bottom. 
577    # 
578    # If you remove a line here THAT COMMIT WILL BE LOST. 
579    # 
580    # However, if you remove everything, the rebase will be aborted. 
581    # 
582    # Note that empty commits are commented out 
583  
584It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this: 
585  
586    $ git log --pretty=format:"%h %s" HEAD~3..HEAD 
587    a5f4a0d added cat-file 
588    310154e updated README formatting and added blame 
589    f7f3f6d changed my name a bit 
590  
591Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay. 
592  
593You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this: 
594  
595    edit f7f3f6d changed my name a bit 
596    pick 310154e updated README formatting and added blame 
597    pick a5f4a0d added cat-file 
598  
599When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message: 
600  
601<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  
602nor is the commit message. Please review  
603--> 
604  
605    $ git rebase -i HEAD~3 
606    Stopped at 7482e0d... updated the gemspec to hopefully work better 
607    You can amend the commit now, with 
608  
609           git commit --amend 
610  
611    Once you’re satisfied with your changes, run 
612  
613           git rebase --continue 
614  
615These instructions tell you exactly what to do. Type 
616  
617    $ git commit --amend 
618  
619Change the commit message, and exit the editor. Then, run 
620  
621    $ git rebase --continue 
622  
623This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished. 
624  
625### Reordering Commits ### 
626  
627You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this 
628  
629    pick f7f3f6d changed my name a bit 
630    pick 310154e updated README formatting and added blame 
631    pick a5f4a0d added cat-file 
632  
633to this: 
634  
635    pick 310154e updated README formatting and added blame 
636    pick f7f3f6d changed my name a bit 
637  
638When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely. 
639  
640### Squashing Commits ### 
641  
642It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message: 
643  
644    # 
645    # Commands: 
646    #  p, pick = use commit 
647    #  r, reword = use commit, but edit the commit message 
648    #  e, edit = use commit, but stop for amending 
649    #  s, squash = use commit, but meld into previous commit 
650    #  f, fixup = like "squash", but discard this commit's log message 
651    #  x, exec = run command (the rest of the line) using shell 
652    # 
653    # These lines can be re-ordered; they are executed from top to bottom. 
654    # 
655    # If you remove a line here THAT COMMIT WILL BE LOST. 
656    # 
657    # However, if you remove everything, the rebase will be aborted. 
658    # 
659    # Note that empty commits are commented out 
660  
661If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this: 
662  
663    pick f7f3f6d changed my name a bit 
664    squash 310154e updated README formatting and added blame 
665    squash a5f4a0d added cat-file 
666  
667When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages: 
668  
669    # This is a combination of 3 commits. 
670    # The first commit's message is: 
671    changed my name a bit 
672  
673    # This is the 2nd commit message: 
674  
675    updated README formatting and added blame 
676  
677    # This is the 3rd commit message: 
678  
679    added cat-file 
680  
681When you save that, you have a single commit that introduces the changes of all three previous commits. 
682  
683### Splitting a Commit ### 
684  
685Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit": 
686  
687    pick f7f3f6d changed my name a bit 
688    edit 310154e updated README formatting and added blame 
689    pick a5f4a0d added cat-file 
690  
691When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done: 
692  
693    $ git reset HEAD^ 
694    $ git add README 
695    $ git commit -m 'updated README formatting' 
696    $ git add lib/simplegit.rb 
697    $ git commit -m 'added blame' 
698    $ git rebase --continue 
699  
700Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this: 
701  
702    $ git log -4 --pretty=format:"%h %s" 
703    1c002dd added cat-file 
704    9b29157 added blame 
705    35cfb2b updated README formatting 
706    f3cc40e changed my name a bit 
707  
708Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository. 
709  
710### The Nuclear Option: filter-branch ### 
711  
712There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of. 
713  
714#### Removing a File from Every Commit #### 
715  
716This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`: 
717  
718    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 
719    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) 
720    Ref 'refs/heads/master' was rewritten 
721  
722The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`. 
723  
724You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. 
725  
726#### Making a Subdirectory the New Root #### 
727  
728Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too: 
729  
730    $ git filter-branch --subdirectory-filter trunk HEAD 
731    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) 
732    Ref 'refs/heads/master' was rewritten 
733  
734Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory. 
735  
736#### Changing E-Mail Addresses Globally #### 
737  
738Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`: 
739  
740    $ git filter-branch --commit-filter ' 
741            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; 
742            then 
743                    GIT_AUTHOR_NAME="Scott Chacon"; 
744                    GIT_AUTHOR_EMAIL="schacon@example.com"; 
745                    git commit-tree "$@"; 
746            else 
747                    git commit-tree "$@"; 
748            fi' HEAD 
749  
750This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address. 
751  
752### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
753  
754[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
755  
756See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
757  
758## Debugging with Git ## 
759  
760Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. 
761  
762### File Annotation ### 
763  
764If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: 
765  
766    $ git blame -L 12,22 simplegit.rb 
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master') 
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}") 
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end 
770    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15) 
771    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master') 
772    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}") 
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end 
774    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19) 
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path) 
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}") 
777    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end 
778  
779Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here. 
780  
781Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from: 
782  
783    $ git blame -C -L 141,153 GITPackUpload.m 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
786    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
787    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
793    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 
796    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 
797  
798This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. 
799  
800### Binary Search ### 
801  
802Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. 
803  
804Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: 
805  
806    $ git bisect start 
807    $ git bisect bad 
808    $ git bisect good v1.0 
809    Bisecting: 6 revisions left to test after this 
810    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo 
811  
812Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: 
813  
814    $ git bisect good 
815    Bisecting: 3 revisions left to test after this 
816    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing 
817  
818Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: 
819  
820    $ git bisect bad 
821    Bisecting: 1 revisions left to test after this 
822    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table 
823  
824This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: 
825  
826    $ git bisect good 
827    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit 
828    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 
829    Author: PJ Hyett <pjhyett@example.com> 
830    Date:   Tue Jan 27 14:48:32 2009 -0800 
831  
832        secure this thing 
833  
834    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 
835    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config 
836  
837When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: 
838  
839    $ git bisect reset 
840  
841This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: 
842  
843    $ git bisect start HEAD v1.0 
844    $ git bisect run test-error.sh 
845  
846Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. 
847  
848## Submodules ## 
849  
850It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. 
851  
852Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available. 
853  
854Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate. 
855  
856### Starting with Submodules ### 
857  
858Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
859  
860    $ git submodule add git://github.com/chneukirchen/rack.git rack 
861    Initialized empty Git repository in /opt/subtest/rack/.git/ 
862    remote: Counting objects: 3181, done. 
863    remote: Compressing objects: 100% (1534/1534), done. 
864    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
865    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. 
866    Resolving deltas: 100% (1951/1951), done. 
867  
868Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
869  
870    $ git status 
871    # On branch master 
872    # Changes to be committed: 
873    #   (use "git reset HEAD <file>..." to unstage) 
874    # 
875    #      new file:   .gitmodules 
876    #      new file:   rack 
877    # 
878  
879First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into: 
880  
881    $ cat .gitmodules 
882    [submodule "rack"] 
883          path = rack 
884          url = git://github.com/chneukirchen/rack.git 
885  
886If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. 
887  
888The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting: 
889  
890    $ git diff --cached rack 
891    diff --git a/rack b/rack 
892    new file mode 160000 
893    index 0000000..08d709f 
894    --- /dev/null 
895    +++ b/rack 
896    @@ -0,0 +1 @@ 
897    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
898  
899Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 
900  
901This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
902  
903When you commit, you see something like this: 
904  
905    $ git commit -m 'first commit with submodule rack' 
906    [master 0550271] first commit with submodule rack 
907     2 files changed, 4 insertions(+), 0 deletions(-) 
908     create mode 100644 .gitmodules 
909     create mode 160000 rack 
910  
911Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file. 
912  
913You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
914  
915    $ git log -1 
916    commit 0550271328a0038865aad6331e620cd7238601bb 
917    Author: Scott Chacon <schacon@gmail.com> 
918    Date:   Thu Apr 9 09:03:56 2009 -0700 
919  
920        first commit with submodule rack 
921    $ cd rack/ 
922    $ git log -1 
923    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
924    Author: Christian Neukirchen <chneukirchen@gmail.com> 
925    Date:   Wed Mar 25 14:49:04 2009 +0100 
926  
927        Document version change 
928  
929### Cloning a Project with Submodules ### 
930  
931Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet: 
932  
933    $ git clone git://github.com/schacon/myproject.git 
934    Initialized empty Git repository in /opt/myproject/.git/ 
935    remote: Counting objects: 6, done. 
936    remote: Compressing objects: 100% (4/4), done. 
937    remote: Total 6 (delta 0), reused 0 (delta 0) 
938    Receiving objects: 100% (6/6), done. 
939    $ cd myproject 
940    $ ls -l 
941    total 8 
942    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 
943    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 
944    $ ls rack/ 
945    $ 
946  
947The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject: 
948  
949    $ git submodule init 
950    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' 
951    $ git submodule update 
952    Initialized empty Git repository in /opt/myproject/rack/.git/ 
953    remote: Counting objects: 3181, done. 
954    remote: Compressing objects: 100% (1534/1534), done. 
955    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
956    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. 
957    Resolving deltas: 100% (1951/1951), done. 
958    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' 
959  
960Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 
961  
962    $ git merge origin/master 
963    Updating 0550271..85a3eee 
964    Fast forward 
965     rack |    2 +- 
966     1 files changed, 1 insertions(+), 1 deletions(-) 
967    [master*]$ git status 
968    # On branch master 
969    # Changes not staged for commit: 
970    #   (use "git add <file>..." to update what will be committed) 
971    #   (use "git checkout -- <file>..." to discard changes in working directory) 
972    # 
973    #      modified:   rack 
974    # 
975  
976You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
977  
978    $ git diff 
979    diff --git a/rack b/rack 
980    index 6c5e70b..08d709f 160000 
981    --- a/rack 
982    +++ b/rack 
983    @@ -1 +1 @@ 
984    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
985    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
986  
987This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
988  
989    $ git submodule update 
990    remote: Counting objects: 5, done. 
991    remote: Compressing objects: 100% (3/3), done. 
992    remote: Total 3 (delta 1), reused 2 (delta 0) 
993    Unpacking objects: 100% (3/3), done. 
994    From git@github.com:schacon/rack 
995       08d709f..6c5e70b  master     -> origin/master 
996    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
997  
998You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
999  
1000One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1001  
1002    $ git submodule update 
1003    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1004    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1005  
1006You have to see who last changed the submodule: 
1007  
1008    $ git log -1 rack 
1009    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1010    Author: Scott Chacon <schacon@gmail.com> 
1011    Date:   Thu Apr 9 09:19:14 2009 -0700 
1012  
1013        added a submodule reference I will never make public. hahahahaha! 
1014  
1015Then, you e-mail that guy and yell at him. 
1016  
1017### Superprojects ### 
1018  
1019Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1020  
1021A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1022  
1023### Issues with Submodules ### 
1024  
1025Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 
1026  
1027To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1028  
1029Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory: 
1030  
1031    $ git checkout -b rack 
1032    Switched to a new branch "rack" 
1033    $ git submodule add git@github.com:schacon/rack.git rack 
1034    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1035    ... 
1036    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1037    Resolving deltas: 100% (1952/1952), done. 
1038    $ git commit -am 'added rack submodule' 
1039    [rack cc49a69] added rack submodule 
1040     2 files changed, 4 insertions(+), 0 deletions(-) 
1041     create mode 100644 .gitmodules 
1042     create mode 160000 rack 
1043    $ git checkout master 
1044    Switched to branch "master" 
1045    $ git status 
1046    # On branch master 
1047    # Untracked files: 
1048    #   (use "git add <file>..." to include in what will be committed) 
1049    # 
1050    #      rack/ 
1051  
1052You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 
1053  
1054The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you: 
1055  
1056    $ rm -Rf rack/ 
1057    $ git submodule add git@github.com:schacon/rack.git rack 
1058    'rack' already exists in the index 
1059  
1060You have to unstage the `rack` directory first. Then you can add the submodule: 
1061  
1062    $ git rm -r rack 
1063    $ git submodule add git@github.com:schacon/rack.git rack 
1064    Initialized empty Git repository in /opt/testsub/rack/.git/ 
1065    remote: Counting objects: 3184, done. 
1066    remote: Compressing objects: 100% (1465/1465), done. 
1067    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1068    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. 
1069    Resolving deltas: 100% (1952/1952), done. 
1070  
1071Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule — you get this error: 
1072  
1073    $ git checkout master 
1074    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 
1075  
1076You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1077  
1078    $ mv rack /tmp/ 
1079    $ git checkout master 
1080    Switched to branch "master" 
1081    $ ls 
1082    README  rack 
1083  
1084Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory. 
1085  
1086## Subtree Merging ## 
1087  
1088Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1089  
1090However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1091  
1092The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing. 
1093  
1094You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch: 
1095  
1096    $ git remote add rack_remote git@github.com:schacon/rack.git 
1097    $ git fetch rack_remote 
1098    warning: no common commits 
1099    remote: Counting objects: 3184, done. 
1100    remote: Compressing objects: 100% (1465/1465), done. 
1101    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1102    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. 
1103    Resolving deltas: 100% (1952/1952), done. 
1104    From git@github.com:schacon/rack 
1105     * [new branch]      build      -> rack_remote/build 
1106     * [new branch]      master     -> rack_remote/master 
1107     * [new branch]      rack-0.4   -> rack_remote/rack-0.4 
1108     * [new branch]      rack-0.9   -> rack_remote/rack-0.9 
1109    $ git checkout -b rack_branch rack_remote/master 
1110    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. 
1111    Switched to a new branch "rack_branch" 
1112  
1113Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots: 
1114  
1115    $ ls 
1116    AUTHORS        KNOWN-ISSUES   Rakefile      contrib        lib 
1117    COPYING        README         bin           example        test 
1118    $ git checkout master 
1119    Switched to branch "master" 
1120    $ ls 
1121    README 
1122  
1123You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: 
1124  
1125    $ git read-tree --prefix=rack/ -u rack_branch 
1126  
1127When you commit, it looks like you have all the Rack files under that subdirectory — as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling: 
1128  
1129    $ git checkout rack_branch 
1130    $ git pull 
1131  
1132Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option: 
1133  
1134    $ git checkout master 
1135    $ git merge --squash -s subtree --no-commit rack_branch 
1136    Squash commit -- not updating HEAD 
1137    Automatic merge went well; stopped before committing as requested 
1138  
1139All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite — make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream. 
1140  
1141To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch — to see if you need to merge them — you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to: 
1142  
1143    $ git diff-tree -p rack_branch 
1144  
1145Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run 
1146  
1147    $ git diff-tree -p rack_remote/master 
1148  
1149## Summary ## 
1150  
1151You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. 
1152 187 
+
+ diff --git a/book/07-git-tools/sections/diff-revision-selection.htm b/book/07-git-tools/sections/diff-revision-selection.htm new file mode 100644 index 00000000..2634f468 --- /dev/null +++ b/book/07-git-tools/sections/diff-revision-selection.htm @@ -0,0 +1,5011 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\revision-selection.asc
.1# Git Tools # 1[[_revision_selection]] 
2  
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. 
4  
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. 
6  
7## Revision Selection ## 2=== Revision Selection 
8 3 
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know.4Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know.
10 5 
.11### Single Revisions ### 6==== Single Revisions 
12 7 
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit.8You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit.
14 9 
.15### Short SHA ### 10==== Short SHA 
16 11 
.17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous that is, only one object in the current repository begins with that partial SHA-1.12Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous that is, only one object in the current repository begins with that partial SHA-1.
18 13 
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality:14For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality:
20 15 
. 16[source,console]
 17----
21    $ git log18$ git log
22    commit 734713bc047d87bf7eac9674765ae793478c50d319commit 734713bc047d87bf7eac9674765ae793478c50d3
23    Author: Scott Chacon <schacon@gmail.com>20Author: Scott Chacon <schacon@gmail.com>
24    Date:   Fri Jan 2 18:32:33 2009 -080021Date:   Fri Jan 2 18:32:33 2009 -0800
25 22 
.26        fixed refs handling, added gc auto, updated tests23    fixed refs handling, added gc auto, updated tests
27 24 
.28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef25commit d921970aadf03b3cf0e71becdaab3147ba71cdef
29    Merge: 1c002dd... 35cfb2b...26Merge: 1c002dd... 35cfb2b...
30    Author: Scott Chacon <schacon@gmail.com>27Author: Scott Chacon <schacon@gmail.com>
31    Date:   Thu Dec 11 15:08:43 2008 -080028Date:   Thu Dec 11 15:08:43 2008 -0800
32 29 
.33        Merge commit 'phedders/rdocs'30    Merge commit 'phedders/rdocs'
34 31 
.35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b32commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
36    Author: Scott Chacon <schacon@gmail.com>33Author: Scott Chacon <schacon@gmail.com>
37    Date:   Thu Dec 11 14:58:32 2008 -080034Date:   Thu Dec 11 14:58:32 2008 -0800
38 35 
.39        added some blame and merge stuff36    added some blame and merge stuff
 37----
40 38 
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous):39In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous):
42 40 
. 41[source,console]
 42----
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b43$ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b
44    $ git show 1c002dd4b536e7479f44$ git show 1c002dd4b536e7479f
45    $ git show 1c002d45$ git show 1c002d
 46----
46 47 
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous:48Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous:
48 49 
. 50[source,console]
 51----
49    $ git log --abbrev-commit --pretty=oneline52$ git log --abbrev-commit --pretty=oneline
50    ca82a6d changed the version number53ca82a6d changed the version number
51    085bb3b removed unnecessary test code54085bb3b removed unnecessary test code
52    a11bef0 first commit55a11bef0 first commit
 56----
53 57 
.54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 58Generally, eight to ten characters are more than enough to be unique within a project. 
55 59 
. 60As an example, the Linux kernel, which is a pretty large project with over 450k commits and 3.6 million objects, has no two objects whose SHAs overlap more than the first 11 characters.
 61 
 62[NOTE]
56### A SHORT NOTE ABOUT SHA-1 ### 63.A SHORT NOTE ABOUT SHA-1 
 64====
57 65 
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then?66A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then?
59 67 
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object.68If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object.
61 69 
.62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth.70However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160))`. 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth.
63 71 
.64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night.72Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (3.6 million Git objects) and pushing it into one enormous Git repository, it would take roughly 2 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night.
 73====
65 74 
. 75[[_branch_references]]
66### Branch References ### 76==== Branch References 
67 77 
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`:78The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`:
69 79 
. 80[source,console]
 81----
70    $ git show ca82a6dff817ec66f44342007202690a9376394982$ git show ca82a6dff817ec66f44342007202690a93763949
71    $ git show topic183$ git show topic1
 84----
72 85 
.73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch.86If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see <<_git_internals>> for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch.
74 87 
. 88[source,console]
 89----
75    $ git rev-parse topic190$ git rev-parse topic1
76    ca82a6dff817ec66f44342007202690a9376394991ca82a6dff817ec66f44342007202690a93763949
 92----
77 93 
. 94[[_git_reflog]]
78### RefLog Shortnames ### 95==== RefLog Shortnames 
79 96 
.80One of the things Git does in the background while you’re working away is keep a reflog a log of where your HEAD and branch references have been for the last few months.97One of the things Git does in the background while you’re working away is keep a ``reflog'' a log of where your HEAD and branch references have been for the last few months.
81 98 
82You can see your reflog by using `git reflog`:99You can see your reflog by using `git reflog`:
83 100 
. 101[source,console]
 102----
84    $ git reflog103$ git reflog
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated104734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive.105d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive.
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff1061c002dd HEAD@{2}: commit: added some blame and merge stuff
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD1071c36188 HEAD@{3}: rebase -i (squash): updating HEAD
89    95df984 HEAD@{4}: commit: # This is a combination of two commits.10895df984 HEAD@{4}: commit: # This is a combination of two commits.
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD1091c36188 HEAD@{5}: rebase -i (squash): updating HEAD
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD1107e05da5 HEAD@{6}: rebase -i (pick): updating HEAD
 111----
92 112 
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output:113Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output:
94 114 
. 115[source,console]
 116----
95    $ git show HEAD@{5}117$ git show HEAD@{5}
 118----
96 119 
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type120You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type
98 121 
. 122[source,console]
 123----
99    $ git show master@{yesterday}124$ git show master@{yesterday}
 125----
100 126 
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months.127That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months.
102 128 
103To see reflog information formatted like the `git log` output, you can run `git log -g`:129To see reflog information formatted like the `git log` output, you can run `git log -g`:
104 130 
. 131[source,console]
 132----
105    $ git log -g master133$ git log -g master
106    commit 734713bc047d87bf7eac9674765ae793478c50d3134commit 734713bc047d87bf7eac9674765ae793478c50d3
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)135Reflog: master@{0} (Scott Chacon <schacon@gmail.com>)
108    Reflog message: commit: fixed refs handling, added gc auto, updated136Reflog message: commit: fixed refs handling, added gc auto, updated
109    Author: Scott Chacon <schacon@gmail.com>137Author: Scott Chacon <schacon@gmail.com>
110    Date:   Fri Jan 2 18:32:33 2009 -0800138Date:   Fri Jan 2 18:32:33 2009 -0800
111 139 
.112        fixed refs handling, added gc auto, updated tests140    fixed refs handling, added gc auto, updated tests
113 141 
.114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef142commit d921970aadf03b3cf0e71becdaab3147ba71cdef
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)143Reflog: master@{1} (Scott Chacon <schacon@gmail.com>)
116    Reflog message: merge phedders/rdocs: Merge made by recursive.144Reflog message: merge phedders/rdocs: Merge made by recursive.
117    Author: Scott Chacon <schacon@gmail.com>145Author: Scott Chacon <schacon@gmail.com>
118    Date:   Thu Dec 11 15:08:43 2008 -0800146Date:   Thu Dec 11 15:08:43 2008 -0800
119 147 
.120        Merge commit 'phedders/rdocs'148    Merge commit 'phedders/rdocs'
 149----
121 150 
.122It’s important to note that the reflog information is strictly local it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago if you cloned it five minutes ago, you’ll get no results.151It’s important to note that the reflog information is strictly local it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you'll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago if you cloned it five minutes ago, you’ll get no results.
123 152 
.124### Ancestry References ### 153==== Ancestry References 
125 154 
.126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 155The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit.  
127Suppose you look at the history of your project:156Suppose you look at the history of your project:
128 157 
. 158[source,console]
 159----
129    $ git log --pretty=format:'%h %s' --graph160$ git log --pretty=format:'%h %s' --graph
130    * 734713b fixed refs handling, added gc auto, updated tests161* 734713b fixed refs handling, added gc auto, updated tests
131    *   d921970 Merge commit 'phedders/rdocs'162*   d921970 Merge commit 'phedders/rdocs'
132    |\163|\
133    | * 35cfb2b Some rdoc changes164| * 35cfb2b Some rdoc changes
134    * | 1c002dd added some blame and merge stuff165* | 1c002dd added some blame and merge stuff
135    |/166|/
136    * 1c36188 ignore *.gem167* 1c36188 ignore *.gem
137    * 9b29157 add open3_detach to gemspec file list168* 9b29157 add open3_detach to gemspec file list
 169----
138 170 
.139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD":171Then, you can see the previous commit by specifying `HEAD^`, which means ``the parent of HEAD'':
140 172 
. 173[source,console]
 174----
141    $ git show HEAD^175$ git show HEAD^
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef176commit d921970aadf03b3cf0e71becdaab3147ba71cdef
143    Merge: 1c002dd... 35cfb2b...177Merge: 1c002dd... 35cfb2b...
144    Author: Scott Chacon <schacon@gmail.com>178Author: Scott Chacon <schacon@gmail.com>
145    Date:   Thu Dec 11 15:08:43 2008 -0800179Date:   Thu Dec 11 15:08:43 2008 -0800
146 180 
.147        Merge commit 'phedders/rdocs'181    Merge commit 'phedders/rdocs'
 182----
148 183 
.149You can also specify a number after the `^` for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in:184You can also specify a number after the `^` for example, `d921970^2` means ``the second parent of d921970.'' This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in:
150 185 
. 186[source,console]
 187----
151    $ git show d921970^188$ git show d921970^
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b189commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b
153    Author: Scott Chacon <schacon@gmail.com>190Author: Scott Chacon <schacon@gmail.com>
154    Date:   Thu Dec 11 14:58:32 2008 -0800191Date:   Thu Dec 11 14:58:32 2008 -0800
155 192 
.156        added some blame and merge stuff193    added some blame and merge stuff
157 194 
.158    $ git show d921970^2195$ git show d921970^2
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548196commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548
160    Author: Paul Hedderly <paul+git@mjr.org>197Author: Paul Hedderly <paul+git@mjr.org>
161    Date:   Wed Dec 10 22:22:03 2008 +0000198Date:   Wed Dec 10 22:22:03 2008 +0000
162 199 
.163        Some rdoc changes200    Some rdoc changes
 201----
164 202 
.165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be203The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means ``the first parent of the first parent,'' or ``the grandparent'' it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be
166 204 
. 205[source,console]
 206----
167    $ git show HEAD~3207$ git show HEAD~3
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d208commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
169    Author: Tom Preston-Werner <tom@mojombo.com>209Author: Tom Preston-Werner <tom@mojombo.com>
170    Date:   Fri Nov 7 13:47:59 2008 -0500210Date:   Fri Nov 7 13:47:59 2008 -0500
171 211 
.172        ignore *.gem212    ignore *.gem
 213----
173 214 
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent:215This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent:
175 216 
. 217[source,console]
 218----
176    $ git show HEAD^^^219$ git show HEAD^^^
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d220commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d
178    Author: Tom Preston-Werner <tom@mojombo.com>221Author: Tom Preston-Werner <tom@mojombo.com>
179    Date:   Fri Nov 7 13:47:59 2008 -0500222Date:   Fri Nov 7 13:47:59 2008 -0500
180 223 
.181        ignore *.gem224    ignore *.gem
 225----
182 226 
.183You can also combine these syntaxes you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on.227You can also combine these syntaxes you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on.
184 228 
. 229[[_commit_ranges]]
185### Commit Ranges ### 230==== Commit Ranges 
186 231 
.187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 232Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches if you have a lot of branches, you can use range specifications to answer questions such as, ``What work is on this branch that I haven’t yet merged into my main branch?'' 
188 233 
.189#### Double Dot #### 234===== Double Dot 
190 235 
.191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1.236The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like <<double_dot>>.
192 237 
.193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
 238[[double_dot]]
 239.Example history for range selection.
 240image::images/double-dot.png[Example history for range selection.]
195 241 
.196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display:242You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` that means ``all commits reachable by experiment that aren’t reachable by master.'' For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display:
197 243 
. 244[source,console]
 245----
198    $ git log master..experiment246$ git log master..experiment
199    D247D
200    C248C
 249----
201 250 
.202If, on the other hand, you want to see the opposite all commits in `master` that aren’t in `experiment` you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`:251If, on the other hand, you want to see the opposite all commits in `master` that aren’t in `experiment` you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`:
203 252 
. 253[source,console]
 254----
204    $ git log experiment..master255$ git log experiment..master
205    F256F
206    E257E
 258----
207 259 
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote:260This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote:
209 261 
. 262[source,console]
 263----
210    $ git log origin/master..HEAD264$ git log origin/master..HEAD
 265----
211 266 
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server.267This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server.
.213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` Git substitutes HEAD if one side is missing.268You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` Git substitutes HEAD if one side is missing.
214 269 
.215#### Multiple Points #### 270===== Multiple Points 
216 271 
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent:272The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent:
218 273 
. 274[source,console]
 275----
219    $ git log refA..refB276$ git log refA..refB
220    $ git log ^refA refB277$ git log ^refA refB
221    $ git log refB --not refA278$ git log refB --not refA
 279----
222 280 
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these:281This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these:
224 282 
. 283[source,console]
 284----
225    $ git log refA refB ^refC285$ git log refA refB ^refC
226    $ git log refA refB --not refC286$ git log refA refB --not refC
 287----
227 288 
228This makes for a very powerful revision query system that should help you figure out what is in your branches.289This makes for a very powerful revision query system that should help you figure out what is in your branches.
229 290 
. 291[[_triple_dot]]
230#### Triple Dot #### 292===== Triple Dot 
231 293 
.232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1.294The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in <<double_dot>>.
233If you want to see what is in `master` or `experiment` but not any common references, you can run295If you want to see what is in `master` or `experiment` but not any common references, you can run
234 296 
. 297[source,console]
 298----
235    $ git log master...experiment299$ git log master...experiment
236    F300F
237    E301E
238    D302D
239    C303C
 304----
240 305 
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering.306Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering.
242 307 
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful:308A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful:
244 309 
. 310[source,console]
 311----
245    $ git log --left-right master...experiment312$ git log --left-right master...experiment
246    < F313< F
247    < E314< E
248    > D315> D
249    > C316> C
 317----
250 318 
251With these tools, you can much more easily let Git know what commit or commits you want to inspect.319With these tools, you can much more easily let Git know what commit or commits you want to inspect.
.252  
253## Interactive Staging ## 
254  
255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257  
258    $ git add -i 
259               staged     unstaged path 
260      1:    unchanged        +0/-1 TODO 
261      2:    unchanged        +1/-1 index.html 
262      3:    unchanged        +5/-1 lib/simplegit.rb 
263  
264    *** Commands *** 
265      1: status     2: update      3: revert     4: add untracked 
266      5: patch      6: diff        7: quit       8: help 
267    What now> 
268  
269You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. 
270  
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. 
272  
273### Staging and Unstaging Files ### 
274  
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: 
276  
277    What now> 2 
278               staged     unstaged path 
279      1:    unchanged        +0/-1 TODO 
280      2:    unchanged        +1/-1 index.html 
281      3:    unchanged        +5/-1 lib/simplegit.rb 
282    Update>> 
283  
284To stage the TODO and index.html files, you can type the numbers: 
285  
286    Update>> 1,2 
287               staged     unstaged path 
288    * 1:    unchanged        +0/-1 TODO 
289    * 2:    unchanged        +1/-1 index.html 
290      3:    unchanged        +5/-1 lib/simplegit.rb 
291    Update>> 
292  
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: 
294  
295    Update>> 
296    updated 2 paths 
297  
298    *** Commands *** 
299      1: status     2: update      3: revert     4: add untracked 
300      5: patch      6: diff        7: quit       8: help 
301    What now> 1 
302               staged     unstaged path 
303      1:        +0/-1      nothing TODO 
304      2:        +1/-1      nothing index.html 
305      3:    unchanged        +5/-1 lib/simplegit.rb 
306  
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: 
308  
309    *** Commands *** 
310      1: status     2: update      3: revert     4: add untracked 
311      5: patch      6: diff        7: quit       8: help 
312    What now> 3 
313               staged     unstaged path 
314      1:        +0/-1      nothing TODO 
315      2:        +1/-1      nothing index.html 
316      3:    unchanged        +5/-1 lib/simplegit.rb 
317    Revert>> 1 
318               staged     unstaged path 
319    * 1:        +0/-1      nothing TODO 
320      2:        +1/-1      nothing index.html 
321      3:    unchanged        +5/-1 lib/simplegit.rb 
322    Revert>> [enter] 
323    reverted one path 
324  
325Looking at your Git status again, you can see that you’ve unstaged the TODO file: 
326  
327    *** Commands *** 
328      1: status     2: update      3: revert     4: add untracked 
329      5: patch      6: diff        7: quit       8: help 
330    What now> 1 
331               staged     unstaged path 
332      1:    unchanged        +0/-1 TODO 
333      2:        +1/-1      nothing index.html 
334      3:    unchanged        +5/-1 lib/simplegit.rb 
335  
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: 
337  
338    *** Commands *** 
339      1: status     2: update      3: revert     4: add untracked 
340      5: patch      6: diff        7: quit       8: help 
341    What now> 6 
342               staged     unstaged path 
343      1:        +1/-1      nothing index.html 
344    Review diff>> 1 
345    diff --git a/index.html b/index.html 
346    index 4d07108..4335f49 100644 
347    --- a/index.html 
348    +++ b/index.html 
349    @@ -16,7 +16,7 @@ Date Finder 
350  
351     <p id="out">...</p> 
352  
353    -<div id="footer">contact : support@github.com</div> 
354    +<div id="footer">contact : email.support@github.com</div> 
355  
356     <script type="text/javascript"> 
357  
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily. 
359  
360### Staging Patches ### 
361  
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: 
363  
364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
365    index dd5ecc4..57399e0 100644 
366    --- a/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 
368    @@ -22,7 +22,7 @@ class SimpleGit 
369       end 
370  
371       def log(treeish = 'master') 
372    -    command("git log -n 25 #{treeish}") 
373    +    command("git log -n 30 #{treeish}") 
374       end 
375  
376       def blame(path) 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 
378  
379You have a lot of options at this point. Typing `?` shows a list of what you can do: 
380  
381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
382    y - stage this hunk 
383    n - do not stage this hunk 
384    a - stage this and all the remaining hunks in the file 
385    d - do not stage this hunk nor any of the remaining hunks in the file 
386    g - select a hunk to go to 
387    / - search for a hunk matching the given regex 
388    j - leave this hunk undecided, see next undecided hunk 
389    J - leave this hunk undecided, see next hunk 
390    k - leave this hunk undecided, see previous undecided hunk 
391    K - leave this hunk undecided, see previous hunk 
392    s - split the current hunk into smaller hunks 
393    e - manually edit the current hunk 
394    ? - print help 
395  
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: 
397  
398    What now> 1 
399               staged     unstaged path 
400      1:    unchanged        +0/-1 TODO 
401      2:        +1/-1      nothing index.html 
402      3:        +1/-1        +4/-0 lib/simplegit.rb 
403  
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. 
405  
406Finally, you don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using `git add -p` or `git add --patch` on the command line. 
407  
408## Stashing ## 
409  
410Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command. 
411  
412Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time. 
413  
414### Stashing Your Work ### 
415  
416To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state: 
417  
418    $ git status 
419    # On branch master 
420    # Changes to be committed: 
421    #   (use "git reset HEAD <file>..." to unstage) 
422    # 
423    #      modified:   index.html 
424    # 
425    # Changes not staged for commit: 
426    #   (use "git add <file>..." to update what will be committed) 
427    # 
428    #      modified:   lib/simplegit.rb 
429    # 
430  
431Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`: 
432  
433    $ git stash 
434    Saved working directory and index state \ 
435      "WIP on master: 049d078 added the index file" 
436    HEAD is now at 049d078 added the index file 
437    (To restore them type "git stash apply") 
438  
439Your working directory is clean: 
440  
441    $ git status 
442    # On branch master 
443    nothing to commit, working directory clean 
444  
445At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: 
446  
447    $ git stash list 
448    stash@{0}: WIP on master: 049d078 added the index file 
449    stash@{1}: WIP on master: c264051 Revert "added file_size" 
450    stash@{2}: WIP on master: 21d80a5 added number to log 
451  
452In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it: 
453  
454    $ git stash apply 
455    # On branch master 
456    # Changes not staged for commit: 
457    #   (use "git add <file>..." to update what will be committed) 
458    # 
459    #      modified:   index.html 
460    #      modified:   lib/simplegit.rb 
461    # 
462  
463You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly. 
464  
465The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position: 
466  
467    $ git stash apply --index 
468    # On branch master 
469    # Changes to be committed: 
470    #   (use "git reset HEAD <file>..." to unstage) 
471    # 
472    #      modified:   index.html 
473    # 
474    # Changes not staged for commit: 
475    #   (use "git add <file>..." to update what will be committed) 
476    # 
477    #      modified:   lib/simplegit.rb 
478    # 
479  
480The apply option only tries to apply the stashed work — you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove: 
481  
482    $ git stash list 
483    stash@{0}: WIP on master: 049d078 added the index file 
484    stash@{1}: WIP on master: c264051 Revert "added file_size" 
485    stash@{2}: WIP on master: 21d80a5 added number to log 
486    $ git stash drop stash@{0} 
487    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) 
488  
489You can also run `git stash pop` to apply the stash and then immediately drop it from your stack. 
490  
491### Un-applying a Stash ### 
492  
493In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
494  
495    $ git stash show -p stash@{0} | git apply -R 
496  
497Again, if you don’t specify a stash, Git assumes the most recent stash: 
498  
499    $ git stash show -p | git apply -R 
500  
501You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
502  
503    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
504    $ git stash apply 
505    $ #... work work work 
506    $ git stash-unapply 
507  
508### Creating a Branch from a Stash ### 
509  
510If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully: 
511  
512    $ git stash branch testchanges 
513    Switched to a new branch "testchanges" 
514    # On branch testchanges 
515    # Changes to be committed: 
516    #   (use "git reset HEAD <file>..." to unstage) 
517    # 
518    #      modified:   index.html 
519    # 
520    # Changes not staged for commit: 
521    #   (use "git add <file>..." to update what will be committed) 
522    # 
523    #      modified:   lib/simplegit.rb 
524    # 
525    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) 
526  
527This is a nice shortcut to recover stashed work easily and work on it in a new branch. 
528  
529## Rewriting History ## 
530  
531Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others. 
532  
533In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. 
534  
535### Changing the Last Commit ### 
536  
537Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 
538  
539If you only want to modify your last commit message, it’s very simple: 
540  
541    $ git commit --amend 
542  
543That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. 
544  
545If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. 
546  
547You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it. 
548  
549### Changing Multiple Commit Messages ### 
550  
551To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. 
552  
553For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: 
554  
555    $ git rebase -i HEAD~3 
556  
557Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change. 
558  
559Running this command gives you a list of commits in your text editor that looks something like this: 
560  
561    pick f7f3f6d changed my name a bit 
562    pick 310154e updated README formatting and added blame 
563    pick a5f4a0d added cat-file 
564  
565    # Rebase 710f0f8..a5f4a0d onto 710f0f8 
566    # 
567    # Commands: 
568    #  p, pick = use commit 
569    #  r, reword = use commit, but edit the commit message 
570    #  e, edit = use commit, but stop for amending 
571    #  s, squash = use commit, but meld into previous commit 
572    #  f, fixup = like "squash", but discard this commit's log message 
573    #  x, exec = run command (the rest of the line) using shell 
574    # 
575    # These lines can be re-ordered; they are executed from top to bottom. 
576    # 
577    # If you remove a line here THAT COMMIT WILL BE LOST. 
578    # 
579    # However, if you remove everything, the rebase will be aborted. 
580    # 
581    # Note that empty commits are commented out 
582  
583It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this: 
584  
585    $ git log --pretty=format:"%h %s" HEAD~3..HEAD 
586    a5f4a0d added cat-file 
587    310154e updated README formatting and added blame 
588    f7f3f6d changed my name a bit 
589  
590Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay. 
591  
592You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this: 
593  
594    edit f7f3f6d changed my name a bit 
595    pick 310154e updated README formatting and added blame 
596    pick a5f4a0d added cat-file 
597  
598When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message: 
599  
600<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  
601nor is the commit message. Please review  
602--> 
603  
604    $ git rebase -i HEAD~3 
605    Stopped at 7482e0d... updated the gemspec to hopefully work better 
606    You can amend the commit now, with 
607  
608           git commit --amend 
609  
610    Once you’re satisfied with your changes, run 
611  
612           git rebase --continue 
613  
614These instructions tell you exactly what to do. Type 
615  
616    $ git commit --amend 
617  
618Change the commit message, and exit the editor. Then, run 
619  
620    $ git rebase --continue 
621  
622This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished. 
623  
624### Reordering Commits ### 
625  
626You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this 
627  
628    pick f7f3f6d changed my name a bit 
629    pick 310154e updated README formatting and added blame 
630    pick a5f4a0d added cat-file 
631  
632to this: 
633  
634    pick 310154e updated README formatting and added blame 
635    pick f7f3f6d changed my name a bit 
636  
637When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely. 
638  
639### Squashing Commits ### 
640  
641It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message: 
642  
643    # 
644    # Commands: 
645    #  p, pick = use commit 
646    #  r, reword = use commit, but edit the commit message 
647    #  e, edit = use commit, but stop for amending 
648    #  s, squash = use commit, but meld into previous commit 
649    #  f, fixup = like "squash", but discard this commit's log message 
650    #  x, exec = run command (the rest of the line) using shell 
651    # 
652    # These lines can be re-ordered; they are executed from top to bottom. 
653    # 
654    # If you remove a line here THAT COMMIT WILL BE LOST. 
655    # 
656    # However, if you remove everything, the rebase will be aborted. 
657    # 
658    # Note that empty commits are commented out 
659  
660If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this: 
661  
662    pick f7f3f6d changed my name a bit 
663    squash 310154e updated README formatting and added blame 
664    squash a5f4a0d added cat-file 
665  
666When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages: 
667  
668    # This is a combination of 3 commits. 
669    # The first commit's message is: 
670    changed my name a bit 
671  
672    # This is the 2nd commit message: 
673  
674    updated README formatting and added blame 
675  
676    # This is the 3rd commit message: 
677  
678    added cat-file 
679  
680When you save that, you have a single commit that introduces the changes of all three previous commits. 
681  
682### Splitting a Commit ### 
683  
684Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit": 
685  
686    pick f7f3f6d changed my name a bit 
687    edit 310154e updated README formatting and added blame 
688    pick a5f4a0d added cat-file 
689  
690When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done: 
691  
692    $ git reset HEAD^ 
693    $ git add README 
694    $ git commit -m 'updated README formatting' 
695    $ git add lib/simplegit.rb 
696    $ git commit -m 'added blame' 
697    $ git rebase --continue 
698  
699Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this: 
700  
701    $ git log -4 --pretty=format:"%h %s" 
702    1c002dd added cat-file 
703    9b29157 added blame 
704    35cfb2b updated README formatting 
705    f3cc40e changed my name a bit 
706  
707Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository. 
708  
709### The Nuclear Option: filter-branch ### 
710  
711There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of. 
712  
713#### Removing a File from Every Commit #### 
714  
715This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`: 
716  
717    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 
718    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) 
719    Ref 'refs/heads/master' was rewritten 
720  
721The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`. 
722  
723You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. 
724  
725#### Making a Subdirectory the New Root #### 
726  
727Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too: 
728  
729    $ git filter-branch --subdirectory-filter trunk HEAD 
730    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) 
731    Ref 'refs/heads/master' was rewritten 
732  
733Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory. 
734  
735#### Changing E-Mail Addresses Globally #### 
736  
737Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`: 
738  
739    $ git filter-branch --commit-filter ' 
740            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; 
741            then 
742                    GIT_AUTHOR_NAME="Scott Chacon"; 
743                    GIT_AUTHOR_EMAIL="schacon@example.com"; 
744                    git commit-tree "$@"; 
745            else 
746                    git commit-tree "$@"; 
747            fi' HEAD 
748  
749This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address. 
750  
751### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
752  
753[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
754  
755See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
756  
757## Debugging with Git ## 
758  
759Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. 
760  
761### File Annotation ### 
762  
763If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: 
764  
765    $ git blame -L 12,22 simplegit.rb 
766    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master') 
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}") 
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end 
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15) 
770    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master') 
771    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}") 
772    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end 
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19) 
774    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path) 
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}") 
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end 
777  
778Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here. 
779  
780Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from: 
781  
782    $ git blame -C -L 141,153 GITPackUpload.m 
783    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
786    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
787    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
793    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 
796  
797This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. 
798  
799### Binary Search ### 
800  
801Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. 
802  
803Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: 
804  
805    $ git bisect start 
806    $ git bisect bad 
807    $ git bisect good v1.0 
808    Bisecting: 6 revisions left to test after this 
809    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo 
810  
811Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: 
812  
813    $ git bisect good 
814    Bisecting: 3 revisions left to test after this 
815    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing 
816  
817Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: 
818  
819    $ git bisect bad 
820    Bisecting: 1 revisions left to test after this 
821    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table 
822  
823This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: 
824  
825    $ git bisect good 
826    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit 
827    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 
828    Author: PJ Hyett <pjhyett@example.com> 
829    Date:   Tue Jan 27 14:48:32 2009 -0800 
830  
831        secure this thing 
832  
833    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 
834    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config 
835  
836When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: 
837  
838    $ git bisect reset 
839  
840This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: 
841  
842    $ git bisect start HEAD v1.0 
843    $ git bisect run test-error.sh 
844  
845Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. 
846  
847## Submodules ## 
848  
849It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. 
850  
851Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available. 
852  
853Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate. 
854  
855### Starting with Submodules ### 
856  
857Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
858  
859    $ git submodule add git://github.com/chneukirchen/rack.git rack 
860    Initialized empty Git repository in /opt/subtest/rack/.git/ 
861    remote: Counting objects: 3181, done. 
862    remote: Compressing objects: 100% (1534/1534), done. 
863    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
864    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. 
865    Resolving deltas: 100% (1951/1951), done. 
866  
867Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
868  
869    $ git status 
870    # On branch master 
871    # Changes to be committed: 
872    #   (use "git reset HEAD <file>..." to unstage) 
873    # 
874    #      new file:   .gitmodules 
875    #      new file:   rack 
876    # 
877  
878First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into: 
879  
880    $ cat .gitmodules 
881    [submodule "rack"] 
882          path = rack 
883          url = git://github.com/chneukirchen/rack.git 
884  
885If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. 
886  
887The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting: 
888  
889    $ git diff --cached rack 
890    diff --git a/rack b/rack 
891    new file mode 160000 
892    index 0000000..08d709f 
893    --- /dev/null 
894    +++ b/rack 
895    @@ -0,0 +1 @@ 
896    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
897  
898Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 
899  
900This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
901  
902When you commit, you see something like this: 
903  
904    $ git commit -m 'first commit with submodule rack' 
905    [master 0550271] first commit with submodule rack 
906     2 files changed, 4 insertions(+), 0 deletions(-) 
907     create mode 100644 .gitmodules 
908     create mode 160000 rack 
909  
910Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file. 
911  
912You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
913  
914    $ git log -1 
915    commit 0550271328a0038865aad6331e620cd7238601bb 
916    Author: Scott Chacon <schacon@gmail.com> 
917    Date:   Thu Apr 9 09:03:56 2009 -0700 
918  
919        first commit with submodule rack 
920    $ cd rack/ 
921    $ git log -1 
922    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
923    Author: Christian Neukirchen <chneukirchen@gmail.com> 
924    Date:   Wed Mar 25 14:49:04 2009 +0100 
925  
926        Document version change 
927  
928### Cloning a Project with Submodules ### 
929  
930Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet: 
931  
932    $ git clone git://github.com/schacon/myproject.git 
933    Initialized empty Git repository in /opt/myproject/.git/ 
934    remote: Counting objects: 6, done. 
935    remote: Compressing objects: 100% (4/4), done. 
936    remote: Total 6 (delta 0), reused 0 (delta 0) 
937    Receiving objects: 100% (6/6), done. 
938    $ cd myproject 
939    $ ls -l 
940    total 8 
941    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 
942    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 
943    $ ls rack/ 
944    $ 
945  
946The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject: 
947  
948    $ git submodule init 
949    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' 
950    $ git submodule update 
951    Initialized empty Git repository in /opt/myproject/rack/.git/ 
952    remote: Counting objects: 3181, done. 
953    remote: Compressing objects: 100% (1534/1534), done. 
954    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
955    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. 
956    Resolving deltas: 100% (1951/1951), done. 
957    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' 
958  
959Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 
960  
961    $ git merge origin/master 
962    Updating 0550271..85a3eee 
963    Fast forward 
964     rack |    2 +- 
965     1 files changed, 1 insertions(+), 1 deletions(-) 
966    [master*]$ git status 
967    # On branch master 
968    # Changes not staged for commit: 
969    #   (use "git add <file>..." to update what will be committed) 
970    #   (use "git checkout -- <file>..." to discard changes in working directory) 
971    # 
972    #      modified:   rack 
973    # 
974  
975You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
976  
977    $ git diff 
978    diff --git a/rack b/rack 
979    index 6c5e70b..08d709f 160000 
980    --- a/rack 
981    +++ b/rack 
982    @@ -1 +1 @@ 
983    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
984    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
985  
986This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
987  
988    $ git submodule update 
989    remote: Counting objects: 5, done. 
990    remote: Compressing objects: 100% (3/3), done. 
991    remote: Total 3 (delta 1), reused 2 (delta 0) 
992    Unpacking objects: 100% (3/3), done. 
993    From git@github.com:schacon/rack 
994       08d709f..6c5e70b  master     -> origin/master 
995    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
996  
997You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
998  
999One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1000  
1001    $ git submodule update 
1002    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1003    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1004  
1005You have to see who last changed the submodule: 
1006  
1007    $ git log -1 rack 
1008    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1009    Author: Scott Chacon <schacon@gmail.com> 
1010    Date:   Thu Apr 9 09:19:14 2009 -0700 
1011  
1012        added a submodule reference I will never make public. hahahahaha! 
1013  
1014Then, you e-mail that guy and yell at him. 
1015  
1016### Superprojects ### 
1017  
1018Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1019  
1020A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1021  
1022### Issues with Submodules ### 
1023  
1024Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 
1025  
1026To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1027  
1028Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory: 
1029  
1030    $ git checkout -b rack 
1031    Switched to a new branch "rack" 
1032    $ git submodule add git@github.com:schacon/rack.git rack 
1033    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1034    ... 
1035    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1036    Resolving deltas: 100% (1952/1952), done. 
1037    $ git commit -am 'added rack submodule' 
1038    [rack cc49a69] added rack submodule 
1039     2 files changed, 4 insertions(+), 0 deletions(-) 
1040     create mode 100644 .gitmodules 
1041     create mode 160000 rack 
1042    $ git checkout master 
1043    Switched to branch "master" 
1044    $ git status 
1045    # On branch master 
1046    # Untracked files: 
1047    #   (use "git add <file>..." to include in what will be committed) 
1048    # 
1049    #      rack/ 
1050  
1051You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 
1052  
1053The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you: 
1054  
1055    $ rm -Rf rack/ 
1056    $ git submodule add git@github.com:schacon/rack.git rack 
1057    'rack' already exists in the index 
1058  
1059You have to unstage the `rack` directory first. Then you can add the submodule: 
1060  
1061    $ git rm -r rack 
1062    $ git submodule add git@github.com:schacon/rack.git rack 
1063    Initialized empty Git repository in /opt/testsub/rack/.git/ 
1064    remote: Counting objects: 3184, done. 
1065    remote: Compressing objects: 100% (1465/1465), done. 
1066    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1067    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. 
1068    Resolving deltas: 100% (1952/1952), done. 
1069  
1070Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule — you get this error: 
1071  
1072    $ git checkout master 
1073    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 
1074  
1075You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1076  
1077    $ mv rack /tmp/ 
1078    $ git checkout master 
1079    Switched to branch "master" 
1080    $ ls 
1081    README  rack 
1082  
1083Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory. 
1084  
1085## Subtree Merging ## 
1086  
1087Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1088  
1089However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1090  
1091The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing. 
1092  
1093You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch: 
1094  
1095    $ git remote add rack_remote git@github.com:schacon/rack.git 
1096    $ git fetch rack_remote 
1097    warning: no common commits 
1098    remote: Counting objects: 3184, done. 
1099    remote: Compressing objects: 100% (1465/1465), done. 
1100    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1101    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. 
1102    Resolving deltas: 100% (1952/1952), done. 
1103    From git@github.com:schacon/rack 
1104     * [new branch]      build      -> rack_remote/build 
1105     * [new branch]      master     -> rack_remote/master 
1106     * [new branch]      rack-0.4   -> rack_remote/rack-0.4 
1107     * [new branch]      rack-0.9   -> rack_remote/rack-0.9 
1108    $ git checkout -b rack_branch rack_remote/master 
1109    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. 
1110    Switched to a new branch "rack_branch" 
1111  
1112Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots: 
1113  
1114    $ ls 
1115    AUTHORS        KNOWN-ISSUES   Rakefile      contrib        lib 
1116    COPYING        README         bin           example        test 
1117    $ git checkout master 
1118    Switched to branch "master" 
1119    $ ls 
1120    README 
1121  
1122You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: 
1123  
1124    $ git read-tree --prefix=rack/ -u rack_branch 
1125  
1126When you commit, it looks like you have all the Rack files under that subdirectory — as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling: 
1127  
1128    $ git checkout rack_branch 
1129    $ git pull 
1130  
1131Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option: 
1132  
1133    $ git checkout master 
1134    $ git merge --squash -s subtree --no-commit rack_branch 
1135    Squash commit -- not updating HEAD 
1136    Automatic merge went well; stopped before committing as requested 
1137  
1138All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite — make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream. 
1139  
1140To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch — to see if you need to merge them — you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to: 
1141  
1142    $ git diff-tree -p rack_branch 
1143  
1144Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run 
1145  
1146    $ git diff-tree -p rack_remote/master 
1147  
1148## Summary ## 
1149  
1150You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. 
1151 320 
+
+ diff --git a/book/07-git-tools/sections/diff-rewriting-history.htm b/book/07-git-tools/sections/diff-rewriting-history.htm new file mode 100644 index 00000000..21d0e7fc --- /dev/null +++ b/book/07-git-tools/sections/diff-rewriting-history.htm @@ -0,0 +1,4955 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\rewriting-history.asc
.1# Git Tools # 1[[_rewriting_history]] 
2  
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. 
4  
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. 
6  
7## Revision Selection ## 
8  
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. 
10  
11### Single Revisions ### 
12  
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. 
14  
15### Short SHA ### 
16  
17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. 
18  
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: 
20  
21    $ git log 
22    commit 734713bc047d87bf7eac9674765ae793478c50d3 
23    Author: Scott Chacon <schacon@gmail.com> 
24    Date:   Fri Jan 2 18:32:33 2009 -0800 
25  
26        fixed refs handling, added gc auto, updated tests 
27  
28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
29    Merge: 1c002dd... 35cfb2b... 
30    Author: Scott Chacon <schacon@gmail.com> 
31    Date:   Thu Dec 11 15:08:43 2008 -0800 
32  
33        Merge commit 'phedders/rdocs' 
34  
35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
36    Author: Scott Chacon <schacon@gmail.com> 
37    Date:   Thu Dec 11 14:58:32 2008 -0800 
38  
39        added some blame and merge stuff 
40  
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): 
42  
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
44    $ git show 1c002dd4b536e7479f 
45    $ git show 1c002d 
46  
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: 
48  
49    $ git log --abbrev-commit --pretty=oneline 
50    ca82a6d changed the version number 
51    085bb3b removed unnecessary test code 
52    a11bef0 first commit 
53  
54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 
55  
56### A SHORT NOTE ABOUT SHA-1 ### 
57  
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? 
59  
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. 
61  
62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. 
63  
64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. 
65  
66### Branch References ### 
67  
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: 
69  
70    $ git show ca82a6dff817ec66f44342007202690a93763949 
71    $ git show topic1 
72  
73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. 
74  
75    $ git rev-parse topic1 
76    ca82a6dff817ec66f44342007202690a93763949 
77  
78### RefLog Shortnames ### 
79  
80One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. 
81  
82You can see your reflog by using `git reflog`: 
83  
84    $ git reflog 
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated 
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff 
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 
89    95df984 HEAD@{4}: commit: # This is a combination of two commits. 
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD 
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD 
92  
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: 
94  
95    $ git show HEAD@{5} 
96  
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type 
98  
99    $ git show master@{yesterday} 
100  
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. 
102  
103To see reflog information formatted like the `git log` output, you can run `git log -g`: 
104  
105    $ git log -g master 
106    commit 734713bc047d87bf7eac9674765ae793478c50d3 
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) 
108    Reflog message: commit: fixed refs handling, added gc auto, updated 
109    Author: Scott Chacon <schacon@gmail.com> 
110    Date:   Fri Jan 2 18:32:33 2009 -0800 
111  
112        fixed refs handling, added gc auto, updated tests 
113  
114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>) 
116    Reflog message: merge phedders/rdocs: Merge made by recursive. 
117    Author: Scott Chacon <schacon@gmail.com> 
118    Date:   Thu Dec 11 15:08:43 2008 -0800 
119  
120        Merge commit 'phedders/rdocs' 
121  
122It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. 
123  
124### Ancestry References ### 
125  
126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 
127Suppose you look at the history of your project: 
128  
129    $ git log --pretty=format:'%h %s' --graph 
130    * 734713b fixed refs handling, added gc auto, updated tests 
131    *   d921970 Merge commit 'phedders/rdocs' 
132    |\ 
133    | * 35cfb2b Some rdoc changes 
134    * | 1c002dd added some blame and merge stuff 
135    |/ 
136    * 1c36188 ignore *.gem 
137    * 9b29157 add open3_detach to gemspec file list 
138  
139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": 
140  
141    $ git show HEAD^ 
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
143    Merge: 1c002dd... 35cfb2b... 
144    Author: Scott Chacon <schacon@gmail.com> 
145    Date:   Thu Dec 11 15:08:43 2008 -0800 
146  
147        Merge commit 'phedders/rdocs' 
148  
149You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: 
150  
151    $ git show d921970^ 
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
153    Author: Scott Chacon <schacon@gmail.com> 
154    Date:   Thu Dec 11 14:58:32 2008 -0800 
155  
156        added some blame and merge stuff 
157  
158    $ git show d921970^2 
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 
160    Author: Paul Hedderly <paul+git@mjr.org> 
161    Date:   Wed Dec 10 22:22:03 2008 +0000 
162  
163        Some rdoc changes 
164  
165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be 
166  
167    $ git show HEAD~3 
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
169    Author: Tom Preston-Werner <tom@mojombo.com> 
170    Date:   Fri Nov 7 13:47:59 2008 -0500 
171  
172        ignore *.gem 
173  
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: 
175  
176    $ git show HEAD^^^ 
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
178    Author: Tom Preston-Werner <tom@mojombo.com> 
179    Date:   Fri Nov 7 13:47:59 2008 -0500 
180  
181        ignore *.gem 
182  
183You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. 
184  
185### Commit Ranges ### 
186  
187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 
188  
189#### Double Dot #### 
190  
191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. 
192  
193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
195  
196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: 
197  
198    $ git log master..experiment 
199    D 
200    C 
201  
202If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: 
203  
204    $ git log experiment..master 
205    F 
206    E 
207  
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: 
209  
210    $ git log origin/master..HEAD 
211  
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. 
213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. 
214  
215#### Multiple Points #### 
216  
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: 
218  
219    $ git log refA..refB 
220    $ git log ^refA refB 
221    $ git log refB --not refA 
222  
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: 
224  
225    $ git log refA refB ^refC 
226    $ git log refA refB --not refC 
227  
228This makes for a very powerful revision query system that should help you figure out what is in your branches. 
229  
230#### Triple Dot #### 
231  
232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. 
233If you want to see what is in `master` or `experiment` but not any common references, you can run 
234  
235    $ git log master...experiment 
236    F 
237    E 
238    D 
239    C 
240  
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. 
242  
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: 
244  
245    $ git log --left-right master...experiment 
246    < F 
247    < E 
248    > D 
249    > C 
250  
251With these tools, you can much more easily let Git know what commit or commits you want to inspect. 
252  
253## Interactive Staging ## 
254  
255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257  
258    $ git add -i 
259               staged     unstaged path 
260      1:    unchanged        +0/-1 TODO 
261      2:    unchanged        +1/-1 index.html 
262      3:    unchanged        +5/-1 lib/simplegit.rb 
263  
264    *** Commands *** 
265      1: status     2: update      3: revert     4: add untracked 
266      5: patch      6: diff        7: quit       8: help 
267    What now> 
268  
269You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. 
270  
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. 
272  
273### Staging and Unstaging Files ### 
274  
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: 
276  
277    What now> 2 
278               staged     unstaged path 
279      1:    unchanged        +0/-1 TODO 
280      2:    unchanged        +1/-1 index.html 
281      3:    unchanged        +5/-1 lib/simplegit.rb 
282    Update>> 
283  
284To stage the TODO and index.html files, you can type the numbers: 
285  
286    Update>> 1,2 
287               staged     unstaged path 
288    * 1:    unchanged        +0/-1 TODO 
289    * 2:    unchanged        +1/-1 index.html 
290      3:    unchanged        +5/-1 lib/simplegit.rb 
291    Update>> 
292  
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: 
294  
295    Update>> 
296    updated 2 paths 
297  
298    *** Commands *** 
299      1: status     2: update      3: revert     4: add untracked 
300      5: patch      6: diff        7: quit       8: help 
301    What now> 1 
302               staged     unstaged path 
303      1:        +0/-1      nothing TODO 
304      2:        +1/-1      nothing index.html 
305      3:    unchanged        +5/-1 lib/simplegit.rb 
306  
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: 
308  
309    *** Commands *** 
310      1: status     2: update      3: revert     4: add untracked 
311      5: patch      6: diff        7: quit       8: help 
312    What now> 3 
313               staged     unstaged path 
314      1:        +0/-1      nothing TODO 
315      2:        +1/-1      nothing index.html 
316      3:    unchanged        +5/-1 lib/simplegit.rb 
317    Revert>> 1 
318               staged     unstaged path 
319    * 1:        +0/-1      nothing TODO 
320      2:        +1/-1      nothing index.html 
321      3:    unchanged        +5/-1 lib/simplegit.rb 
322    Revert>> [enter] 
323    reverted one path 
324  
325Looking at your Git status again, you can see that you’ve unstaged the TODO file: 
326  
327    *** Commands *** 
328      1: status     2: update      3: revert     4: add untracked 
329      5: patch      6: diff        7: quit       8: help 
330    What now> 1 
331               staged     unstaged path 
332      1:    unchanged        +0/-1 TODO 
333      2:        +1/-1      nothing index.html 
334      3:    unchanged        +5/-1 lib/simplegit.rb 
335  
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: 
337  
338    *** Commands *** 
339      1: status     2: update      3: revert     4: add untracked 
340      5: patch      6: diff        7: quit       8: help 
341    What now> 6 
342               staged     unstaged path 
343      1:        +1/-1      nothing index.html 
344    Review diff>> 1 
345    diff --git a/index.html b/index.html 
346    index 4d07108..4335f49 100644 
347    --- a/index.html 
348    +++ b/index.html 
349    @@ -16,7 +16,7 @@ Date Finder 
350  
351     <p id="out">...</p> 
352  
353    -<div id="footer">contact : support@github.com</div> 
354    +<div id="footer">contact : email.support@github.com</div> 
355  
356     <script type="text/javascript"> 
357  
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily. 
359  
360### Staging Patches ### 
361  
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: 
363  
364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
365    index dd5ecc4..57399e0 100644 
366    --- a/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 
368    @@ -22,7 +22,7 @@ class SimpleGit 
369       end 
370  
371       def log(treeish = 'master') 
372    -    command("git log -n 25 #{treeish}") 
373    +    command("git log -n 30 #{treeish}") 
374       end 
375  
376       def blame(path) 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 
378  
379You have a lot of options at this point. Typing `?` shows a list of what you can do: 
380  
381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
382    y - stage this hunk 
383    n - do not stage this hunk 
384    a - stage this and all the remaining hunks in the file 
385    d - do not stage this hunk nor any of the remaining hunks in the file 
386    g - select a hunk to go to 
387    / - search for a hunk matching the given regex 
388    j - leave this hunk undecided, see next undecided hunk 
389    J - leave this hunk undecided, see next hunk 
390    k - leave this hunk undecided, see previous undecided hunk 
391    K - leave this hunk undecided, see previous hunk 
392    s - split the current hunk into smaller hunks 
393    e - manually edit the current hunk 
394    ? - print help 
395  
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: 
397  
398    What now> 1 
399               staged     unstaged path 
400      1:    unchanged        +0/-1 TODO 
401      2:        +1/-1      nothing index.html 
402      3:        +1/-1        +4/-0 lib/simplegit.rb 
403  
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. 
405  
406Finally, you don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using `git add -p` or `git add --patch` on the command line. 
407  
408## Stashing ## 
409  
410Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command. 
411  
412Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time. 
413  
414### Stashing Your Work ### 
415  
416To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state: 
417  
418    $ git status 
419    # On branch master 
420    # Changes to be committed: 
421    #   (use "git reset HEAD <file>..." to unstage) 
422    # 
423    #      modified:   index.html 
424    # 
425    # Changes not staged for commit: 
426    #   (use "git add <file>..." to update what will be committed) 
427    # 
428    #      modified:   lib/simplegit.rb 
429    # 
430  
431Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`: 
432  
433    $ git stash 
434    Saved working directory and index state \ 
435      "WIP on master: 049d078 added the index file" 
436    HEAD is now at 049d078 added the index file 
437    (To restore them type "git stash apply") 
438  
439Your working directory is clean: 
440  
441    $ git status 
442    # On branch master 
443    nothing to commit, working directory clean 
444  
445At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: 
446  
447    $ git stash list 
448    stash@{0}: WIP on master: 049d078 added the index file 
449    stash@{1}: WIP on master: c264051 Revert "added file_size" 
450    stash@{2}: WIP on master: 21d80a5 added number to log 
451  
452In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it: 
453  
454    $ git stash apply 
455    # On branch master 
456    # Changes not staged for commit: 
457    #   (use "git add <file>..." to update what will be committed) 
458    # 
459    #      modified:   index.html 
460    #      modified:   lib/simplegit.rb 
461    # 
462  
463You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly. 
464  
465The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position: 
466  
467    $ git stash apply --index 
468    # On branch master 
469    # Changes to be committed: 
470    #   (use "git reset HEAD <file>..." to unstage) 
471    # 
472    #      modified:   index.html 
473    # 
474    # Changes not staged for commit: 
475    #   (use "git add <file>..." to update what will be committed) 
476    # 
477    #      modified:   lib/simplegit.rb 
478    # 
479  
480The apply option only tries to apply the stashed work — you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove: 
481  
482    $ git stash list 
483    stash@{0}: WIP on master: 049d078 added the index file 
484    stash@{1}: WIP on master: c264051 Revert "added file_size" 
485    stash@{2}: WIP on master: 21d80a5 added number to log 
486    $ git stash drop stash@{0} 
487    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) 
488  
489You can also run `git stash pop` to apply the stash and then immediately drop it from your stack. 
490  
491### Un-applying a Stash ### 
492  
493In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
494  
495    $ git stash show -p stash@{0} | git apply -R 
496  
497Again, if you don’t specify a stash, Git assumes the most recent stash: 
498  
499    $ git stash show -p | git apply -R 
500  
501You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
502  
503    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
504    $ git stash apply 
505    $ #... work work work 
506    $ git stash-unapply 
507  
508### Creating a Branch from a Stash ### 
509  
510If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully: 
511  
512    $ git stash branch testchanges 
513    Switched to a new branch "testchanges" 
514    # On branch testchanges 
515    # Changes to be committed: 
516    #   (use "git reset HEAD <file>..." to unstage) 
517    # 
518    #      modified:   index.html 
519    # 
520    # Changes not staged for commit: 
521    #   (use "git add <file>..." to update what will be committed) 
522    # 
523    #      modified:   lib/simplegit.rb 
524    # 
525    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) 
526  
527This is a nice shortcut to recover stashed work easily and work on it in a new branch. 
528  
529## Rewriting History ## 2=== Rewriting History 
530 3 
.531Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely all before you share your work with others.4Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely all before you share your work with others.
532 5 
533In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others.6In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others.
534 7 
. 8[[_git_amend]]
535### Changing the Last Commit ### 9==== Changing the Last Commit 
536 10 
.537Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 11Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files.  
538 12 
539If you only want to modify your last commit message, it’s very simple:13If you only want to modify your last commit message, it’s very simple:
540 14 
. 15[source,console]
 16----
541    $ git commit --amend17$ git commit --amend
 18----
542 19 
543That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit.20That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit.
544 21 
545If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit.22If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit.
546 23 
.547You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase don’t amend your last commit if you’ve already pushed it.24You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase don’t amend your last commit if you’ve already pushed it.
548 25 
. 26[[_changing_multiple]]
549### Changing Multiple Commit Messages ### 27==== Changing Multiple Commit Messages 
550 28 
551To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto.29To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto.
552 30 
553For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit:31For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit:
554 32 
. 33[source,console]
 34----
555    $ git rebase -i HEAD~335$ git rebase -i HEAD~3
 36----
556 37 
.557Remember again that this is a rebasing command every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server doing so will confuse other developers by providing an alternate version of the same change.38Remember again that this is a rebasing command every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server doing so will confuse other developers by providing an alternate version of the same change.
558 39 
559Running this command gives you a list of commits in your text editor that looks something like this:40Running this command gives you a list of commits in your text editor that looks something like this:
560 41 
. 42[source,console]
 43----
561    pick f7f3f6d changed my name a bit44pick f7f3f6d changed my name a bit
562    pick 310154e updated README formatting and added blame45pick 310154e updated README formatting and added blame
563    pick a5f4a0d added cat-file46pick a5f4a0d added cat-file
564 47 
565    # Rebase 710f0f8..a5f4a0d onto 710f0f848# Rebase 710f0f8..a5f4a0d onto 710f0f8
566    #49#
567    # Commands:50# Commands:
568    #  p, pick = use commit51#  p, pick = use commit
569    #  r, reword = use commit, but edit the commit message52#  r, reword = use commit, but edit the commit message
570    #  e, edit = use commit, but stop for amending53#  e, edit = use commit, but stop for amending
571    #  s, squash = use commit, but meld into previous commit54#  s, squash = use commit, but meld into previous commit
572    #  f, fixup = like "squash", but discard this commit's log message55#  f, fixup = like "squash", but discard this commit's log message
573    #  x, exec = run command (the rest of the line) using shell56#  x, exec = run command (the rest of the line) using shell
574    #57#
575    # These lines can be re-ordered; they are executed from top to bottom.58# These lines can be re-ordered; they are executed from top to bottom.
576    #59#
577    # If you remove a line here THAT COMMIT WILL BE LOST.60# If you remove a line here THAT COMMIT WILL BE LOST.
578    #61#
579    # However, if you remove everything, the rebase will be aborted.62# However, if you remove everything, the rebase will be aborted.
580    #63#
581    # Note that empty commits are commented out64# Note that empty commits are commented out
 65----
582 66 
583It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this:67It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this:
584 68 
. 69[source,console]
 70----
585    $ git log --pretty=format:"%h %s" HEAD~3..HEAD71$ git log --pretty=format:"%h %s" HEAD~3..HEAD
586    a5f4a0d added cat-file72a5f4a0d added cat-file
587    310154e updated README formatting and added blame73310154e updated README formatting and added blame
588    f7f3f6d changed my name a bit74f7f3f6d changed my name a bit
 75----
589 76 
590Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay.77Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay.
591 78 
.592You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this:79You need to edit the script so that it stops at the commit you want to edit. To do so, change the word `pick' to the word `edit' for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this:
593 80 
. 81[source,console]
 82----
594    edit f7f3f6d changed my name a bit83edit f7f3f6d changed my name a bit
595    pick 310154e updated README formatting and added blame84pick 310154e updated README formatting and added blame
596    pick a5f4a0d added cat-file85pick a5f4a0d added cat-file
 86----
597 87 
598When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message:88When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message:
599 89 
.600<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  90[source,console] 
601nor is the commit message. Please review  
602--> 
603  
 91----
604    $ git rebase -i HEAD~392$ git rebase -i HEAD~3
605    Stopped at 7482e0d... updated the gemspec to hopefully work better 93Stopped at f7f3f6d... changed my name a bit 
606    You can amend the commit now, with94You can amend the commit now, with
607 95 
.608           git commit --amend96       git commit --amend
609 97 
.610    Once you’re satisfied with your changes, run98Once you’re satisfied with your changes, run
611 99 
.612           git rebase --continue100       git rebase --continue
 101----
613 102 
614These instructions tell you exactly what to do. Type103These instructions tell you exactly what to do. Type
615 104 
. 105[source,console]
 106----
616    $ git commit --amend107$ git commit --amend
 108----
617 109 
618Change the commit message, and exit the editor. Then, run110Change the commit message, and exit the editor. Then, run
619 111 
. 112[source,console]
 113----
620    $ git rebase --continue114$ git rebase --continue
 115----
621 116 
622This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished.117This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished.
623 118 
.624### Reordering Commits ### 119==== Reordering Commits 
625 120 
.626You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this121You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the ``added cat-file'' commit and change the order in which the other two commits are introduced, you can change the rebase script from this
627 122 
. 123[source,console]
 124----
628    pick f7f3f6d changed my name a bit125pick f7f3f6d changed my name a bit
629    pick 310154e updated README formatting and added blame126pick 310154e updated README formatting and added blame
630    pick a5f4a0d added cat-file127pick a5f4a0d added cat-file
 128----
631 129 
632to this:130to this:
633 131 
. 132 
 133[source,console]
 134----
634    pick 310154e updated README formatting and added blame135pick 310154e updated README formatting and added blame
635    pick f7f3f6d changed my name a bit136pick f7f3f6d changed my name a bit
 137----
636 138 
.637When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely.139When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the ``added cat-file'' commit completely.
638 140 
. 141[[_squashing]]
639### Squashing Commits ### 142==== Squashing Commits 
640 143 
641It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message:144It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message:
642 145 
. 146[source,console]
 147----
643    #148#
644    # Commands:149# Commands:
645    #  p, pick = use commit150#  p, pick = use commit
646    #  r, reword = use commit, but edit the commit message151#  r, reword = use commit, but edit the commit message
647    #  e, edit = use commit, but stop for amending152#  e, edit = use commit, but stop for amending
648    #  s, squash = use commit, but meld into previous commit153#  s, squash = use commit, but meld into previous commit
649    #  f, fixup = like "squash", but discard this commit's log message154#  f, fixup = like "squash", but discard this commit's log message
650    #  x, exec = run command (the rest of the line) using shell155#  x, exec = run command (the rest of the line) using shell
651    #156#
652    # These lines can be re-ordered; they are executed from top to bottom.157# These lines can be re-ordered; they are executed from top to bottom.
653    #158#
654    # If you remove a line here THAT COMMIT WILL BE LOST.159# If you remove a line here THAT COMMIT WILL BE LOST.
655    #160#
656    # However, if you remove everything, the rebase will be aborted.161# However, if you remove everything, the rebase will be aborted.
657    #162#
658    # Note that empty commits are commented out163# Note that empty commits are commented out
 164----
659 165 
.660If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this:166If, instead of ``pick'' or ``edit'', you specify ``squash'', Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this:
661 167 
. 168[source,console]
 169----
662    pick f7f3f6d changed my name a bit170pick f7f3f6d changed my name a bit
663    squash 310154e updated README formatting and added blame171squash 310154e updated README formatting and added blame
664    squash a5f4a0d added cat-file172squash a5f4a0d added cat-file
 173----
665 174 
666When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages:175When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages:
667 176 
. 177[source,console]
 178----
668    # This is a combination of 3 commits.179# This is a combination of 3 commits.
669    # The first commit's message is:180# The first commit's message is:
670    changed my name a bit181changed my name a bit
671 182 
.672    # This is the 2nd commit message:183# This is the 2nd commit message:
673 184 
.674    updated README formatting and added blame185updated README formatting and added blame
675 186 
.676    # This is the 3rd commit message:187# This is the 3rd commit message:
677 188 
.678    added cat-file189added cat-file
 190----
679 191 
680When you save that, you have a single commit that introduces the changes of all three previous commits.192When you save that, you have a single commit that introduces the changes of all three previous commits.
681 193 
.682### Splitting a Commit ### 194==== Splitting a Commit 
683 195 
.684Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit":196Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of ``updated README formatting and added blame'', you want to split it into two commits: ``updated README formatting'' for the first, and ``added blame'' for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to ``edit'':
685 197 
. 198[source,console]
 199----
686    pick f7f3f6d changed my name a bit200pick f7f3f6d changed my name a bit
687    edit 310154e updated README formatting and added blame201edit 310154e updated README formatting and added blame
688    pick a5f4a0d added cat-file202pick a5f4a0d added cat-file
 203----
689 204 
.690When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done:205Then, when the script drops you to the command line, you reset that commit, take the changes that have been reset, and create multiple commits out of them. When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can stage and commit files until you have several commits, and run `git rebase --continue` when you’re done:
691 206 
. 207[source,console]
 208----
692    $ git reset HEAD^209$ git reset HEAD^
693    $ git add README210$ git add README
694    $ git commit -m 'updated README formatting'211$ git commit -m 'updated README formatting'
695    $ git add lib/simplegit.rb212$ git add lib/simplegit.rb
696    $ git commit -m 'added blame'213$ git commit -m 'added blame'
697    $ git rebase --continue214$ git rebase --continue
 215----
698 216 
699Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this:217Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this:
700 218 
. 219[source,console]
 220----
701    $ git log -4 --pretty=format:"%h %s"221$ git log -4 --pretty=format:"%h %s"
702    1c002dd added cat-file2221c002dd added cat-file
703    9b29157 added blame2239b29157 added blame
704    35cfb2b updated README formatting22435cfb2b updated README formatting
705    f3cc40e changed my name a bit225f3cc40e changed my name a bit
 226----
706 227 
707Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository.228Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository.
708 229 
.709### The Nuclear Option: filter-branch ### 230==== The Nuclear Option: filter-branch 
710 231 
.711There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of.232There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way for instance, changing your e-mail address globally or removing a file from every commit. The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite. However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of.
712 233 
. 234[[_removing_file_every_commit]]
713#### Removing a File from Every Commit #### 235===== Removing a File from Every Commit 
714 236 
715This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`:237This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`:
716 238 
. 239[source,console]
 240----
717    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD241$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
718    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)242Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21)
719    Ref 'refs/heads/master' was rewritten243Ref 'refs/heads/master' was rewritten
 244----
720 245 
.721The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`.246The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`.
722 247 
723You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command.248You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command.
724 249 
.725#### Making a Subdirectory the New Root #### 250===== Making a Subdirectory the New Root 
726 251 
727Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too:252Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too:
728 253 
. 254[source,console]
 255----
729    $ git filter-branch --subdirectory-filter trunk HEAD256$ git filter-branch --subdirectory-filter trunk HEAD
730    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)257Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12)
731    Ref 'refs/heads/master' was rewritten258Ref 'refs/heads/master' was rewritten
 259----
732 260 
733Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory.261Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory.
734 262 
.735#### Changing E-Mail Addresses Globally #### 263===== Changing E-Mail Addresses Globally 
736 264 
737Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`:265Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`:
738 266 
. 267[source,console]
 268----
739    $ git filter-branch --commit-filter '269$ git filter-branch --commit-filter '
740            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];270        if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ];
741            then271        then
742                    GIT_AUTHOR_NAME="Scott Chacon";272                GIT_AUTHOR_NAME="Scott Chacon";
743                    GIT_AUTHOR_EMAIL="schacon@example.com";273                GIT_AUTHOR_EMAIL="schacon@example.com";
744                    git commit-tree "$@";274                git commit-tree "$@";
745            else275        else
746                    git commit-tree "$@";276                git commit-tree "$@";
747            fi' HEAD277        fi' HEAD
 278----
748 279 
749This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address.280This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address.
.750  
751### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
752  
753[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
754  
755See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
756  
757## Debugging with Git ## 
758  
759Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. 
760  
761### File Annotation ### 
762  
763If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: 
764  
765    $ git blame -L 12,22 simplegit.rb 
766    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master') 
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}") 
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end 
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15) 
770    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master') 
771    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}") 
772    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end 
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19) 
774    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path) 
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}") 
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end 
777  
778Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here. 
779  
780Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from: 
781  
782    $ git blame -C -L 141,153 GITPackUpload.m 
783    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
786    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
787    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
793    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 
796  
797This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. 
798  
799### Binary Search ### 
800  
801Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. 
802  
803Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: 
804  
805    $ git bisect start 
806    $ git bisect bad 
807    $ git bisect good v1.0 
808    Bisecting: 6 revisions left to test after this 
809    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo 
810  
811Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: 
812  
813    $ git bisect good 
814    Bisecting: 3 revisions left to test after this 
815    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing 
816  
817Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: 
818  
819    $ git bisect bad 
820    Bisecting: 1 revisions left to test after this 
821    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table 
822  
823This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: 
824  
825    $ git bisect good 
826    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit 
827    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 
828    Author: PJ Hyett <pjhyett@example.com> 
829    Date:   Tue Jan 27 14:48:32 2009 -0800 
830  
831        secure this thing 
832  
833    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 
834    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config 
835  
836When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: 
837  
838    $ git bisect reset 
839  
840This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: 
841  
842    $ git bisect start HEAD v1.0 
843    $ git bisect run test-error.sh 
844  
845Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. 
846  
847## Submodules ## 
848  
849It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. 
850  
851Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available. 
852  
853Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate. 
854  
855### Starting with Submodules ### 
856  
857Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
858  
859    $ git submodule add git://github.com/chneukirchen/rack.git rack 
860    Initialized empty Git repository in /opt/subtest/rack/.git/ 
861    remote: Counting objects: 3181, done. 
862    remote: Compressing objects: 100% (1534/1534), done. 
863    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
864    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. 
865    Resolving deltas: 100% (1951/1951), done. 
866  
867Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
868  
869    $ git status 
870    # On branch master 
871    # Changes to be committed: 
872    #   (use "git reset HEAD <file>..." to unstage) 
873    # 
874    #      new file:   .gitmodules 
875    #      new file:   rack 
876    # 
877  
878First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into: 
879  
880    $ cat .gitmodules 
881    [submodule "rack"] 
882          path = rack 
883          url = git://github.com/chneukirchen/rack.git 
884  
885If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. 
886  
887The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting: 
888  
889    $ git diff --cached rack 
890    diff --git a/rack b/rack 
891    new file mode 160000 
892    index 0000000..08d709f 
893    --- /dev/null 
894    +++ b/rack 
895    @@ -0,0 +1 @@ 
896    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
897  
898Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 
899  
900This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
901  
902When you commit, you see something like this: 
903  
904    $ git commit -m 'first commit with submodule rack' 
905    [master 0550271] first commit with submodule rack 
906     2 files changed, 4 insertions(+), 0 deletions(-) 
907     create mode 100644 .gitmodules 
908     create mode 160000 rack 
909  
910Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file. 
911  
912You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
913  
914    $ git log -1 
915    commit 0550271328a0038865aad6331e620cd7238601bb 
916    Author: Scott Chacon <schacon@gmail.com> 
917    Date:   Thu Apr 9 09:03:56 2009 -0700 
918  
919        first commit with submodule rack 
920    $ cd rack/ 
921    $ git log -1 
922    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
923    Author: Christian Neukirchen <chneukirchen@gmail.com> 
924    Date:   Wed Mar 25 14:49:04 2009 +0100 
925  
926        Document version change 
927  
928### Cloning a Project with Submodules ### 
929  
930Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet: 
931  
932    $ git clone git://github.com/schacon/myproject.git 
933    Initialized empty Git repository in /opt/myproject/.git/ 
934    remote: Counting objects: 6, done. 
935    remote: Compressing objects: 100% (4/4), done. 
936    remote: Total 6 (delta 0), reused 0 (delta 0) 
937    Receiving objects: 100% (6/6), done. 
938    $ cd myproject 
939    $ ls -l 
940    total 8 
941    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 
942    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 
943    $ ls rack/ 
944    $ 
945  
946The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject: 
947  
948    $ git submodule init 
949    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' 
950    $ git submodule update 
951    Initialized empty Git repository in /opt/myproject/rack/.git/ 
952    remote: Counting objects: 3181, done. 
953    remote: Compressing objects: 100% (1534/1534), done. 
954    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
955    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. 
956    Resolving deltas: 100% (1951/1951), done. 
957    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' 
958  
959Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 
960  
961    $ git merge origin/master 
962    Updating 0550271..85a3eee 
963    Fast forward 
964     rack |    2 +- 
965     1 files changed, 1 insertions(+), 1 deletions(-) 
966    [master*]$ git status 
967    # On branch master 
968    # Changes not staged for commit: 
969    #   (use "git add <file>..." to update what will be committed) 
970    #   (use "git checkout -- <file>..." to discard changes in working directory) 
971    # 
972    #      modified:   rack 
973    # 
974  
975You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
976  
977    $ git diff 
978    diff --git a/rack b/rack 
979    index 6c5e70b..08d709f 160000 
980    --- a/rack 
981    +++ b/rack 
982    @@ -1 +1 @@ 
983    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
984    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
985  
986This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
987  
988    $ git submodule update 
989    remote: Counting objects: 5, done. 
990    remote: Compressing objects: 100% (3/3), done. 
991    remote: Total 3 (delta 1), reused 2 (delta 0) 
992    Unpacking objects: 100% (3/3), done. 
993    From git@github.com:schacon/rack 
994       08d709f..6c5e70b  master     -> origin/master 
995    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
996  
997You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
998  
999One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1000  
1001    $ git submodule update 
1002    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1003    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1004  
1005You have to see who last changed the submodule: 
1006  
1007    $ git log -1 rack 
1008    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1009    Author: Scott Chacon <schacon@gmail.com> 
1010    Date:   Thu Apr 9 09:19:14 2009 -0700 
1011  
1012        added a submodule reference I will never make public. hahahahaha! 
1013  
1014Then, you e-mail that guy and yell at him. 
1015  
1016### Superprojects ### 
1017  
1018Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1019  
1020A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1021  
1022### Issues with Submodules ### 
1023  
1024Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 
1025  
1026To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1027  
1028Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory: 
1029  
1030    $ git checkout -b rack 
1031    Switched to a new branch "rack" 
1032    $ git submodule add git@github.com:schacon/rack.git rack 
1033    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1034    ... 
1035    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1036    Resolving deltas: 100% (1952/1952), done. 
1037    $ git commit -am 'added rack submodule' 
1038    [rack cc49a69] added rack submodule 
1039     2 files changed, 4 insertions(+), 0 deletions(-) 
1040     create mode 100644 .gitmodules 
1041     create mode 160000 rack 
1042    $ git checkout master 
1043    Switched to branch "master" 
1044    $ git status 
1045    # On branch master 
1046    # Untracked files: 
1047    #   (use "git add <file>..." to include in what will be committed) 
1048    # 
1049    #      rack/ 
1050  
1051You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 
1052  
1053The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you: 
1054  
1055    $ rm -Rf rack/ 
1056    $ git submodule add git@github.com:schacon/rack.git rack 
1057    'rack' already exists in the index 
1058  
1059You have to unstage the `rack` directory first. Then you can add the submodule: 
1060  
1061    $ git rm -r rack 
1062    $ git submodule add git@github.com:schacon/rack.git rack 
1063    Initialized empty Git repository in /opt/testsub/rack/.git/ 
1064    remote: Counting objects: 3184, done. 
1065    remote: Compressing objects: 100% (1465/1465), done. 
1066    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1067    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. 
1068    Resolving deltas: 100% (1952/1952), done. 
1069  
1070Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule — you get this error: 
1071  
1072    $ git checkout master 
1073    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 
1074  
1075You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1076  
1077    $ mv rack /tmp/ 
1078    $ git checkout master 
1079    Switched to branch "master" 
1080    $ ls 
1081    README  rack 
1082  
1083Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory. 
1084  
1085## Subtree Merging ## 
1086  
1087Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1088  
1089However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1090  
1091The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing. 
1092  
1093You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch: 
1094  
1095    $ git remote add rack_remote git@github.com:schacon/rack.git 
1096    $ git fetch rack_remote 
1097    warning: no common commits 
1098    remote: Counting objects: 3184, done. 
1099    remote: Compressing objects: 100% (1465/1465), done. 
1100    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1101    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. 
1102    Resolving deltas: 100% (1952/1952), done. 
1103    From git@github.com:schacon/rack 
1104     * [new branch]      build      -> rack_remote/build 
1105     * [new branch]      master     -> rack_remote/master 
1106     * [new branch]      rack-0.4   -> rack_remote/rack-0.4 
1107     * [new branch]      rack-0.9   -> rack_remote/rack-0.9 
1108    $ git checkout -b rack_branch rack_remote/master 
1109    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. 
1110    Switched to a new branch "rack_branch" 
1111  
1112Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots: 
1113  
1114    $ ls 
1115    AUTHORS        KNOWN-ISSUES   Rakefile      contrib        lib 
1116    COPYING        README         bin           example        test 
1117    $ git checkout master 
1118    Switched to branch "master" 
1119    $ ls 
1120    README 
1121  
1122You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: 
1123  
1124    $ git read-tree --prefix=rack/ -u rack_branch 
1125  
1126When you commit, it looks like you have all the Rack files under that subdirectory — as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling: 
1127  
1128    $ git checkout rack_branch 
1129    $ git pull 
1130  
1131Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option: 
1132  
1133    $ git checkout master 
1134    $ git merge --squash -s subtree --no-commit rack_branch 
1135    Squash commit -- not updating HEAD 
1136    Automatic merge went well; stopped before committing as requested 
1137  
1138All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite — make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream. 
1139  
1140To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch — to see if you need to merge them — you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to: 
1141  
1142    $ git diff-tree -p rack_branch 
1143  
1144Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run 
1145  
1146    $ git diff-tree -p rack_remote/master 
1147  
1148## Summary ## 
1149  
1150You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. 
1151 281 
+
+ diff --git a/book/07-git-tools/sections/diff-signing.htm b/book/07-git-tools/sections/diff-signing.htm new file mode 100644 index 00000000..56ecf924 --- /dev/null +++ b/book/07-git-tools/sections/diff-signing.htm @@ -0,0 +1,5567 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\02-git-basics\01-chapter2.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\signing.asc
. 1[[_signing]]
 2=== Signing Your Work
 3 
 4Git is cryptographically secure, but it's not foolproof. If you're taking work from others on the internet and want to verify that commits are actually from a trusted source, Git has a few ways to sign and verify work using GPG.
 5 
 6==== GPG Introduction
 7 
 8First of all, if you want to sign anything you need to get GPG configured and your personal key installed.
 9 
 10[source,console]
 11----
 12$ gpg --list-keys
 13/Users/schacon/.gnupg/pubring.gpg
 14---------------------------------
 15pub   2048R/0A46826A 2014-06-04
 16uid                  Scott Chacon (Git signing key) <schacon@gmail.com>
 17sub   2048R/874529A9 2014-06-04
 18----
 19 
 20If you don't have a key installed, you can generate one with `gpg --gen-key`.
 21 
 22[source,console]
 23----
 24gpg --gen-key
 25----
 26 
 27Once you have a private key to sign with, you can configure Git to use it for signing things by setting the `user.signingkey` config setting.
 28 
 29[source,console]
 30----
 31git config --global user.signingkey 0A46826A
 32----
 33 
1# Git Basics # 34Now Git will use your key by default to sign tags and commits if you want. 
2  
3If you can read only one chapter to get going with Git, this is it. This chapter covers every basic command you need to do the vast majority of the things you’ll eventually spend your time doing with Git. By the end of the chapter, you should be able to configure and initialize a repository, begin and stop tracking files, and stage and commit changes. We’ll also show you how to set up Git to ignore certain files and file patterns, how to undo mistakes quickly and easily, how to browse the history of your project and view changes between commits, and how to push and pull from remote repositories. 
4  
5## Getting a Git Repository ## 
6  
7You can get a Git project using two main approaches. The first takes an existing project or directory and imports it into Git. The second clones an existing Git repository from another server. 
8  
9### Initializing a Repository in an Existing Directory ### 
10  
11If you’re starting to track an existing project in Git, you need to go to the project’s directory and type 
12  
13    $ git init 
14  
15This creates a new subdirectory named `.git` that contains all of your necessary repository files — a Git repository skeleton. At this point, nothing in your project is tracked yet. (See *Chapter 9* for more information about exactly what files are contained in the `.git` directory you just created.) 
16  
17If you want to start version-controlling existing files (as opposed to an empty directory), you should probably begin tracking those files and do an initial commit. You can accomplish that with a few `git add` commands that specify the files you want to track, followed by a commit: 
18  
19    $ git add *.c 
20    $ git add README 
21    $ git commit -m 'initial project version' 
22  
23We’ll go over what these commands do in just a minute. At this point, you have a Git repository with tracked files and an initial commit. 
24  
25### Cloning an Existing Repository ### 
26  
27If you want to get a copy of an existing Git repository — for example, a project you’d like to contribute to — the command you need is `git clone`. If you’re familiar with other VCS systems such as Subversion, you’ll notice that the command is `clone` and not `checkout`. This is an important distinction — Git receives a copy of nearly all data that the server has. Every version of every file for the history of the project is pulled down when you run `git clone`. In fact, if your server disk gets corrupted, you can use any of the clones on any client to set the server back to the state it was in when it was cloned (you may lose some server-side hooks and such, but all the versioned data would be there — see *Chapter 4* for more details). 
28  
29You clone a repository with `git clone [url]`. For example, if you want to clone the Ruby Git library called Grit, you can do so like this: 
30  
31    $ git clone git://github.com/schacon/grit.git 
32  
33That creates a directory named `grit`, initializes a `.git` directory inside it, pulls down all the data for that repository, and checks out a working copy of the latest version. If you go into the new `grit` directory, you’ll see the project files in there, ready to be worked on or used. If you want to clone the repository into a directory named something other than grit, you can specify that as the next command-line option: 
34  
35    $ git clone git://github.com/schacon/grit.git mygrit 
36  
37That command does the same thing as the previous one, but the target directory is called `mygrit`. 
38  
39Git has a number of different transfer protocols you can use. The previous example uses the `git://` protocol, but you may also see `http(s)://` or `user@server:/path.git`, which uses the SSH transfer protocol. *Chapter 4* will introduce all of the available options the server can set up to access your Git repository and the pros and cons of each. 
40  
41## Recording Changes to the Repository ## 
42  
43You have a bona fide Git repository and a checkout or working copy of the files for that project. You need to make some changes and commit snapshots of those changes into your repository each time the project reaches a state you want to record. 
44  
45Remember that each file in your working directory can be in one of two states: *tracked* or *untracked*. *Tracked* files are files that were in the last snapshot; they can be *unmodified*, *modified*, or *staged*. *Untracked* files are everything else — any files in your working directory that were not in your last snapshot and are not in your staging area.  When you first clone a repository, all of your files will be tracked and unmodified because you just checked them out and haven’t edited anything. 
46  
47As you edit files, Git sees them as modified, because you’ve changed them since your last commit. You *stage* these modified files and then commit all your staged changes, and the cycle repeats. This lifecycle is illustrated in Figure 2-1. 
48  
49Insert 18333fig0201.png 
50Figure 2-1. The lifecycle of the status of your files. 
51  
52### Checking the Status of Your Files ### 
53  
54The main tool you use to determine which files are in which state is the `git status` command. If you run this command directly after a clone, you should see something like this: 
55  
56    $ git status 
57    On branch master 
58    nothing to commit, working directory clean 
59  
60This means you have a clean working directory — in other words, no tracked files are modified. Git also doesn’t see any untracked files, or they would be listed here. Finally, the command tells you which branch you’re on. For now, that is always `master`, which is the default; you won’t worry about it here. The next chapter will go over branches and references in detail. 
61  
62Let’s say you add a new file to your project, a simple `README` file. If the file didn’t exist before, and you run `git status`, you see your untracked file like so: 
63  
64    $ vim README 
65    $ git status 
66    On branch master 
67    Untracked files: 
68      (use "git add <file>..." to include in what will be committed) 
69      
70            README 
71  
72    nothing added to commit but untracked files present (use "git add" to track) 
73  
74You can see that your new `README` file is untracked, because it’s under the “Untracked files” heading in your status output. Untracked basically means that Git sees a file you didn’t have in the previous snapshot (commit); Git won’t start including it in your commit snapshots until you explicitly tell it to do so. It does this so you don’t accidentally begin including generated binary files or other files that you did not mean to include. You do want to start including README, so let’s start tracking the file. 
75  
76### Tracking New Files ### 
77  
78In order to begin tracking a new file, you use the command `git add`. To begin tracking the `README` file, you can run this: 
79  
80    $ git add README 
81  
82If you run your status command again, you can see that your `README` file is now tracked and staged: 
83  
84    $ git status 
85    On branch master 
86    Changes to be committed: 
87      (use "git reset HEAD <file>..." to unstage) 
88      
89            new file:   README 
90      
91  
92You can tell that it’s staged because it’s under the “Changes to be committed” heading. If you commit at this point, the version of the file at the time you ran `git add` is what will be in the historical snapshot. You may recall that when you ran `git init` earlier, you then ran `git add (files)` — that was to begin tracking files in your directory. The `git add` command takes a path name for either a file or a directory; if it’s a directory, the command adds all the files in that directory recursively. 
93  
94### Staging Modified Files ### 
95  
96Let’s change a file that was already tracked. If you change a previously tracked file called `benchmarks.rb` and then run your `status` command again, you get something that looks like this: 
97  
98    $ git status 
99    On branch master 
100    Changes to be committed: 
101      (use "git reset HEAD <file>..." to unstage) 
102      
103            new file:   README 
104  
105    Changes not staged for commit: 
106      (use "git add <file>..." to update what will be committed) 
107      (use "git checkout -- <file>..." to discard changes in working directory) 
108      
109            modified:   benchmarks.rb 
110      
111  
112The `benchmarks.rb` file appears under a section named “Changes not staged for commit” — which means that a file that is tracked has been modified in the working directory but not yet staged. To stage it, you run the `git add` command (it’s a multipurpose command — you use it to begin tracking new files, to stage files, and to do other things like marking merge-conflicted files as resolved). Let’s run `git add` now to stage the `benchmarks.rb` file, and then run `git status` again: 
113  
114    $ git add benchmarks.rb 
115    $ git status 
116    On branch master 
117    Changes to be committed: 
118      (use "git reset HEAD <file>..." to unstage) 
119      
120            new file:   README 
121            modified:   benchmarks.rb 
122      
123  
124Both files are staged and will go into your next commit. At this point, suppose you remember one little change that you want to make in `benchmarks.rb` before you commit it. You open it again and make that change, and you’re ready to commit. However, let’s run `git status` one more time: 
125  
126    $ vim benchmarks.rb 
127    $ git status 
128    On branch master 
129    Changes to be committed: 
130      (use "git reset HEAD <file>..." to unstage) 
131      
132            new file:   README 
133            modified:   benchmarks.rb 
134      
135    Changes not staged for commit: 
136      (use "git add <file>..." to update what will be committed) 
137      (use "git checkout -- <file>..." to discard changes in working directory) 
138      
139            modified:   benchmarks.rb 
140      
141  
142What the heck? Now `benchmarks.rb` is listed as both staged and unstaged. How is that possible? It turns out that Git stages a file exactly as it is when you run the `git add` command. If you commit now, the version of `benchmarks.rb` as it was when you last ran the `git add` command is how it will go into the commit, not the version of the file as it looks in your working directory when you run `git commit`. If you modify a file after you run `git add`, you have to run `git add` again to stage the latest version of the file: 
143  
144    $ git add benchmarks.rb 
145    $ git status 
146    On branch master 
147    Changes to be committed: 
148      (use "git reset HEAD <file>..." to unstage) 
149      
150            new file:   README 
151            modified:   benchmarks.rb 
152      
153  
154### Ignoring Files ### 
155  
156Often, you’ll have a class of files that you don’t want Git to automatically add or even show you as being untracked. These are generally automatically generated files such as log files or files produced by your build system. In such cases, you can create a file listing patterns to match them named `.gitignore`.  Here is an example `.gitignore` file: 
157  
158    $ cat .gitignore 
159    *.[oa] 
160    *~ 
161  
162The first line tells Git to ignore any files ending in `.o` or `.a` — *object* and *archive* files that may be the product of building your code. The second line tells Git to ignore all files that end with a tilde (`~`), which is used by many text editors such as Emacs to mark temporary files. You may also include a `log`, `tmp`, or `pid` directory; automatically generated documentation; and so on. Setting up a `.gitignore` file before you get going is generally a good idea so you don’t accidentally commit files that you really don’t want in your Git repository. 
163  
164The rules for the patterns you can put in the `.gitignore` file are as follows: 
165  
166*   Blank lines or lines starting with `#` are ignored. 
167*   Standard glob patterns work. 
168*   You can end patterns with a forward slash (`/`) to specify a directory. 
169*   You can negate a pattern by starting it with an exclamation point (`!`). 
170  
171Glob patterns are like simplified regular expressions that shells use. An asterisk (`*`) matches zero or more characters; `[abc]` matches any character inside the brackets (in this case `a`, `b`, or `c`); a question mark (`?`) matches a single character; and brackets enclosing characters separated by a hyphen(`[0-9]`) matches any character in the range (in this case 0 through 9) . 
172  
173Here is another example `.gitignore` file: 
174  
175    # a comment - this is ignored 
176    # no .a files 
177    *.a 
178    # but do track lib.a, even though you're ignoring .a files above 
179    !lib.a 
180    # only ignore the root TODO file, not subdir/TODO 
181    /TODO 
182    # ignore all files in the build/ directory 
183    build/ 
184    # ignore doc/notes.txt, but not doc/server/arch.txt 
185    doc/*.txt 
186    # ignore all .txt files in the doc/ directory 
187    doc/**/*.txt 
188  
189A `**/` pattern is available in Git since version 1.8.2. 
190  
191### Viewing Your Staged and Unstaged Changes ### 
192  
193If the `git status` command is too vague for you — you want to know exactly what you changed, not just which files were changed — you can use the `git diff` command. We’ll cover `git diff` in more detail later; but you’ll probably use it most often to answer these two questions: What have you changed but not yet staged? And what have you staged that you are about to commit? Although `git status` answers those questions very generally, `git diff` shows you the exact lines added and removed — the patch, as it were. 
194  
195Let’s say you edit and stage the `README` file again and then edit the `benchmarks.rb` file without staging it. If you run your `status` command, you once again see something like this: 
196  
197    $ git status 
198    On branch master 
199    Changes to be committed: 
200      (use "git reset HEAD <file>..." to unstage) 
201      
202            new file:   README 
203      
204    Changes not staged for commit: 
205      (use "git add <file>..." to update what will be committed) 
206      (use "git checkout -- <file>..." to discard changes in working directory) 
207      
208            modified:   benchmarks.rb 
209      
210  
211To see what you’ve changed but not yet staged, type `git diff` with no other arguments: 
212  
213    $ git diff 
214    diff --git a/benchmarks.rb b/benchmarks.rb 
215    index 3cb747f..da65585 100644 
216    --- a/benchmarks.rb 
217    +++ b/benchmarks.rb 
218    @@ -36,6 +36,10 @@ def main 
219               @commit.parents[0].parents[0].parents[0] 
220             end 
221  
222    +        run_code(x, 'commits 1') do 
223    +          git.commits.size 
224    +        end 
225    + 
226             run_code(x, 'commits 2') do 
227               log = git.commits('master', 15) 
228               log.size 
229  
230That command compares what is in your working directory with what is in your staging area. The result tells you the changes you’ve made that you haven’t yet staged. 
231  
232If you want to see what you’ve staged that will go into your next commit, you can use `git diff --cached`. (In Git versions 1.6.1 and later, you can also use `git diff --staged`, which may be easier to remember.) This command compares your staged changes to your last commit: 
233  
234    $ git diff --cached 
235    diff --git a/README b/README 
236    new file mode 100644 
237    index 0000000..03902a1 
238    --- /dev/null 
239    +++ b/README2 
240    @@ -0,0 +1,5 @@ 
241    +grit 
242    + by Tom Preston-Werner, Chris Wanstrath 
243    + http://github.com/mojombo/grit 
244    + 
245    +Grit is a Ruby library for extracting information from a Git repository 
246  
247It’s important to note that `git diff` by itself doesn’t show all changes made since your last commit — only changes that are still unstaged. This can be confusing, because if you’ve staged all of your changes, `git diff` will give you no output. 
248  
249For another example, if you stage the `benchmarks.rb` file and then edit it, you can use `git diff` to see the changes in the file that are staged and the changes that are unstaged: 
250  
251    $ git add benchmarks.rb 
252    $ echo '# test line' >> benchmarks.rb 
253    $ git status 
254    On branch master 
255    Changes to be committed: 
256      (use "git reset HEAD <file>..." to unstage) 
257      
258            modified:   benchmarks.rb 
259      
260    Changes not staged for commit: 
261      (use "git add <file>..." to update what will be committed) 
262      (use "git checkout -- <file>..." to discard changes in working directory) 
263      
264            modified:   benchmarks.rb 
265      
266  
267Now you can use `git diff` to see what is still unstaged 
268  
269    $ git diff 
270    diff --git a/benchmarks.rb b/benchmarks.rb 
271    index e445e28..86b2f7c 100644 
272    --- a/benchmarks.rb 
273    +++ b/benchmarks.rb 
274    @@ -127,3 +127,4 @@ end 
275     main() 
276  
277     ##pp Grit::GitRuby.cache_client.stats 
278    +# test line 
279  
280and `git diff --cached` to see what you’ve staged so far: 
281  
282    $ git diff --cached 
283    diff --git a/benchmarks.rb b/benchmarks.rb 
284    index 3cb747f..e445e28 100644 
285    --- a/benchmarks.rb 
286    +++ b/benchmarks.rb 
287    @@ -36,6 +36,10 @@ def main 
288              @commit.parents[0].parents[0].parents[0] 
289            end 
290  
291    +        run_code(x, 'commits 1') do 
292    +          git.commits.size 
293    +        end 
294    + 
295            run_code(x, 'commits 2') do 
296              log = git.commits('master', 15) 
297              log.size 
298  
299### Committing Your Changes ### 
300  
301Now that your staging area is set up the way you want it, you can commit your changes. Remember that anything that is still unstaged — any files you have created or modified that you haven’t run `git add` on since you edited them — won’t go into this commit. They will stay as modified files on your disk. 
302In this case, the last time you ran `git status`, you saw that everything was staged, so you’re ready to commit your changes. The simplest way to commit is to type `git commit`: 
303  
304    $ git commit 
305  
306Doing so launches your editor of choice. (This is set by your shell’s `$EDITOR` environment variable — usually vim or emacs, although you can configure it with whatever you want using the `git config --global core.editor` command as you saw in *Chapter 1*). 
307  
308The editor displays the following text (this example is a Vim screen): 
309  
310    # Please enter the commit message for your changes. Lines starting 
311    # with '#' will be ignored, and an empty message aborts the commit. 
312    # On branch master 
313    # Changes to be committed: 
314    #       new file:   README 
315    #       modified:   benchmarks.rb 
316    # 
317    ~ 
318    ~ 
319    ~ 
320    ".git/COMMIT_EDITMSG" 10L, 283C 
321  
322You can see that the default commit message contains the latest output of the `git status` command commented out and one empty line on top. You can remove these comments and type your commit message, or you can leave them there to help you remember what you’re committing. (For an even more explicit reminder of what you’ve modified, you can pass the `-v` option to `git commit`. Doing so also puts the diff of your change in the editor so you can see exactly what you did.) When you exit the editor, Git creates your commit with that commit message (with the comments and diff stripped out). 
323  
324Alternatively, you can type your commit message inline with the `commit` command by specifying it after a `-m` flag, like this: 
325  
326    $ git commit -m "Story 182: Fix benchmarks for speed" 
327    [master 463dc4f] Story 182: Fix benchmarks for speed 
328     2 files changed, 3 insertions(+) 
329     create mode 100644 README 
330  
331Now you’ve created your first commit! You can see that the commit has given you some output about itself: which branch you committed to (`master`), what SHA-1 checksum the commit has (`463dc4f`), how many files were changed, and statistics about lines added and removed in the commit. 
332  
333Remember that the commit records the snapshot you set up in your staging area. Anything you didn’t stage is still sitting there modified; you can do another commit to add it to your history. Every time you perform a commit, you’re recording a snapshot of your project that you can revert to or compare to later. 
334  
335### Skipping the Staging Area ### 
336  
337Although it can be amazingly useful for crafting commits exactly how you want them, the staging area is sometimes a bit more complex than you need in your workflow. If you want to skip the staging area, Git provides a simple shortcut. Providing the `-a` option to the `git commit` command makes Git automatically stage every file that is already tracked before doing the commit, letting you skip the `git add` part: 
338  
339    $ git status 
340    On branch master 
341    Changes not staged for commit: 
342      (use "git add <file>..." to update what will be committed) 
343      (use "git checkout -- <file>..." to discard changes in working directory) 
344      
345            modified:   benchmarks.rb 
346      
347    no changes added to commit (use "git add" and/or "git commit -a") 
348    $ git commit -a -m 'added new benchmarks' 
349    [master 83e38c7] added new benchmarks 
350     1 files changed, 5 insertions(+) 
351  
352Notice how you don’t have to run `git add` on the `benchmarks.rb` file in this case before you commit. 
353  
354### Removing Files ### 
355  
356To remove a file from Git, you have to remove it from your tracked files (more accurately, remove it from your staging area) and then commit. The `git rm` command does that and also removes the file from your working directory so you don’t see it as an untracked file next time around. 
357  
358If you simply remove the file from your working directory, it shows up under the “Changes not staged for commit” (that is, _unstaged_) area of your `git status` output: 
359  
360    $ rm grit.gemspec 
361    $ git status 
362    On branch master 
363    Changes not staged for commit: 
364      (use "git add/rm <file>..." to update what will be committed) 
365      (use "git checkout -- <file>..." to discard changes in working directory) 
366      
367            deleted:    grit.gemspec 
368      
369    no changes added to commit (use "git add" and/or "git commit -a") 
370  
371Then, if you run `git rm`, it stages the file’s removal: 
372  
373    $ git rm grit.gemspec 
374    rm 'grit.gemspec' 
375    $ git status 
376    On branch master 
377    Changes to be committed: 
378      (use "git reset HEAD <file>..." to unstage) 
379      
380            deleted:    grit.gemspec 
381      
382  
383The next time you commit, the file will be gone and no longer tracked. If you modified the file and added it to the index already, you must force the removal with the `-f` option. This is a safety feature to prevent accidental removal of data that hasn’t yet been recorded in a snapshot and that can’t be recovered from Git. 
384  
385Another useful thing you may want to do is to keep the file in your working tree but remove it from your staging area. In other words, you may want to keep the file on your hard drive but not have Git track it anymore. This is particularly useful if you forgot to add something to your `.gitignore` file and accidentally staged it, like a large log file or a bunch of `.a` compiled files. To do this, use the `--cached` option: 
386  
387    $ git rm --cached readme.txt 
388  
389You can pass files, directories, and file-glob patterns to the `git rm` command. That means you can do things such as 
390  
391    $ git rm log/\*.log 
392  
393Note the backslash (`\`) in front of the `*`. This is necessary because Git does its own filename expansion in addition to your shell’s filename expansion. On Windows with the system console, the backslash must be omitted. This command removes all files that have the `.log` extension in the `log/` directory. Or, you can do something like this: 
394  
395    $ git rm \*~ 
396  
397This command removes all files that end with `~`. 
398  
399### Moving Files ### 
400  
401Unlike many other VCS systems, Git doesn’t explicitly track file movement. If you rename a file in Git, no metadata is stored in Git that tells it you renamed the file. However, Git is pretty smart about figuring that out after the fact — we’ll deal with detecting file movement a bit later. 
402  
403Thus it’s a bit confusing that Git has a `mv` command. If you want to rename a file in Git, you can run something like 
404  
405    $ git mv file_from file_to 
406  
407and it works fine. In fact, if you run something like this and look at the status, you’ll see that Git considers it a renamed file: 
408  
409    $ git mv README README.txt 
410    $ git status 
411    On branch master 
412    Changes to be committed: 
413      (use "git reset HEAD <file>..." to unstage) 
414      
415            renamed:    README -> README.txt 
416      
417  
418However, this is equivalent to running something like this: 
419  
420    $ mv README README.txt 
421    $ git rm README 
422    $ git add README.txt 
423  
424Git figures out that it’s a rename implicitly, so it doesn’t matter if you rename a file that way or with the `mv` command. The only real difference is that `mv` is one command instead of three — it’s a convenience function. More important, you can use any tool you like to rename a file, and address the add/rm later, before you commit. 
425  
426## Viewing the Commit History ## 
427  
428After you have created several commits, or if you have cloned a repository with an existing commit history, you’ll probably want to look back to see what has happened. The most basic and powerful tool to do this is the `git log` command. 
429  
430These examples use a very simple project called `simplegit` that I often use for demonstrations. To get the project, run 
431  
432    git clone git://github.com/schacon/simplegit-progit.git 
433  
434When you run `git log` in this project, you should get output that looks something like this: 
435  
436    $ git log 
437    commit ca82a6dff817ec66f44342007202690a93763949 
438    Author: Scott Chacon <schacon@gee-mail.com> 
439    Date:   Mon Mar 17 21:52:11 2008 -0700 
440  
441        changed the version number 
442  
443    commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 
444    Author: Scott Chacon <schacon@gee-mail.com> 
445    Date:   Sat Mar 15 16:40:33 2008 -0700 
446  
447        removed unnecessary test code 
448  
449    commit a11bef06a3f659402fe7563abf99ad00de2209e6 
450    Author: Scott Chacon <schacon@gee-mail.com> 
451    Date:   Sat Mar 15 10:31:28 2008 -0700 
452  
453        first commit 
454  
455By default, with no arguments, `git log` lists the commits made in that repository in reverse chronological order. That is, the most recent commits show up first. As you can see, this command lists each commit with its SHA-1 checksum, the author’s name and e-mail, the date written, and the commit message. 
456  
457A huge number and variety of options to the `git log` command are available to show you exactly what you’re looking for. Here, we’ll show you some of the most-used options. 
458  
459One of the more helpful options is `-p`, which shows the diff introduced in each commit. You can also use `-2`, which limits the output to only the last two entries: 
460  
461    $ git log -p -2 
462    commit ca82a6dff817ec66f44342007202690a93763949 
463    Author: Scott Chacon <schacon@gee-mail.com> 
464    Date:   Mon Mar 17 21:52:11 2008 -0700 
465  
466        changed the version number 
467  
468    diff --git a/Rakefile b/Rakefile 
469    index a874b73..8f94139 100644 
470    --- a/Rakefile 
471    +++ b/Rakefile 
472    @@ -5,5 +5,5 @@ require 'rake/gempackagetask' 
473     spec = Gem::Specification.new do |s| 
474         s.name      =   "simplegit" 
475    -    s.version   =   "0.1.0" 
476    +    s.version   =   "0.1.1" 
477         s.author    =   "Scott Chacon" 
478         s.email     =   "schacon@gee-mail.com 
479  
480    commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 
481    Author: Scott Chacon <schacon@gee-mail.com> 
482    Date:   Sat Mar 15 16:40:33 2008 -0700 
483  
484        removed unnecessary test code 
485  
486    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
487    index a0a60ae..47c6340 100644 
488    --- a/lib/simplegit.rb 
489    +++ b/lib/simplegit.rb 
490    @@ -18,8 +18,3 @@ class SimpleGit 
491         end 
492  
493     end 
494    - 
495    -if $0 == __FILE__ 
496    -  git = SimpleGit.new 
497    -  puts git.show 
498    -end 
499    \ No newline at end of file 
500  
501This option displays the same information but with a diff directly following each entry. This is very helpful for code review or to quickly browse what happened during a series of commits that a collaborator has added. 
502  
503Sometimes it's easier to review changes on the word level rather than on the line level. There is a `--word-diff` option available in Git, that you can append to the `git log -p` command to get word diff instead of normal line by line diff. Word diff format is quite useless when applied to source code, but it comes in handy when applied to large text files, like books or your dissertation. Here is an example: 
504  
505    $ git log -U1 --word-diff 
506    commit ca82a6dff817ec66f44342007202690a93763949 
507    Author: Scott Chacon <schacon@gee-mail.com> 
508    Date:   Mon Mar 17 21:52:11 2008 -0700 
509  
510        changed the version number 
511  
512    diff --git a/Rakefile b/Rakefile 
513    index a874b73..8f94139 100644 
514    --- a/Rakefile 
515    +++ b/Rakefile 
516    @@ -7,3 +7,3 @@ spec = Gem::Specification.new do |s| 
517        s.name      =   "simplegit" 
518        s.version   =   [-"0.1.0"-]{+"0.1.1"+} 
519        s.author    =   "Scott Chacon" 
520  
521As you can see, there is no added and removed lines in this output as in a normal diff. Changes are shown inline instead. You can see the added word enclosed in `{+ +}` and removed one enclosed in `[- -]`. You may also want to reduce the usual three lines context in diff output to only one line, as the context is now words, not lines. You can do this with `-U1` as we did in the example above. 
522  
523You can also use a series of summarizing options with `git log`. For example, if you want to see some abbreviated stats for each commit, you can use the `--stat` option: 
524  
525    $ git log --stat 
526    commit ca82a6dff817ec66f44342007202690a93763949 
527    Author: Scott Chacon <schacon@gee-mail.com> 
528    Date:   Mon Mar 17 21:52:11 2008 -0700 
529  
530        changed the version number 
531  
532     Rakefile |    2 +- 
533     1 file changed, 1 insertion(+), 1 deletion(-) 
534  
535    commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 
536    Author: Scott Chacon <schacon@gee-mail.com> 
537    Date:   Sat Mar 15 16:40:33 2008 -0700 
538  
539        removed unnecessary test code 
540  
541     lib/simplegit.rb |    5 ----- 
542     1 file changed, 5 deletions(-) 
543  
544    commit a11bef06a3f659402fe7563abf99ad00de2209e6 
545    Author: Scott Chacon <schacon@gee-mail.com> 
546    Date:   Sat Mar 15 10:31:28 2008 -0700 
547  
548        first commit 
549  
550     README           |    6 ++++++ 
551     Rakefile         |   23 +++++++++++++++++++++++ 
552     lib/simplegit.rb |   25 +++++++++++++++++++++++++ 
553     3 files changed, 54 insertions(+) 
554  
555As you can see, the `--stat` option prints below each commit entry a list of modified files, how many files were changed, and how many lines in those files were added and removed. It also puts a summary of the information at the end. 
556Another really useful option is `--pretty`. This option changes the log output to formats other than the default. A few prebuilt options are available for you to use. The `oneline` option prints each commit on a single line, which is useful if you’re looking at a lot of commits. In addition, the `short`, `full`, and `fuller` options show the output in roughly the same format but with less or more information, respectively: 
557  
558    $ git log --pretty=oneline 
559    ca82a6dff817ec66f44342007202690a93763949 changed the version number 
560    085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code 
561    a11bef06a3f659402fe7563abf99ad00de2209e6 first commit 
562  
563The most interesting option is `format`, which allows you to specify your own log output format. This is especially useful when you’re generating output for machine parsing — because you specify the format explicitly, you know it won’t change with updates to Git: 
564  
565    $ git log --pretty=format:"%h - %an, %ar : %s" 
566    ca82a6d - Scott Chacon, 11 months ago : changed the version number 
567    085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code 
568    a11bef0 - Scott Chacon, 11 months ago : first commit 
569  
570Table 2-1 lists some of the more useful options that format takes. 
571  
572<!-- Attention to translators: this is a table declaration. 
573The lines must be formatted as follows 
574<TAB><First column text><TAB><Second column text> 
575--> 
576  
577    Option  Description of Output 
578    %H  Commit hash 
579    %h  Abbreviated commit hash 
580    %T  Tree hash 
581    %t  Abbreviated tree hash 
582    %P  Parent hashes 
583    %p  Abbreviated parent hashes 
584    %an Author name 
585    %ae Author e-mail 
586    %ad Author date (format respects the --date= option) 
587    %ar Author date, relative 
588    %cn Committer name 
589    %ce Committer email 
590    %cd Committer date 
591    %cr Committer date, relative 
592    %s  Subject 
593  
594You may be wondering what the difference is between _author_ and _committer_. The _author_ is the person who originally wrote the patch, whereas the _committer_ is the person who last applied the patch. So, if you send in a patch to a project and one of the core members applies the patch, both of you get credit — you as the author and the core member as the committer. We’ll cover this distinction a bit more in *Chapter 5*. 
595  
596The `oneline` and `format` options are particularly useful with another `log` option called `--graph`. This option adds a nice little ASCII graph showing your branch and merge history, which we can see in our copy of the Grit project repository: 
597  
598    $ git log --pretty=format:"%h %s" --graph 
599    * 2d3acf9 ignore errors from SIGCHLD on trap 
600    *  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit 
601    |\ 
602    | * 420eac9 Added a method for getting the current branch. 
603    * | 30e367c timeout code and tests 
604    * | 5a09431 add timeout protection to grit 
605    * | e1193f8 support for heads with slashes in them 
606    |/ 
607    * d6016bc require time for xmlschema 
608    *  11d191e Merge branch 'defunkt' into local 
609  
610Those are only some simple output-formatting options to `git log` — there are many more. Table 2-2 lists the options we’ve covered so far and some other common formatting options that may be useful, along with how they change the output of the `log` command. 
611  
612<!-- Attention to translators: this is a table declaration. 
613The lines must be formatted as follows 
614<TAB><First column text><TAB><Second column text> 
615--> 
616  
617    Option  Description 
618    -p  Show the patch introduced with each commit. 
619    --word-diff Show the patch in a word diff format. 
620    --stat  Show statistics for files modified in each commit. 
621    --shortstat Display only the changed/insertions/deletions line from the --stat command. 
622    --name-only Show the list of files modified after the commit information. 
623    --name-status   Show the list of files affected with added/modified/deleted information as well. 
624    --abbrev-commit Show only the first few characters of the SHA-1 checksum instead of all 40. 
625    --relative-date Display the date in a relative format (for example, “2 weeks ago”) instead of using the full date format. 
626    --graph Display an ASCII graph of the branch and merge history beside the log output. 
627    --pretty    Show commits in an alternate format. Options include oneline, short, full, fuller, and format (where you specify your own format). 
628    --oneline   A convenience option short for `--pretty=oneline --abbrev-commit`. 
629  
630### Limiting Log Output ### 
631  
632In addition to output-formatting options, `git log` takes a number of useful limiting options — that is, options that let you show only a subset of commits. You’ve seen one such option already — the `-2` option, which shows only the last two commits. In fact, you can do `-<n>`, where `n` is any integer to show the last `n` commits. In reality, you’re unlikely to use that often, because Git by default pipes all output through a pager so you see only one page of log output at a time. 
633  
634However, the time-limiting options such as `--since` and `--until` are very useful. For example, this command gets the list of commits made in the last two weeks: 
635  
636    $ git log --since=2.weeks 
637  
638This command works with lots of formats — you can specify a specific date (“2008-01-15”) or a relative date such as “2 years 1 day 3 minutes ago”. 
639  
640You can also filter the list to commits that match some search criteria. The `--author` option allows you to filter on a specific author, and the `--grep` option lets you search for keywords in the commit messages. (Note that if you specify both author and grep options, the command will match commits with both.) 
641  
642If you want to specify multiple grep options, you have to add `--all-match` or the command will match commits with either. 
643  
644The last really useful option to pass to `git log` as a filter is a path. If you specify a directory or file name, you can limit the log output to commits that introduced a change to those files. This is always the last option and is generally preceded by double dashes (`--`) to separate the paths from the options. 
645  
646In Table 2-3 we’ll list these and a few other common options for your reference. 
647  
648<!-- Attention to translators: this is a table declaration. 
649The lines must be formatted as follows 
650<TAB><First column text><TAB><Second column text> 
651--> 
652  
653    Option  Description 
654    -(n)    Show only the last n commits 
655    --since, --after    Limit the commits to those whose CommitDate was made on-or-after the specified date/time. 
656    --until, --before   Limit the commits to those whose CommitDate was made on-or-before the specified date/time. 
657    --author    Only show commits in which the author entry matches the specified string. 
658    --committer Only show commits in which the committer entry matches the specified string. 
659  
660  
661### Limiting Log Output according to Date/Time ### 
662  
663To determine which commits in the Git source code repository (git://git.kernel.org/pub/scm/git/git.git) have CommitDate on 2014-04-29 relative to your local timezone (as set on your computer), use 
664  
665    $ git log --after="2014-04-29 00:00:00" --before="2014-04-29 23:59:59" \ 
666      --pretty=fuller 
667  
668As the output will be different according to the timezone where it will be run, it's recommended to always use an absolute time such as ISO 8601 format (which includes timezone information) as argument to `--after` and `--before`, so that everone running the command will get the same repeatable results.  
669  
670To obtain commits made at a specific instant in time (e.g. 29 April 2013 at 17:07:22 CET), we can use 
671  
672    $ git log  --after="2013-04-29T17:07:22+0200"      \ 
673              --before="2013-04-29T17:07:22+0200" --pretty=fuller 
674      
675    commit de7c201a10857e5d424dbd8db880a6f24ba250f9 
676    Author:     Ramkumar Ramachandra <artagnon@gmail.com> 
677    AuthorDate: Mon Apr 29 18:19:37 2013 +0530 
678    Commit:     Junio C Hamano <gitster@pobox.com> 
679    CommitDate: Mon Apr 29 08:07:22 2013 -0700 
680      
681        git-completion.bash: lexical sorting for diff.statGraphWidth 
682          
683        df44483a (diff --stat: add config option to limit graph width, 
684        2012-03-01) added the option diff.startGraphWidth to the list of 
685        configuration variables in git-completion.bash, but failed to notice 
686        that the list is sorted alphabetically.  Move it to its rightful place 
687        in the list. 
688          
689        Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> 
690        Signed-off-by: Junio C Hamano <gitster@pobox.com> 
691  
692The above times (`AuthorDate`, `CommitDate`) are displayed in default format (`--date=default`), which shows timezone information of respective author and commiter. 
693  
694Other useful formats include `--date=iso` (ISO 8601), `--date=rfc` (RFC 2822), `--date=raw` (seconds since the epoch (1970-01-01 UTC)) `--date=local` (times according to your local timezone) as well as `--date=relative` (e.g. "2 hours ago"). 
695  
696When using `git log` without specifying time, the time defaults to the time at which the command is run on your computer (keeping the identical offset from UTC). 
697  
698For example, running a `git log` at 09:00 on your computer with your timezone currently 3 hours ahead of UTC, makes the following two commands equivalent: 
699  
700    $ git log --after=2008-06-01 --before=2008-07-01 
701    $ git log --after="2008-06-01T09:00:00+0300" \ 
702        --before="2008-07-01T09:00:00+0300" 
703  
704As a final example, if you want to see which commits modifying test files in the Git source code history were committed by Junio Hamano with CommitDate being in the month of October 2008 (relative to the timezone of New York) and were not merges, you can run something like this: 
705  
706        $ git log --pretty="%h - %s" --author=gitster \ 
707           --after="2008-10-01T00:00:00-0400"         \ 
708          --before="2008-10-31T23:59:59-0400" --no-merges -- t/ 
709    5610e3b - Fix testcase failure when extended attribute 
710    acd3b9e - Enhance hold_lock_file_for_{update,append}() 
711    f563754 - demonstrate breakage of detached checkout wi 
712    d1a43f2 - reset --hard/read-tree --reset -u: remove un 
713    51a94af - Fix "checkout --track -b newbranch" on detac 
714    b0ad11e - pull: allow "git pull origin $something:$cur 
715  
716Of the more than 36,000 commits in the Git source code history, this command shows the 6 that match those criteria. 
717  
718### Using a GUI to Visualize History ### 
719  
720If you like to use a more graphical tool to visualize your commit history, you may want to take a look at a Tcl/Tk program called `gitk` that is distributed with Git. Gitk is basically a visual `git log` tool, and it accepts nearly all the filtering options that `git log` does. If you type `gitk` on the command line in your project, you should see something like Figure 2-2. 
721  
722Insert 18333fig0202.png 
723Figure 2-2. The gitk history visualizer. 
724  
725You can see the commit history in the top half of the window along with a nice ancestry graph. The diff viewer in the bottom half of the window shows you the changes introduced at any commit you click. 
726  
727## Undoing Things ## 
728  
729At any stage, you may want to undo something. Here, we’ll review a few basic tools for undoing changes that you’ve made. Be careful, because you can’t always revert some of these undos. This is one of the few areas in Git where you may lose some work if you do it wrong. 
730  
731### Changing Your Last Commit ### 
732  
733One of the common undos takes place when you commit too early and possibly forget to add some files, or you mess up your commit message. If you want to try that commit again, you can run commit with the `--amend` option: 
734  
735    $ git commit --amend 
736  
737This command takes your staging area and uses it for the commit. If you’ve made no changes since your last commit (for instance, you run this command immediately after your previous commit), then your snapshot will look exactly the same and all you’ll change is your commit message. 
738  
739The same commit-message editor fires up, but it already contains the message of your previous commit. You can edit the message the same as always, but it overwrites your previous commit. 
740  
741As an example, if you commit and then realize you forgot to stage the changes in a file you wanted to add to this commit, you can do something like this: 
742  
743    $ git commit -m 'initial commit' 
744    $ git add forgotten_file 
745    $ git commit --amend 
746  
747After these three commands, you end up with a single commit — the second commit replaces the results of the first. 
748  
749### Unstaging a Staged File ### 
750  
751The next two sections demonstrate how to wrangle your staging area and working directory changes. The nice part is that the command you use to determine the state of those two areas also reminds you how to undo changes to them. For example, let’s say you’ve changed two files and want to commit them as two separate changes, but you accidentally type `git add *` and stage them both. How can you unstage one of the two? The `git status` command reminds you: 
752  
753    $ git add . 
754    $ git status 
755    On branch master 
756    Changes to be committed: 
757      (use "git reset HEAD <file>..." to unstage) 
758      
759            modified:   README.txt 
760            modified:   benchmarks.rb 
761      
762  
763Right below the “Changes to be committed” text, it says "use `git reset HEAD <file>...` to unstage". So, let’s use that advice to unstage the `benchmarks.rb` file: 
764  
765    $ git reset HEAD benchmarks.rb 
766    Unstaged changes after reset: 
767    M       benchmarks.rb 
768    $ git status 
769    On branch master 
770    Changes to be committed: 
771      (use "git reset HEAD <file>..." to unstage) 
772      
773            modified:   README.txt 
774      
775    Changes not staged for commit: 
776      (use "git add <file>..." to update what will be committed) 
777      (use "git checkout -- <file>..." to discard changes in working directory) 
778      
779            modified:   benchmarks.rb 
780      
781  
782The command is a bit strange, but it works. The `benchmarks.rb` file is modified but once again unstaged. 
783  
784### Unmodifying a Modified File ### 
785  
786What if you realize that you don’t want to keep your changes to the `benchmarks.rb` file? How can you easily unmodify it — revert it back to what it looked like when you last committed (or initially cloned, or however you got it into your working directory)? Luckily, `git status` tells you how to do that, too. In the last example output, the unstaged area looks like this: 
787  
788    Changes not staged for commit: 
789      (use "git add <file>..." to update what will be committed) 
790      (use "git checkout -- <file>..." to discard changes in working directory) 
791      
792            modified:   benchmarks.rb 
793      
794  
795It tells you pretty explicitly how to discard the changes you’ve made (at least, the newer versions of Git, 1.6.1 and later, do this — if you have an older version, we highly recommend upgrading it to get some of these nicer usability features). Let’s do what it says: 
796  
797    $ git checkout -- benchmarks.rb 
798    $ git status 
799    On branch master 
800    Changes to be committed: 
801      (use "git reset HEAD <file>..." to unstage) 
802      
803            modified:   README.txt 
804      
805  
806You can see that the changes have been reverted. You should also realize that this is a dangerous command: any changes you made to that file are gone — you just copied another file over it. Don’t ever use this command unless you absolutely know that you don’t want the file. If you just need to get it out of the way, we’ll go over stashing and branching in the next chapter; these are generally better ways to go. 
807  
808Remember, anything that is committed in Git can almost always be recovered. Even commits that were on branches that were deleted or commits that were overwritten with an `--amend` commit can be recovered (see *Chapter 9* for data recovery). However, anything you lose that was never committed is likely never to be seen again. 
809  
810## Working with Remotes ## 
811  
812To be able to collaborate on any Git project, you need to know how to manage your remote repositories. Remote repositories are versions of your project that are hosted on the Internet or network somewhere. You can have several of them, each of which generally is either read-only or read/write for you. Collaborating with others involves managing these remote repositories and pushing and pulling data to and from them when you need to share work. 
813Managing remote repositories includes knowing how to add remote repositories, remove remotes that are no longer valid, manage various remote branches and define them as being tracked or not, and more. In this section, we’ll cover these remote-management skills. 
814  
815### Showing Your Remotes ### 
816  
817To see which remote servers you have configured, you can run the `git remote` command. It lists the shortnames of each remote handle you’ve specified. If you’ve cloned your repository, you should at least see *origin* — that is the default name Git gives to the server you cloned from: 
818  
819    $ git clone git://github.com/schacon/ticgit.git 
820    Cloning into 'ticgit'... 
821    remote: Reusing existing pack: 1857, done. 
822    remote: Total 1857 (delta 0), reused 0 (delta 0) 
823    Receiving objects: 100% (1857/1857), 374.35 KiB | 193.00 KiB/s, done. 
824    Resolving deltas: 100% (772/772), done. 
825    Checking connectivity... done. 
826    $ cd ticgit 
827    $ git remote 
828    origin 
829  
830You can also specify `-v`, which shows you the URL that Git has stored for the shortname to be expanded to: 
831  
832    $ git remote -v 
833    origin  git://github.com/schacon/ticgit.git (fetch) 
834    origin  git://github.com/schacon/ticgit.git (push) 
835  
836If you have more than one remote, the command lists them all. For example, my Grit repository looks something like this. 
837  
838    $ cd grit 
839    $ git remote -v 
840    bakkdoor  git://github.com/bakkdoor/grit.git 
841    cho45     git://github.com/cho45/grit.git 
842    defunkt   git://github.com/defunkt/grit.git 
843    koke      git://github.com/koke/grit.git 
844    origin    git@github.com:mojombo/grit.git 
845  
846This means I can pull contributions from any of these users pretty easily. But notice that only the origin remote is an SSH URL, so it’s the only one I can push to (we’ll cover why this is in *Chapter 4*). 
847  
848### Adding Remote Repositories ### 
849  
850I’ve mentioned and given some demonstrations of adding remote repositories in previous sections, but here is how to do it explicitly. To add a new remote Git repository as a shortname you can reference easily, run `git remote add [shortname] [url]`: 
851  
852    $ git remote 
853    origin 
854    $ git remote add pb git://github.com/paulboone/ticgit.git 
855    $ git remote -v 
856    origin  git://github.com/schacon/ticgit.git 
857    pb  git://github.com/paulboone/ticgit.git 
858  
859Now you can use the string `pb` on the command line in lieu of the whole URL. For example, if you want to fetch all the information that Paul has but that you don’t yet have in your repository, you can run `git fetch pb`: 
860  
861    $ git fetch pb 
862    remote: Counting objects: 58, done. 
863    remote: Compressing objects: 100% (41/41), done. 
864    remote: Total 44 (delta 24), reused 1 (delta 0) 
865    Unpacking objects: 100% (44/44), done. 
866    From git://github.com/paulboone/ticgit 
867     * [new branch]      master     -> pb/master 
868     * [new branch]      ticgit     -> pb/ticgit 
869  
870Paul’s master branch is accessible locally as `pb/master` — you can merge it into one of your branches, or you can check out a local branch at that point if you want to inspect it. 
871  
872### Fetching and Pulling from Your Remotes ### 
873  
874As you just saw, to get data from your remote projects, you can run: 
875  
876    $ git fetch [remote-name] 
877  
878The command goes out to that remote project and pulls down all the data from that remote project that you don’t have yet. After you do this, you should have references to all the branches from that remote, which you can merge in or inspect at any time. (We’ll go over what branches are and how to use them in much more detail in *Chapter 3*.) 
879  
880If you clone a repository, the command automatically adds that remote repository under the name *origin*. So, `git fetch origin` fetches any new work that has been pushed to that server since you cloned (or last fetched from) it. It’s important to note that the `fetch` command pulls the data to your local repository — it doesn’t automatically merge it with any of your work or modify what you’re currently working on. You have to merge it manually into your work when you’re ready. 
881  
882If you have a branch set up to track a remote branch (see the next section and *Chapter 3* for more information), you can use the `git pull` command to automatically fetch and then merge a remote branch into your current branch. This may be an easier or more comfortable workflow for you; and by default, the `git clone` command automatically sets up your local master branch to track the remote master branch on the server you cloned from (assuming the remote has a master branch). Running `git pull` generally fetches data from the server you originally cloned from and automatically tries to merge it into the code you’re currently working on. 
883  
884### Pushing to Your Remotes ### 
885  
886When you have your project at a point that you want to share, you have to push it upstream. The command for this is simple: `git push [remote-name] [branch-name]`. If you want to push your master branch to your `origin` server (again, cloning generally sets up both of those names for you automatically), then you can run this to push your work back up to the server: 
887  
888    $ git push origin master 
889  
890This command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to pull down their work first and incorporate it into yours before you’ll be allowed to push. See *Chapter 3* for more detailed information on how to push to remote servers. 
891  
892### Inspecting a Remote ### 
893  
894If you want to see more information about a particular remote, you can use the `git remote show [remote-name]` command. If you run this command with a particular shortname, such as `origin`, you get something like this: 
895  
896    $ git remote show origin 
897    * remote origin 
898      URL: git://github.com/schacon/ticgit.git 
899      Remote branch merged with 'git pull' while on branch master 
900        master 
901      Tracked remote branches 
902        master 
903        ticgit 
904  
905It lists the URL for the remote repository as well as the tracking branch information. The command helpfully tells you that if you’re on the master branch and you run `git pull`, it will automatically merge in the master branch on the remote after it fetches all the remote references. It also lists all the remote references it has pulled down. 
906  
907That is a simple example you’re likely to encounter. When you’re using Git more heavily, however, you may see much more information from `git remote show`: 
908  
909    $ git remote show origin 
910    * remote origin 
911      URL: git@github.com:defunkt/github.git 
912      Remote branch merged with 'git pull' while on branch issues 
913        issues 
914      Remote branch merged with 'git pull' while on branch master 
915        master 
916      New remote branches (next fetch will store in remotes/origin) 
917        caching 
918      Stale tracking branches (use 'git remote prune') 
919        libwalker 
920        walker2 
921      Tracked remote branches 
922        acl 
923        apiv2 
924        dashboard2 
925        issues 
926        master 
927        postgres 
928      Local branch pushed with 'git push' 
929        master:master 
930  
931This command shows which branch is automatically pushed when you run `git push` on certain branches. It also shows you which remote branches on the server you don’t yet have, which remote branches you have that have been removed from the server, and multiple branches that are automatically merged when you run `git pull`. 
932  
933### Removing and Renaming Remotes ### 
934  
935If you want to rename a reference, in newer versions of Git you can run `git remote rename` to change a remote’s shortname. For instance, if you want to rename `pb` to `paul`, you can do so with `git remote rename`: 
936  
937    $ git remote rename pb paul 
938    $ git remote 
939    origin 
940    paul 
941  
942It’s worth mentioning that this changes your remote branch names, too. What used to be referenced at `pb/master` is now at `paul/master`. 
943  
944If you want to remove a reference for some reason — you’ve moved the server or are no longer using a particular mirror, or perhaps a contributor isn’t contributing anymore — you can use `git remote rm`: 
945  
946    $ git remote rm paul 
947    $ git remote 
948    origin 
949  
950## Tagging ## 
951  
952Like most VCSs, Git has the ability to tag specific points in history as being important. Generally, people use this functionality to mark release points (`v1.0`, and so on). In this section, you’ll learn how to list the available tags, how to create new tags, and what the different types of tags are. 
953  
954### Listing Your Tags ### 
955  
956Listing the available tags in Git is straightforward. Just type `git tag`: 
957  
958    $ git tag 
959    v0.1 
960    v1.3 
961  
962This command lists the tags in alphabetical order; the order in which they appear has no real importance. 
963  
964You can also search for tags with a particular pattern. The Git source repo, for instance, contains more than 240 tags. If you’re only interested in looking at the 1.4.2 series, you can run this: 
965  
966    $ git tag -l 'v1.4.2.*' 
967    v1.4.2.1 
968    v1.4.2.2 
969    v1.4.2.3 
970    v1.4.2.4 
971  
972### Creating Tags ### 
973  
974Git uses two main types of tags: lightweight and annotated. A lightweight tag is very much like a branch that doesn’t change — it’s just a pointer to a specific commit. Annotated tags, however, are stored as full objects in the Git database. They’re checksummed; contain the tagger name, e-mail, and date; have a tagging message; and can be signed and verified with GNU Privacy Guard (GPG). It’s generally recommended that you create annotated tags so you can have all this information; but if you want a temporary tag or for some reason don’t want to keep the other information, lightweight tags are available too. 
975  
976### Annotated Tags ### 
977  
978Creating an annotated tag in Git is simple. The easiest way is to specify `-a` when you run the `tag` command: 
979  
980    $ git tag -a v1.4 -m 'my version 1.4' 
981    $ git tag 
982    v0.1 
983    v1.3 
984    v1.4 
985  
986The `-m` specifies a tagging message, which is stored with the tag. If you don’t specify a message for an annotated tag, Git launches your editor so you can type it in. 
987  
988You can see the tag data along with the commit that was tagged by using the `git show` command: 
989  
990    $ git show v1.4 
991    tag v1.4 
992    Tagger: Scott Chacon <schacon@gee-mail.com> 
993    Date:   Mon Feb 9 14:45:11 2009 -0800 
994  
995    my version 1.4 
996  
997    commit 15027957951b64cf874c3557a0f3547bd83b3ff6 
998    Merge: 4a447f7... a6b4c97... 
999    Author: Scott Chacon <schacon@gee-mail.com> 
1000    Date:   Sun Feb 8 19:02:46 2009 -0800 
1001  
1002        Merge branch 'experiment' 
1003  
1004That shows the tagger information, the date the commit was tagged, and the annotation message before showing the commit information. 
1005 35 
.1006### Signed Tags ### 36==== Signing Tags 
1007 37 
.1008You can also sign your tags with GPG, assuming you have a private key. All you have to do is use `-s` instead of `-a`:38If you have a GPG private key setup, you can now use it to sign new tags. All you have to do is use `-s` instead of `-a`:
1009 39 
. 40[source,console]
 41----
1010    $ git tag -s v1.5 -m 'my signed 1.5 tag'42$ git tag -s v1.5 -m 'my signed 1.5 tag'
 43 
1011    You need a passphrase to unlock the secret key for44You need a passphrase to unlock the secret key for
1012    user: "Scott Chacon <schacon@gee-mail.com>"45user: "Ben Straub <ben@straub.cc>"
1013    1024-bit DSA key, ID F721C45A, created 2009-02-09 462048-bit RSA key, ID 800430EB, created 2014-05-04 
 47----
1014 48 
1015If you run `git show` on that tag, you can see your GPG signature attached to it:49If you run `git show` on that tag, you can see your GPG signature attached to it:
1016 50 
. 51[source,console]
 52--------
1017    $ git show v1.553$ git show v1.5
1018    tag v1.554tag v1.5
1019    Tagger: Scott Chacon <schacon@gee-mail.com>55Tagger: Ben Straub <ben@straub.cc>
1020    Date:   Mon Feb 9 15:22:20 2009 -080056Date:   Sat May 3 20:29:41 2014 -0700
1021 57 
.1022    my signed 1.5 tag58my signed 1.5 tag
1023    -----BEGIN PGP SIGNATURE-----59-----BEGIN PGP SIGNATURE-----
1024    Version: GnuPG v1.4.8 (Darwin) 60Version: GnuPG v1 
1025 61 
.1026    iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN 62iQEcBAABAgAGBQJTZbQlAAoJEF0+sviABDDrZbQH/09PfE51KPVPlanr6q1v4/Ut 
1027    Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/ 63LQxfojUWiLQdg2ESJItkcuweYg+kc3HCyFejeDIBw9dpXt00rY26p05qrpnG+85b 
 64hM1/PswpPLuBSr+oCIDj5GMC2r2iEKsfv2fJbNW8iWAXVLoWZRF8B0MfqX/YTMbm
 65ecorc4iXzQu7tupRihslbNkfvfciMnSDeSvzCpWAHl7h8Wj6hhqePmLm9lAYqnKp
 668S5B/1SSQuEAjRZgI4IexpZoeKGVDptPHxLLS38fozsyi0QyDyzEgJxcJQVMXxVi
 67RUysgqjcpT8+iQM1PblGfHR4XAhuOqN5Fx06PSaFZhqvWFezJ28/CLyX5q+oIVk=
1028    =WryJ 68=EFTF 
1029    -----END PGP SIGNATURE-----69-----END PGP SIGNATURE-----
 70 
1030    commit 15027957951b64cf874c3557a0f3547bd83b3ff6 71commit ca82a6dff817ec66f44342007202690a93763949 
1031    Merge: 4a447f7... a6b4c97... 
1032    Author: Scott Chacon <schacon@gee-mail.com>72Author: Scott Chacon <schacon@gee-mail.com>
1033    Date:   Sun Feb 8 19:02:46 2009 -080073Date:   Mon Mar 17 21:52:11 2008 -0700
1034 74 
.1035        Merge branch 'experiment' 75    changed the version number 
1036 76-------- 
1037A bit later, you’ll learn how to verify signed tags. 
1038  
1039### Lightweight Tags ### 
1040  
1041Another way to tag commits is with a lightweight tag. This is basically the commit checksum stored in a file — no other information is kept. To create a lightweight tag, don’t supply the `-a`, `-s`, or `-m` option: 
1042  
1043    $ git tag v1.4-lw 
1044    $ git tag 
1045    v0.1 
1046    v1.3 
1047    v1.4 
1048    v1.4-lw 
1049    v1.5 
1050  
1051This time, if you run `git show` on the tag, you don’t see the extra tag information. The command just shows the commit: 
1052  
1053    $ git show v1.4-lw 
1054    commit 15027957951b64cf874c3557a0f3547bd83b3ff6 
1055    Merge: 4a447f7... a6b4c97... 
1056    Author: Scott Chacon <schacon@gee-mail.com> 
1057    Date:   Sun Feb 8 19:02:46 2009 -0800 
1058  
1059        Merge branch 'experiment' 
1060 77 
.1061### Verifying Tags ### 78==== Verifying Tags 
1062 79 
1063To verify a signed tag, you use `git tag -v [tag-name]`. This command uses GPG to verify the signature. You need the signer’s public key in your keyring for this to work properly:80To verify a signed tag, you use `git tag -v [tag-name]`. This command uses GPG to verify the signature. You need the signer’s public key in your keyring for this to work properly:
1064 81 
. 82[source,console]
 83----
1065    $ git tag -v v1.4.2.184$ git tag -v v1.4.2.1
1066    object 883653babd8ee7ea23e6a5c392bb739348b1eb6185object 883653babd8ee7ea23e6a5c392bb739348b1eb61
1067    type commit86type commit
1068    tag v1.4.2.187tag v1.4.2.1
1069    tagger Junio C Hamano <junkio@cox.net> 1158138501 -070088tagger Junio C Hamano <junkio@cox.net> 1158138501 -0700
1070 89 
.1071    GIT 1.4.2.190GIT 1.4.2.1
1072 91 
.1073    Minor fixes since 1.4.2, including git-mv and git-http with alternates.92Minor fixes since 1.4.2, including git-mv and git-http with alternates.
1074    gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A93gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1075    gpg: Good signature from "Junio C Hamano <junkio@cox.net>"94gpg: Good signature from "Junio C Hamano <junkio@cox.net>"
1076    gpg:                 aka "[jpeg image of size 1513]"95gpg:                 aka "[jpeg image of size 1513]"
1077    Primary key fingerprint: 3565 2A26 2040 E066 C9A7  4A7D C0C6 D9A4 F311 9B9A96Primary key fingerprint: 3565 2A26 2040 E066 C9A7  4A7D C0C6 D9A4 F311 9B9A
 97----
1078 98 
1079If you don’t have the signer’s public key, you get something like this instead:99If you don’t have the signer’s public key, you get something like this instead:
1080 100 
. 101[source,console]
 102----
1081    gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A103gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
1082    gpg: Can't check signature: public key not found104gpg: Can't check signature: public key not found
1083    error: could not verify the tag 'v1.4.2.1'105error: could not verify the tag 'v1.4.2.1'
 106----
 107 
 108[[_signing_commits]]
 109==== Signing Commits
 110 
 111In more recent versions of Git (v1.7.9 and above), you can now also sign individual commits.
 112If you're interested in signing commits directly instead of just the tags, all you need to do is add a `-S` to your `git commit` command.
 113 
 114[source,console]
 115----
 116$ git commit -a -S -m 'signed commit'
 117 
 118You need a passphrase to unlock the secret key for
 119user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
 1202048-bit RSA key, ID 0A46826A, created 2014-06-04
 121 
 122[master 5c3386c] signed commit
 123 4 files changed, 4 insertions(+), 24 deletions(-)
 124 rewrite Rakefile (100%)
 125 create mode 100644 lib/git.rb
 126----
 127 
 128To see and verify these signatures, there is also a `--show-signature` option to `git log`.
 129 
 130[source,console]
 131----
 132$ git log --show-signature -1
 133commit 5c3386cf54bba0a33a32da706aa52bc0155503c2
 134gpg: Signature made Wed Jun  4 19:49:17 2014 PDT using RSA key ID 0A46826A
 135gpg: Good signature from "Scott Chacon (Git signing key) <schacon@gmail.com>"
 136Author: Scott Chacon <schacon@gmail.com>
 137Date:   Wed Jun 4 19:49:17 2014 -0700
 138 
 139    signed commit
 140----
 141 
 142Additionally, you can configure `git log` to check any signatures it finds and list them in it's output with the `%G?` format.
 143 
 144[source,console]
 145----
 146$ git log --pretty="format:%h %G? %aN  %s"
 147 
 1485c3386c G Scott Chacon  signed commit
 149ca82a6d N Scott Chacon  changed the version number
 150085bb3b N Scott Chacon  removed unnecessary test code
 151a11bef0 N Scott Chacon  first commit
 152----
 153 
 154Here we can see that only the latest commit is signed and valid and the previous commits are not.
 155 
 156In Git 1.8.3 and later, "git merge" and "git pull" can  be told to inspect and reject when merging a commit that does not carry a trusted GPG signature with the `--verify-signatures` command.
 157 
 158If you use this option when merging a branch and it contains commits that are not signed and valid, the merge will not work.
 159 
 160[source,console]
 161----
 162$ git merge --verify-signatures non-verify
 163fatal: Commit ab06180 does not have a GPG signature.
 164----
 165 
 166If the merge contains only valid signed commits, the merge command will show you all the signatures it has checked and then move forward with the merge.
 167 
 168[source,console]
 169----
 170$ git merge --verify-signatures signed-branch
 171Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>
 172Updating 5c3386c..13ad65e
 173Fast-forward
 174 README | 2 ++
 175 1 file changed, 2 insertions(+)
 176----
 177 
 178You can also use the `-S` option with the `git merge` command itself to sign the resulting merge commit itself. The following example both verifies that every commit in the branch to be merged is signed and furthermore signs the resulting merge commit.
 179 
 180[source,console]
 181----
 182$ git merge --verify-signatures -S  signed-branch
 183Commit 13ad65e has a good GPG signature by Scott Chacon (Git signing key) <schacon@gmail.com>
 184 
 185You need a passphrase to unlock the secret key for
 186user: "Scott Chacon (Git signing key) <schacon@gmail.com>"
 1872048-bit RSA key, ID 0A46826A, created 2014-06-04
 188 
 189Merge made by the 'recursive' strategy.
 190 README | 2 ++
 191 1 file changed, 2 insertions(+)
 192----
1084 193 
.1085### Tagging Later ### 194==== Everyone Must Sign 
1086 195 
.1087You can also tag commits after you’ve moved past them. Suppose your commit history looks like this: 196Signing tags and commits is great, but if you decide to use this in your normal workflow, you'll have to make sure that everyone on your team understands how to do so. If you don't, you'll end up spending a lot of time helping people figure out how to rewrite their commits with signed versions. Make sure you understand GPG and the benefits of signing things before adopting this as part of your standard workflow. 
1088  
1089    $ git log --pretty=oneline 
1090    15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment' 
1091    a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support 
1092    0d52aaab4479697da7686c15f77a3d64d9165190 one more thing 
1093    6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment' 
1094    0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function 
1095    4682c3261057305bdd616e23b64b0857d832627b added a todo file 
1096    166ae0c4d3f420721acbb115cc33848dfcc2121a started write support 
1097    9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile 
1098    964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo 
1099    8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme 
1100  
1101Now, suppose you forgot to tag the project at `v1.2`, which was at the "updated rakefile" commit. You can add it after the fact. To tag that commit, you specify the commit checksum (or part of it) at the end of the command: 
1102  
1103    $ git tag -a v1.2 -m 'version 1.2' 9fceb02 
1104  
1105You can see that you’ve tagged the commit: 
1106  
1107    $ git tag 
1108    v0.1 
1109    v1.2 
1110    v1.3 
1111    v1.4 
1112    v1.4-lw 
1113    v1.5 
1114  
1115    $ git show v1.2 
1116    tag v1.2 
1117    Tagger: Scott Chacon <schacon@gee-mail.com> 
1118    Date:   Mon Feb 9 15:32:16 2009 -0800 
1119  
1120    version 1.2 
1121    commit 9fceb02d0ae598e95dc970b74767f19372d61af8 
1122    Author: Magnus Chacon <mchacon@gee-mail.com> 
1123    Date:   Sun Apr 27 20:43:35 2008 -0700 
1124  
1125        updated rakefile 
1126    ... 
1127  
1128### Sharing Tags ### 
1129  
1130By default, the `git push` command doesn’t transfer tags to remote servers. You will have to explicitly push tags to a shared server after you have created them.  This process is just like sharing remote branches — you can run `git push origin [tagname]`. 
1131  
1132    $ git push origin v1.5 
1133    Counting objects: 50, done. 
1134    Compressing objects: 100% (38/38), done. 
1135    Writing objects: 100% (44/44), 4.56 KiB, done. 
1136    Total 44 (delta 18), reused 8 (delta 1) 
1137    To git@github.com:schacon/simplegit.git 
1138    * [new tag]         v1.5 -> v1.5 
1139  
1140If you have a lot of tags that you want to push up at once, you can also use the `--tags` option to the `git push` command.  This will transfer all of your tags to the remote server that are not already there. 
1141  
1142    $ git push origin --tags 
1143    Counting objects: 50, done. 
1144    Compressing objects: 100% (38/38), done. 
1145    Writing objects: 100% (44/44), 4.56 KiB, done. 
1146    Total 44 (delta 18), reused 8 (delta 1) 
1147    To git@github.com:schacon/simplegit.git 
1148     * [new tag]         v0.1 -> v0.1 
1149     * [new tag]         v1.2 -> v1.2 
1150     * [new tag]         v1.4 -> v1.4 
1151     * [new tag]         v1.4-lw -> v1.4-lw 
1152     * [new tag]         v1.5 -> v1.5 
1153  
1154Now, when someone else clones or pulls from your repository, they will get all your tags as well. 
1155  
1156## Tips and Tricks ## 
1157  
1158Before we finish this chapter on basic Git, a few little tips and tricks may make your Git experience a bit simpler, easier, or more familiar. Many people use Git without using any of these tips, and we won’t refer to them or assume you’ve used them later in the book; but you should probably know how to do them. 
1159  
1160### Auto-Completion ### 
1161  
1162If you use the Bash shell, Git comes with a nice auto-completion script you can enable. Download it directly from the Git source code at https://github.com/git/git/blob/master/contrib/completion/git-completion.bash . Copy this file to your home directory, and add this to your `.bashrc` file: 
1163  
1164    source ~/git-completion.bash 
1165  
1166If you want to set up Git to automatically have Bash shell completion for all users, copy this script to the `/opt/local/etc/bash_completion.d` directory on Mac systems or to the `/etc/bash_completion.d/` directory on Linux systems. This is a directory of scripts that Bash will automatically load to provide shell completions. 
1167  
1168If you’re using Windows with Git Bash, which is the default when installing Git on Windows with msysGit, auto-completion should be preconfigured. 
1169  
1170Press the Tab key when you’re writing a Git command, and it should return a set of suggestions for you to pick from: 
1171  
1172    $ git co<tab><tab> 
1173    commit config 
1174  
1175In this case, typing `git co` and then pressing the Tab key twice suggests commit and config. Adding `m<tab>` completes `git commit` automatically. 
1176  
1177This also works with options, which is probably more useful. For instance, if you’re running a `git log` command and can’t remember one of the options, you can start typing it and press Tab to see what matches: 
1178  
1179    $ git log --s<tab><tab> 
1180    --shortstat               --sparse 
1181    --simplify-by-decoration  --src-prefix= 
1182    --simplify-merges         --stat 
1183    --since=                  --summary 
1184  
1185That’s a pretty nice trick and may save you some time and documentation reading. 
1186  
1187### Git Aliases ### 
1188  
1189Git doesn’t infer your command if you type it in partially. If you don’t want to type the entire text of each of the Git commands, you can easily set up an alias for each command using `git config`. Here are a couple of examples you may want to set up: 
1190  
1191    $ git config --global alias.co checkout 
1192    $ git config --global alias.br branch 
1193    $ git config --global alias.ci commit 
1194    $ git config --global alias.st status 
1195  
1196This means that, for example, instead of typing `git commit`, you just need to type `git ci`. As you go on using Git, you’ll probably use other commands frequently as well; in this case, don’t hesitate to create new aliases. 
1197  
1198This technique can also be very useful in creating commands that you think should exist. For example, to correct the usability problem you encountered with unstaging a file, you can add your own unstage alias to Git: 
1199  
1200    $ git config --global alias.unstage 'reset HEAD --' 
1201  
1202This makes the following two commands equivalent: 
1203  
1204    $ git unstage fileA 
1205    $ git reset HEAD fileA 
1206  
1207This seems a bit clearer. It’s also common to add a `last` command, like this: 
1208  
1209    $ git config --global alias.last 'log -1 HEAD' 
1210  
1211This way, you can see the last commit easily: 
1212  
1213    $ git last 
1214    commit 66938dae3329c7aebe598c2246a8e6af90d04646 
1215    Author: Josh Goebel <dreamer3@example.com> 
1216    Date:   Tue Aug 26 19:48:51 2008 +0800 
1217  
1218        test for current head 
1219  
1220        Signed-off-by: Scott Chacon <schacon@example.com> 
1221  
1222As you can tell, Git simply replaces the new command with whatever you alias it to. However, maybe you want to run an external command, rather than a Git subcommand. In that case, you start the command with a `!` character. This is useful if you write your own tools that work with a Git repository. We can demonstrate by aliasing `git visual` to run `gitk`: 
1223  
1224    $ git config --global alias.visual '!gitk' 
1225  
1226## Summary ## 
1227  
1228At this point, you can do all the basic local Git operations — creating or cloning a repository, making changes, staging and committing those changes, and viewing the history of all the changes the repository has been through. Next, we’ll cover Git’s killer feature: its branching model. 
1229 197 
+
+ diff --git a/book/07-git-tools/sections/diff-stashing-cleaning.htm b/book/07-git-tools/sections/diff-stashing-cleaning.htm new file mode 100644 index 00000000..22c18cc7 --- /dev/null +++ b/book/07-git-tools/sections/diff-stashing-cleaning.htm @@ -0,0 +1,5275 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\stashing-cleaning.asc
.1# Git Tools # 1[[_git_stashing]] 
2  
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. 
4  
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. 
6  
7## Revision Selection ## 
8  
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. 
10  
11### Single Revisions ### 
12  
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. 
14  
15### Short SHA ### 
16  
17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. 
18  
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: 
20  
21    $ git log 
22    commit 734713bc047d87bf7eac9674765ae793478c50d3 
23    Author: Scott Chacon <schacon@gmail.com> 
24    Date:   Fri Jan 2 18:32:33 2009 -0800 
25  
26        fixed refs handling, added gc auto, updated tests 
27  
28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
29    Merge: 1c002dd... 35cfb2b... 
30    Author: Scott Chacon <schacon@gmail.com> 
31    Date:   Thu Dec 11 15:08:43 2008 -0800 
32  
33        Merge commit 'phedders/rdocs' 
34  
35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
36    Author: Scott Chacon <schacon@gmail.com> 
37    Date:   Thu Dec 11 14:58:32 2008 -0800 
38  
39        added some blame and merge stuff 
40  
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): 
42  
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
44    $ git show 1c002dd4b536e7479f 
45    $ git show 1c002d 
46  
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: 
48  
49    $ git log --abbrev-commit --pretty=oneline 
50    ca82a6d changed the version number 
51    085bb3b removed unnecessary test code 
52    a11bef0 first commit 
53  
54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 
55  
56### A SHORT NOTE ABOUT SHA-1 ### 
57  
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? 
59  
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. 
61  
62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. 
63  
64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. 
65  
66### Branch References ### 
67  
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: 
69  
70    $ git show ca82a6dff817ec66f44342007202690a93763949 
71    $ git show topic1 
72  
73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. 
74  
75    $ git rev-parse topic1 
76    ca82a6dff817ec66f44342007202690a93763949 
77  
78### RefLog Shortnames ### 
79  
80One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. 
81  
82You can see your reflog by using `git reflog`: 
83  
84    $ git reflog 
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated 
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff 
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 
89    95df984 HEAD@{4}: commit: # This is a combination of two commits. 
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD 
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD 
92  
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: 
94  
95    $ git show HEAD@{5} 
96  
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type 
98  
99    $ git show master@{yesterday} 
100  
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. 
102  
103To see reflog information formatted like the `git log` output, you can run `git log -g`: 
104  
105    $ git log -g master 
106    commit 734713bc047d87bf7eac9674765ae793478c50d3 
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) 
108    Reflog message: commit: fixed refs handling, added gc auto, updated 
109    Author: Scott Chacon <schacon@gmail.com> 
110    Date:   Fri Jan 2 18:32:33 2009 -0800 
111  
112        fixed refs handling, added gc auto, updated tests 
113  
114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>) 
116    Reflog message: merge phedders/rdocs: Merge made by recursive. 
117    Author: Scott Chacon <schacon@gmail.com> 
118    Date:   Thu Dec 11 15:08:43 2008 -0800 
119  
120        Merge commit 'phedders/rdocs' 
121  
122It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. 
123  
124### Ancestry References ### 
125  
126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 
127Suppose you look at the history of your project: 
128  
129    $ git log --pretty=format:'%h %s' --graph 
130    * 734713b fixed refs handling, added gc auto, updated tests 
131    *   d921970 Merge commit 'phedders/rdocs' 
132    |\ 
133    | * 35cfb2b Some rdoc changes 
134    * | 1c002dd added some blame and merge stuff 
135    |/ 
136    * 1c36188 ignore *.gem 
137    * 9b29157 add open3_detach to gemspec file list 
138  
139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": 
140  
141    $ git show HEAD^ 
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
143    Merge: 1c002dd... 35cfb2b... 
144    Author: Scott Chacon <schacon@gmail.com> 
145    Date:   Thu Dec 11 15:08:43 2008 -0800 
146  
147        Merge commit 'phedders/rdocs' 
148  
149You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: 
150  
151    $ git show d921970^ 
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
153    Author: Scott Chacon <schacon@gmail.com> 
154    Date:   Thu Dec 11 14:58:32 2008 -0800 
155  
156        added some blame and merge stuff 
157  
158    $ git show d921970^2 
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 
160    Author: Paul Hedderly <paul+git@mjr.org> 
161    Date:   Wed Dec 10 22:22:03 2008 +0000 
162  
163        Some rdoc changes 
164  
165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be 
166  
167    $ git show HEAD~3 
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
169    Author: Tom Preston-Werner <tom@mojombo.com> 
170    Date:   Fri Nov 7 13:47:59 2008 -0500 
171  
172        ignore *.gem 
173  
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: 
175  
176    $ git show HEAD^^^ 
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
178    Author: Tom Preston-Werner <tom@mojombo.com> 
179    Date:   Fri Nov 7 13:47:59 2008 -0500 
180  
181        ignore *.gem 
182  
183You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. 
184  
185### Commit Ranges ### 
186  
187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 
188  
189#### Double Dot #### 
190  
191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. 
192  
193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
195  
196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: 
197  
198    $ git log master..experiment 
199    D 
200    C 
201  
202If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: 
203  
204    $ git log experiment..master 
205    F 
206    E 
207  
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: 
209  
210    $ git log origin/master..HEAD 
211  
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. 
213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. 
214  
215#### Multiple Points #### 
216  
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: 
218  
219    $ git log refA..refB 
220    $ git log ^refA refB 
221    $ git log refB --not refA 
222  
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: 
224  
225    $ git log refA refB ^refC 
226    $ git log refA refB --not refC 
227  
228This makes for a very powerful revision query system that should help you figure out what is in your branches. 
229  
230#### Triple Dot #### 
231  
232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. 
233If you want to see what is in `master` or `experiment` but not any common references, you can run 
234  
235    $ git log master...experiment 
236    F 
237    E 
238    D 
239    C 
240  
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. 
242  
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: 
244  
245    $ git log --left-right master...experiment 
246    < F 
247    < E 
248    > D 
249    > C 
250  
251With these tools, you can much more easily let Git know what commit or commits you want to inspect. 
252  
253## Interactive Staging ## 
254  
255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257  
258    $ git add -i 
259               staged     unstaged path 
260      1:    unchanged        +0/-1 TODO 
261      2:    unchanged        +1/-1 index.html 
262      3:    unchanged        +5/-1 lib/simplegit.rb 
263  
264    *** Commands *** 
265      1: status     2: update      3: revert     4: add untracked 
266      5: patch      6: diff        7: quit       8: help 
267    What now> 
268  
269You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. 
270  
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. 
272  
273### Staging and Unstaging Files ### 
274  
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: 
276  
277    What now> 2 
278               staged     unstaged path 
279      1:    unchanged        +0/-1 TODO 
280      2:    unchanged        +1/-1 index.html 
281      3:    unchanged        +5/-1 lib/simplegit.rb 
282    Update>> 
283  
284To stage the TODO and index.html files, you can type the numbers: 
285  
286    Update>> 1,2 
287               staged     unstaged path 
288    * 1:    unchanged        +0/-1 TODO 
289    * 2:    unchanged        +1/-1 index.html 
290      3:    unchanged        +5/-1 lib/simplegit.rb 
291    Update>> 
292  
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: 
294  
295    Update>> 
296    updated 2 paths 
297  
298    *** Commands *** 
299      1: status     2: update      3: revert     4: add untracked 
300      5: patch      6: diff        7: quit       8: help 
301    What now> 1 
302               staged     unstaged path 
303      1:        +0/-1      nothing TODO 
304      2:        +1/-1      nothing index.html 
305      3:    unchanged        +5/-1 lib/simplegit.rb 
306  
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: 
308  
309    *** Commands *** 
310      1: status     2: update      3: revert     4: add untracked 
311      5: patch      6: diff        7: quit       8: help 
312    What now> 3 
313               staged     unstaged path 
314      1:        +0/-1      nothing TODO 
315      2:        +1/-1      nothing index.html 
316      3:    unchanged        +5/-1 lib/simplegit.rb 
317    Revert>> 1 
318               staged     unstaged path 
319    * 1:        +0/-1      nothing TODO 
320      2:        +1/-1      nothing index.html 
321      3:    unchanged        +5/-1 lib/simplegit.rb 
322    Revert>> [enter] 
323    reverted one path 
324  
325Looking at your Git status again, you can see that you’ve unstaged the TODO file: 
326  
327    *** Commands *** 
328      1: status     2: update      3: revert     4: add untracked 
329      5: patch      6: diff        7: quit       8: help 
330    What now> 1 
331               staged     unstaged path 
332      1:    unchanged        +0/-1 TODO 
333      2:        +1/-1      nothing index.html 
334      3:    unchanged        +5/-1 lib/simplegit.rb 
335  
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: 
337  
338    *** Commands *** 
339      1: status     2: update      3: revert     4: add untracked 
340      5: patch      6: diff        7: quit       8: help 
341    What now> 6 
342               staged     unstaged path 
343      1:        +1/-1      nothing index.html 
344    Review diff>> 1 
345    diff --git a/index.html b/index.html 
346    index 4d07108..4335f49 100644 
347    --- a/index.html 
348    +++ b/index.html 
349    @@ -16,7 +16,7 @@ Date Finder 
350  
351     <p id="out">...</p> 
352  
353    -<div id="footer">contact : support@github.com</div> 
354    +<div id="footer">contact : email.support@github.com</div> 
355  
356     <script type="text/javascript"> 
357  
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily. 
359  
360### Staging Patches ### 
361  
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: 
363  
364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
365    index dd5ecc4..57399e0 100644 
366    --- a/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 
368    @@ -22,7 +22,7 @@ class SimpleGit 
369       end 
370  
371       def log(treeish = 'master') 
372    -    command("git log -n 25 #{treeish}") 
373    +    command("git log -n 30 #{treeish}") 
374       end 
375  
376       def blame(path) 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 
378  
379You have a lot of options at this point. Typing `?` shows a list of what you can do: 
380  
381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
382    y - stage this hunk 
383    n - do not stage this hunk 
384    a - stage this and all the remaining hunks in the file 
385    d - do not stage this hunk nor any of the remaining hunks in the file 
386    g - select a hunk to go to 
387    / - search for a hunk matching the given regex 
388    j - leave this hunk undecided, see next undecided hunk 
389    J - leave this hunk undecided, see next hunk 
390    k - leave this hunk undecided, see previous undecided hunk 
391    K - leave this hunk undecided, see previous hunk 
392    s - split the current hunk into smaller hunks 
393    e - manually edit the current hunk 
394    ? - print help 
395  
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: 
397  
398    What now> 1 
399               staged     unstaged path 
400      1:    unchanged        +0/-1 TODO 
401      2:        +1/-1      nothing index.html 
402      3:        +1/-1        +4/-0 lib/simplegit.rb 
403  
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. 
405  
406Finally, you don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using `git add -p` or `git add --patch` on the command line. 
407  
408## Stashing ## 2=== Stashing and Cleaning 
409 3 
410Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command.4Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command.
411 5 
.412Stashing takes the dirty state of your working directory that is, your modified tracked files and staged changes and saves it on a stack of unfinished changes that you can reapply at any time.6Stashing takes the dirty state of your working directory that is, your modified tracked files and staged changes and saves it on a stack of unfinished changes that you can reapply at any time.
413 7 
.414### Stashing Your Work ### 8==== Stashing Your Work 
415 9 
416To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state:10To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state:
417 11 
. 12[source,console]
 13----
418    $ git status14$ git status
419    # On branch master 
420    # Changes to be committed:15Changes to be committed:
421    #   (use "git reset HEAD <file>..." to unstage)16  (use "git reset HEAD <file>..." to unstage)
422    # 17 
423    #      modified:   index.html18    modified:   index.html
424    # 19 
425    # Changes not staged for commit:20Changes not staged for commit:
426    #   (use "git add <file>..." to update what will be committed)21  (use "git add <file>..." to update what will be committed)
427    # 22  (use "git checkout -- <file>..." to discard changes in working directory) 
 23 
428    #      modified:   lib/simplegit.rb24    modified:   lib/simplegit.rb
429    # 25---- 
430 26 
.431Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`:27Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash` or `git stash save`:
432 28 
. 29[source,console]
 30----
433    $ git stash31$ git stash
434    Saved working directory and index state \32Saved working directory and index state \
435      "WIP on master: 049d078 added the index file"33  "WIP on master: 049d078 added the index file"
436    HEAD is now at 049d078 added the index file34HEAD is now at 049d078 added the index file
437    (To restore them type "git stash apply")35(To restore them type "git stash apply")
 36----
438 37 
439Your working directory is clean:38Your working directory is clean:
440 39 
. 40[source,console]
 41----
441    $ git status42$ git status
442    # On branch master43# On branch master
443    nothing to commit, working directory clean44nothing to commit, working directory clean
 45----
444 46 
445At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`:47At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`:
446 48 
. 49[source,console]
 50----
447    $ git stash list51$ git stash list
448    stash@{0}: WIP on master: 049d078 added the index file52stash@{0}: WIP on master: 049d078 added the index file
449    stash@{1}: WIP on master: c264051 Revert "added file_size"53stash@{1}: WIP on master: c264051 Revert "added file_size"
450    stash@{2}: WIP on master: 21d80a5 added number to log54stash@{2}: WIP on master: 21d80a5 added number to log
 55----
451 56 
452In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it:57In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it:
453 58 
. 59[source,console]
 60----
454    $ git stash apply61$ git stash apply
455    # On branch master62# On branch master
456    # Changes not staged for commit:63# Changed but not updated:
457    #   (use "git add <file>..." to update what will be committed)64#   (use "git add <file>..." to update what will be committed)
458    #65#
459    #      modified:   index.html66#      modified:   index.html
460    #      modified:   lib/simplegit.rb67#      modified:   lib/simplegit.rb
461    #68#
 69----
462 70 
.463You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash Git gives you merge conflicts if anything no longer applies cleanly.71You can see that Git re-modifies the files you reverted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash Git gives you merge conflicts if anything no longer applies cleanly.
464 72 
465The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position:73The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position:
466 74 
. 75[source,console]
 76----
467    $ git stash apply --index77$ git stash apply --index
468    # On branch master78# On branch master
469    # Changes to be committed:79# Changes to be committed:
470    #   (use "git reset HEAD <file>..." to unstage)80#   (use "git reset HEAD <file>..." to unstage)
471    #81#
472    #      modified:   index.html82#      modified:   index.html
473    #83#
474    # Changes not staged for commit:84# Changed but not updated:
475    #   (use "git add <file>..." to update what will be committed)85#   (use "git add <file>..." to update what will be committed)
476    #86#
477    #      modified:   lib/simplegit.rb87#      modified:   lib/simplegit.rb
478    #88#
 89----
479 90 
.480The apply option only tries to apply the stashed work you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove:91The apply option only tries to apply the stashed work you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove:
481 92 
. 93[source,console]
 94----
482    $ git stash list95$ git stash list
483    stash@{0}: WIP on master: 049d078 added the index file96stash@{0}: WIP on master: 049d078 added the index file
484    stash@{1}: WIP on master: c264051 Revert "added file_size"97stash@{1}: WIP on master: c264051 Revert "added file_size"
485    stash@{2}: WIP on master: 21d80a5 added number to log98stash@{2}: WIP on master: 21d80a5 added number to log
486    $ git stash drop stash@{0}99$ git stash drop stash@{0}
487    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)100Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
 101----
488 102 
489You can also run `git stash pop` to apply the stash and then immediately drop it from your stack.103You can also run `git stash pop` to apply the stash and then immediately drop it from your stack.
.490  
491### Un-applying a Stash ### 
492  
493In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
494  
495    $ git stash show -p stash@{0} | git apply -R 
496  
497Again, if you don’t specify a stash, Git assumes the most recent stash: 
498  
499    $ git stash show -p | git apply -R 
500  
501You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
502  
503    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
504    $ git stash apply 
505    $ #... work work work 
506    $ git stash-unapply 
507 104 
. 105==== Creative Stashing
 106 
 107There are a few stash variants that may also be helpful. The first option that is quite popular is the `--keep-index` option to the `stash save` command. This tells Git to not stash anything that you've already staged with the `git add` command.
 108 
 109This can be really helpful if you've made a number of changes but want to only commit some of them and then come back to the rest of the changes at a later time.
 110 
 111[source,console]
 112----
 113$ git status -s
 114M  index.html
 115 M lib/simplegit.rb
 116 
 117$ git stash --keep-index
 118Saved working directory and index state WIP on master: 1b65b17 added the index file
 119HEAD is now at 1b65b17 added the index file
 120 
 121$ git status -s
 122M  index.html
 123----
 124 
 125Another common thing you may want to do with stash is to stash the untracked files as well as the tracked ones. By default, `git stash` will only store files that are already in the index. If you specify `--include-untracked` or `-u`, Git will also stash any untracked files you have created.
 126 
 127[source,console]
 128----
 129$ git status -s
 130M  index.html
 131 M lib/simplegit.rb
 132?? new-file.txt
 133 
 134$ git stash -u
 135Saved working directory and index state WIP on master: 1b65b17 added the index file
 136HEAD is now at 1b65b17 added the index file
 137 
 138$ git status -s
 139$
 140----
 141 
 142Finally, if you specify the `--patch` flag, Git will not stash everything that is modified but will instead prompt you interactively which of the changes you would like to stash and which you would like to keep in your working directly.
 143 
 144[source,console]
 145----
 146$ git stash --patch
 147diff --git a/lib/simplegit.rb b/lib/simplegit.rb
 148index 66d332e..8bb5674 100644
 149--- a/lib/simplegit.rb
 150+++ b/lib/simplegit.rb
 151@@ -16,6 +16,10 @@ class SimpleGit
 152         return `#{git_cmd} 2>&1`.chomp
 153       end
 154     end
 155+
 156+    def show(treeish = 'master')
 157+      command("git show #{treeish}")
 158+    end
 159 
 160 end
 161 test
 162Stash this hunk [y,n,q,a,d,/,e,?]? y
 163 
 164Saved working directory and index state WIP on master: 1b65b17 added the index file
 165----
 166 
 167 
508### Creating a Branch from a Stash ### 168==== Creating a Branch from a Stash 
509 169 
510If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully:170If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully:
511 171 
. 172[source,console]
 173----
512    $ git stash branch testchanges174$ git stash branch testchanges
513    Switched to a new branch "testchanges"175Switched to a new branch "testchanges"
514    # On branch testchanges176# On branch testchanges
515    # Changes to be committed:177# Changes to be committed:
516    #   (use "git reset HEAD <file>..." to unstage)178#   (use "git reset HEAD <file>..." to unstage)
517    #179#
518    #      modified:   index.html180#      modified:   index.html
519    #181#
520    # Changes not staged for commit:182# Changed but not updated:
521    #   (use "git add <file>..." to update what will be committed)183#   (use "git add <file>..." to update what will be committed)
522    #184#
523    #      modified:   lib/simplegit.rb185#      modified:   lib/simplegit.rb
524    #186#
525    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)187Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359)
 188----
526 189 
527This is a nice shortcut to recover stashed work easily and work on it in a new branch.190This is a nice shortcut to recover stashed work easily and work on it in a new branch.
. 191 
 192[[_git_clean]]
 193==== Cleaning your Working Directory
 194 
 195Finally, you may not want to stash some work or files in your working directory, but simply get rid of them. The `git clean` command will do this for you.
 196 
 197Some common reasons for this might be to remove cruft that has been generated by merges or external tools or to remove build artifacts in order to run a clean build.
 198 
 199You'll want to be pretty careful with this command, since it's designed to remove files from your working directory that are not tracked. If you change your mind, there is often no retrieving the content of those files. A safer option is to run `git stash --all` to remove everything but save it in a stash.
 200 
 201Assuming you do want to remove cruft files or clean your working directory, you can do so with `git clean`. To remove all the untracked files in your working directory, you can run `git clean -f -d`, which removes any files and also any subdirectories that become empty as a result. The `-f` means 'force' or "really do this".
 202 
 203If you ever want to see what it would do, you can run the command with the `-n` option, which means ``do a dry run and tell me what you _would_ have removed''.
 204 
 205[source,console]
 206----
 207$ git clean -d -n
 208Would remove test.o
 209Would remove tmp/
 210----
 211 
 212By default, the `git clean` command will only remove untracked files that are not ignored.  Any file that matches a pattern in your `.gitignore` or other ignore files will not be removed. If you want to remove those files too, such as to remove all `.o` files generated from a build so you can do a fully clean build, you can add a `-x` to the clean command.
 213 
 214[source,console]
 215----
 216$ git status -s
 217 M lib/simplegit.rb
 218?? build.TMP
 219?? tmp/
 220 
 221$ git clean -n -d
 222Would remove build.TMP
 223Would remove tmp/
 224 
 225$ git clean -n -d -x
 226Would remove build.TMP
 227Would remove test.o
 228Would remove tmp/
 229----
 230 
 231If you don't know what the `git clean` command is going to do, always run it with a `-n` first to double check before changing the `-n` to a `-f` and doing it for real. The other way you can be careful about the process is to run it with the `-i` or ``interactive'' flag.
 232 
 233This will run the clean command in an interactive mode.
 234 
 235[source,console]
 236----
 237$ git clean -x -i
 238Would remove the following items:
 239  build.TMP  test.o
 240*** Commands ***
 241    1: clean                2: filter by pattern    3: select by numbers    4: ask each             5: quit
 242    6: help
 243What now>
 244----
528 245 
.529## Rewriting History ## 246This way you can step through each file individually or specify patterns for deletion interactively. 
530  
531Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others. 
532  
533In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. 
534  
535### Changing the Last Commit ### 
536  
537Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 
538  
539If you only want to modify your last commit message, it’s very simple: 
540  
541    $ git commit --amend 
542  
543That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. 
544  
545If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. 
546  
547You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it. 
548  
549### Changing Multiple Commit Messages ### 
550  
551To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. 
552  
553For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: 
554  
555    $ git rebase -i HEAD~3 
556  
557Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change. 
558  
559Running this command gives you a list of commits in your text editor that looks something like this: 
560  
561    pick f7f3f6d changed my name a bit 
562    pick 310154e updated README formatting and added blame 
563    pick a5f4a0d added cat-file 
564  
565    # Rebase 710f0f8..a5f4a0d onto 710f0f8 
566    # 
567    # Commands: 
568    #  p, pick = use commit 
569    #  r, reword = use commit, but edit the commit message 
570    #  e, edit = use commit, but stop for amending 
571    #  s, squash = use commit, but meld into previous commit 
572    #  f, fixup = like "squash", but discard this commit's log message 
573    #  x, exec = run command (the rest of the line) using shell 
574    # 
575    # These lines can be re-ordered; they are executed from top to bottom. 
576    # 
577    # If you remove a line here THAT COMMIT WILL BE LOST. 
578    # 
579    # However, if you remove everything, the rebase will be aborted. 
580    # 
581    # Note that empty commits are commented out 
582  
583It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this: 
584  
585    $ git log --pretty=format:"%h %s" HEAD~3..HEAD 
586    a5f4a0d added cat-file 
587    310154e updated README formatting and added blame 
588    f7f3f6d changed my name a bit 
589  
590Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay. 
591  
592You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this: 
593  
594    edit f7f3f6d changed my name a bit 
595    pick 310154e updated README formatting and added blame 
596    pick a5f4a0d added cat-file 
597  
598When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message: 
599  
600<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  
601nor is the commit message. Please review  
602--> 
603  
604    $ git rebase -i HEAD~3 
605    Stopped at 7482e0d... updated the gemspec to hopefully work better 
606    You can amend the commit now, with 
607  
608           git commit --amend 
609  
610    Once you’re satisfied with your changes, run 
611  
612           git rebase --continue 
613  
614These instructions tell you exactly what to do. Type 
615  
616    $ git commit --amend 
617  
618Change the commit message, and exit the editor. Then, run 
619  
620    $ git rebase --continue 
621  
622This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished. 
623  
624### Reordering Commits ### 
625  
626You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this 
627  
628    pick f7f3f6d changed my name a bit 
629    pick 310154e updated README formatting and added blame 
630    pick a5f4a0d added cat-file 
631  
632to this: 
633  
634    pick 310154e updated README formatting and added blame 
635    pick f7f3f6d changed my name a bit 
636  
637When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely. 
638  
639### Squashing Commits ### 
640  
641It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message: 
642  
643    # 
644    # Commands: 
645    #  p, pick = use commit 
646    #  r, reword = use commit, but edit the commit message 
647    #  e, edit = use commit, but stop for amending 
648    #  s, squash = use commit, but meld into previous commit 
649    #  f, fixup = like "squash", but discard this commit's log message 
650    #  x, exec = run command (the rest of the line) using shell 
651    # 
652    # These lines can be re-ordered; they are executed from top to bottom. 
653    # 
654    # If you remove a line here THAT COMMIT WILL BE LOST. 
655    # 
656    # However, if you remove everything, the rebase will be aborted. 
657    # 
658    # Note that empty commits are commented out 
659  
660If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this: 
661  
662    pick f7f3f6d changed my name a bit 
663    squash 310154e updated README formatting and added blame 
664    squash a5f4a0d added cat-file 
665  
666When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages: 
667  
668    # This is a combination of 3 commits. 
669    # The first commit's message is: 
670    changed my name a bit 
671  
672    # This is the 2nd commit message: 
673  
674    updated README formatting and added blame 
675  
676    # This is the 3rd commit message: 
677  
678    added cat-file 
679  
680When you save that, you have a single commit that introduces the changes of all three previous commits. 
681  
682### Splitting a Commit ### 
683  
684Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit": 
685  
686    pick f7f3f6d changed my name a bit 
687    edit 310154e updated README formatting and added blame 
688    pick a5f4a0d added cat-file 
689  
690When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done: 
691  
692    $ git reset HEAD^ 
693    $ git add README 
694    $ git commit -m 'updated README formatting' 
695    $ git add lib/simplegit.rb 
696    $ git commit -m 'added blame' 
697    $ git rebase --continue 
698  
699Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this: 
700  
701    $ git log -4 --pretty=format:"%h %s" 
702    1c002dd added cat-file 
703    9b29157 added blame 
704    35cfb2b updated README formatting 
705    f3cc40e changed my name a bit 
706  
707Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository. 
708  
709### The Nuclear Option: filter-branch ### 
710  
711There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of. 
712  
713#### Removing a File from Every Commit #### 
714  
715This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`: 
716  
717    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 
718    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) 
719    Ref 'refs/heads/master' was rewritten 
720  
721The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`. 
722  
723You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. 
724  
725#### Making a Subdirectory the New Root #### 
726  
727Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too: 
728  
729    $ git filter-branch --subdirectory-filter trunk HEAD 
730    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) 
731    Ref 'refs/heads/master' was rewritten 
732  
733Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory. 
734  
735#### Changing E-Mail Addresses Globally #### 
736  
737Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`: 
738  
739    $ git filter-branch --commit-filter ' 
740            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; 
741            then 
742                    GIT_AUTHOR_NAME="Scott Chacon"; 
743                    GIT_AUTHOR_EMAIL="schacon@example.com"; 
744                    git commit-tree "$@"; 
745            else 
746                    git commit-tree "$@"; 
747            fi' HEAD 
748  
749This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address. 
750  
751### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
752  
753[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
754  
755See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
756  
757## Debugging with Git ## 
758  
759Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. 
760  
761### File Annotation ### 
762  
763If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: 
764  
765    $ git blame -L 12,22 simplegit.rb 
766    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master') 
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}") 
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end 
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15) 
770    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master') 
771    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}") 
772    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end 
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19) 
774    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path) 
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}") 
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end 
777  
778Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here. 
779  
780Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from: 
781  
782    $ git blame -C -L 141,153 GITPackUpload.m 
783    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
786    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
787    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
793    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 
796  
797This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. 
798  
799### Binary Search ### 
800  
801Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. 
802  
803Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: 
804  
805    $ git bisect start 
806    $ git bisect bad 
807    $ git bisect good v1.0 
808    Bisecting: 6 revisions left to test after this 
809    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo 
810  
811Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: 
812  
813    $ git bisect good 
814    Bisecting: 3 revisions left to test after this 
815    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing 
816  
817Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: 
818  
819    $ git bisect bad 
820    Bisecting: 1 revisions left to test after this 
821    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table 
822  
823This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: 
824  
825    $ git bisect good 
826    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit 
827    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 
828    Author: PJ Hyett <pjhyett@example.com> 
829    Date:   Tue Jan 27 14:48:32 2009 -0800 
830  
831        secure this thing 
832  
833    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 
834    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config 
835  
836When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: 
837  
838    $ git bisect reset 
839  
840This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: 
841  
842    $ git bisect start HEAD v1.0 
843    $ git bisect run test-error.sh 
844  
845Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. 
846  
847## Submodules ## 
848  
849It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. 
850  
851Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available. 
852  
853Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate. 
854  
855### Starting with Submodules ### 
856  
857Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
858  
859    $ git submodule add git://github.com/chneukirchen/rack.git rack 
860    Initialized empty Git repository in /opt/subtest/rack/.git/ 
861    remote: Counting objects: 3181, done. 
862    remote: Compressing objects: 100% (1534/1534), done. 
863    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
864    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. 
865    Resolving deltas: 100% (1951/1951), done. 
866  
867Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
868  
869    $ git status 
870    # On branch master 
871    # Changes to be committed: 
872    #   (use "git reset HEAD <file>..." to unstage) 
873    # 
874    #      new file:   .gitmodules 
875    #      new file:   rack 
876    # 
877  
878First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into: 
879  
880    $ cat .gitmodules 
881    [submodule "rack"] 
882          path = rack 
883          url = git://github.com/chneukirchen/rack.git 
884  
885If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. 
886  
887The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting: 
888  
889    $ git diff --cached rack 
890    diff --git a/rack b/rack 
891    new file mode 160000 
892    index 0000000..08d709f 
893    --- /dev/null 
894    +++ b/rack 
895    @@ -0,0 +1 @@ 
896    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
897  
898Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 
899  
900This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
901  
902When you commit, you see something like this: 
903  
904    $ git commit -m 'first commit with submodule rack' 
905    [master 0550271] first commit with submodule rack 
906     2 files changed, 4 insertions(+), 0 deletions(-) 
907     create mode 100644 .gitmodules 
908     create mode 160000 rack 
909  
910Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file. 
911  
912You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
913  
914    $ git log -1 
915    commit 0550271328a0038865aad6331e620cd7238601bb 
916    Author: Scott Chacon <schacon@gmail.com> 
917    Date:   Thu Apr 9 09:03:56 2009 -0700 
918  
919        first commit with submodule rack 
920    $ cd rack/ 
921    $ git log -1 
922    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
923    Author: Christian Neukirchen <chneukirchen@gmail.com> 
924    Date:   Wed Mar 25 14:49:04 2009 +0100 
925  
926        Document version change 
927  
928### Cloning a Project with Submodules ### 
929  
930Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet: 
931  
932    $ git clone git://github.com/schacon/myproject.git 
933    Initialized empty Git repository in /opt/myproject/.git/ 
934    remote: Counting objects: 6, done. 
935    remote: Compressing objects: 100% (4/4), done. 
936    remote: Total 6 (delta 0), reused 0 (delta 0) 
937    Receiving objects: 100% (6/6), done. 
938    $ cd myproject 
939    $ ls -l 
940    total 8 
941    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 
942    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 
943    $ ls rack/ 
944    $ 
945  
946The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject: 
947  
948    $ git submodule init 
949    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' 
950    $ git submodule update 
951    Initialized empty Git repository in /opt/myproject/rack/.git/ 
952    remote: Counting objects: 3181, done. 
953    remote: Compressing objects: 100% (1534/1534), done. 
954    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
955    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. 
956    Resolving deltas: 100% (1951/1951), done. 
957    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' 
958  
959Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 
960  
961    $ git merge origin/master 
962    Updating 0550271..85a3eee 
963    Fast forward 
964     rack |    2 +- 
965     1 files changed, 1 insertions(+), 1 deletions(-) 
966    [master*]$ git status 
967    # On branch master 
968    # Changes not staged for commit: 
969    #   (use "git add <file>..." to update what will be committed) 
970    #   (use "git checkout -- <file>..." to discard changes in working directory) 
971    # 
972    #      modified:   rack 
973    # 
974  
975You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
976  
977    $ git diff 
978    diff --git a/rack b/rack 
979    index 6c5e70b..08d709f 160000 
980    --- a/rack 
981    +++ b/rack 
982    @@ -1 +1 @@ 
983    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
984    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
985  
986This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
987  
988    $ git submodule update 
989    remote: Counting objects: 5, done. 
990    remote: Compressing objects: 100% (3/3), done. 
991    remote: Total 3 (delta 1), reused 2 (delta 0) 
992    Unpacking objects: 100% (3/3), done. 
993    From git@github.com:schacon/rack 
994       08d709f..6c5e70b  master     -> origin/master 
995    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
996  
997You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
998  
999One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1000  
1001    $ git submodule update 
1002    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1003    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1004  
1005You have to see who last changed the submodule: 
1006  
1007    $ git log -1 rack 
1008    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1009    Author: Scott Chacon <schacon@gmail.com> 
1010    Date:   Thu Apr 9 09:19:14 2009 -0700 
1011  
1012        added a submodule reference I will never make public. hahahahaha! 
1013  
1014Then, you e-mail that guy and yell at him. 
1015  
1016### Superprojects ### 
1017  
1018Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1019  
1020A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1021  
1022### Issues with Submodules ### 
1023  
1024Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 
1025  
1026To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1027  
1028Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory: 
1029  
1030    $ git checkout -b rack 
1031    Switched to a new branch "rack" 
1032    $ git submodule add git@github.com:schacon/rack.git rack 
1033    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1034    ... 
1035    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1036    Resolving deltas: 100% (1952/1952), done. 
1037    $ git commit -am 'added rack submodule' 
1038    [rack cc49a69] added rack submodule 
1039     2 files changed, 4 insertions(+), 0 deletions(-) 
1040     create mode 100644 .gitmodules 
1041     create mode 160000 rack 
1042    $ git checkout master 
1043    Switched to branch "master" 
1044    $ git status 
1045    # On branch master 
1046    # Untracked files: 
1047    #   (use "git add <file>..." to include in what will be committed) 
1048    # 
1049    #      rack/ 
1050  
1051You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 
1052  
1053The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you: 
1054  
1055    $ rm -Rf rack/ 
1056    $ git submodule add git@github.com:schacon/rack.git rack 
1057    'rack' already exists in the index 
1058  
1059You have to unstage the `rack` directory first. Then you can add the submodule: 
1060  
1061    $ git rm -r rack 
1062    $ git submodule add git@github.com:schacon/rack.git rack 
1063    Initialized empty Git repository in /opt/testsub/rack/.git/ 
1064    remote: Counting objects: 3184, done. 
1065    remote: Compressing objects: 100% (1465/1465), done. 
1066    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1067    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. 
1068    Resolving deltas: 100% (1952/1952), done. 
1069  
1070Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule — you get this error: 
1071  
1072    $ git checkout master 
1073    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 
1074  
1075You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1076  
1077    $ mv rack /tmp/ 
1078    $ git checkout master 
1079    Switched to branch "master" 
1080    $ ls 
1081    README  rack 
1082  
1083Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory. 
1084  
1085## Subtree Merging ## 
1086  
1087Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1088  
1089However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1090  
1091The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing. 
1092  
1093You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch: 
1094  
1095    $ git remote add rack_remote git@github.com:schacon/rack.git 
1096    $ git fetch rack_remote 
1097    warning: no common commits 
1098    remote: Counting objects: 3184, done. 
1099    remote: Compressing objects: 100% (1465/1465), done. 
1100    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1101    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. 
1102    Resolving deltas: 100% (1952/1952), done. 
1103    From git@github.com:schacon/rack 
1104     * [new branch]      build      -> rack_remote/build 
1105     * [new branch]      master     -> rack_remote/master 
1106     * [new branch]      rack-0.4   -> rack_remote/rack-0.4 
1107     * [new branch]      rack-0.9   -> rack_remote/rack-0.9 
1108    $ git checkout -b rack_branch rack_remote/master 
1109    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. 
1110    Switched to a new branch "rack_branch" 
1111  
1112Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots: 
1113  
1114    $ ls 
1115    AUTHORS        KNOWN-ISSUES   Rakefile      contrib        lib 
1116    COPYING        README         bin           example        test 
1117    $ git checkout master 
1118    Switched to branch "master" 
1119    $ ls 
1120    README 
1121  
1122You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: 
1123  
1124    $ git read-tree --prefix=rack/ -u rack_branch 
1125  
1126When you commit, it looks like you have all the Rack files under that subdirectory — as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling: 
1127  
1128    $ git checkout rack_branch 
1129    $ git pull 
1130  
1131Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option: 
1132  
1133    $ git checkout master 
1134    $ git merge --squash -s subtree --no-commit rack_branch 
1135    Squash commit -- not updating HEAD 
1136    Automatic merge went well; stopped before committing as requested 
1137  
1138All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite — make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream. 
1139  
1140To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch — to see if you need to merge them — you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to: 
1141  
1142    $ git diff-tree -p rack_branch 
1143  
1144Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run 
1145  
1146    $ git diff-tree -p rack_remote/master 
1147  
1148## Summary ## 
1149  
1150You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. 
1151 247 
+
+ diff --git a/book/07-git-tools/sections/diff-submodules.htm b/book/07-git-tools/sections/diff-submodules.htm new file mode 100644 index 00000000..f2581710 --- /dev/null +++ b/book/07-git-tools/sections/diff-submodules.htm @@ -0,0 +1,7427 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\submodules.asc
.1# Git Tools # 1[[_git_submodules]] 
2  
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. 
4  
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. 
6  
7## Revision Selection ## 
8  
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. 
10  
11### Single Revisions ### 
12  
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. 
14  
15### Short SHA ### 
16  
17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. 
18  
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: 
20  
21    $ git log 
22    commit 734713bc047d87bf7eac9674765ae793478c50d3 
23    Author: Scott Chacon <schacon@gmail.com> 
24    Date:   Fri Jan 2 18:32:33 2009 -0800 
25  
26        fixed refs handling, added gc auto, updated tests 
27  
28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
29    Merge: 1c002dd... 35cfb2b... 
30    Author: Scott Chacon <schacon@gmail.com> 
31    Date:   Thu Dec 11 15:08:43 2008 -0800 
32  
33        Merge commit 'phedders/rdocs' 
34  
35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
36    Author: Scott Chacon <schacon@gmail.com> 
37    Date:   Thu Dec 11 14:58:32 2008 -0800 
38  
39        added some blame and merge stuff 
40  
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): 
42  
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
44    $ git show 1c002dd4b536e7479f 
45    $ git show 1c002d 
46  
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: 
48  
49    $ git log --abbrev-commit --pretty=oneline 
50    ca82a6d changed the version number 
51    085bb3b removed unnecessary test code 
52    a11bef0 first commit 
53  
54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 
55  
56### A SHORT NOTE ABOUT SHA-1 ### 
57  
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? 
59  
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. 
61  
62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. 
63  
64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. 
65  
66### Branch References ### 
67  
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: 
69  
70    $ git show ca82a6dff817ec66f44342007202690a93763949 
71    $ git show topic1 
72  
73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. 
74  
75    $ git rev-parse topic1 
76    ca82a6dff817ec66f44342007202690a93763949 
77  
78### RefLog Shortnames ### 
79  
80One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. 
81  
82You can see your reflog by using `git reflog`: 
83  
84    $ git reflog 
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated 
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff 
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 
89    95df984 HEAD@{4}: commit: # This is a combination of two commits. 
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD 
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD 
92  
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: 
94  
95    $ git show HEAD@{5} 
96  
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type 
98  
99    $ git show master@{yesterday} 
100  
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. 
102  
103To see reflog information formatted like the `git log` output, you can run `git log -g`: 
104  
105    $ git log -g master 
106    commit 734713bc047d87bf7eac9674765ae793478c50d3 
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) 
108    Reflog message: commit: fixed refs handling, added gc auto, updated 
109    Author: Scott Chacon <schacon@gmail.com> 
110    Date:   Fri Jan 2 18:32:33 2009 -0800 
111  
112        fixed refs handling, added gc auto, updated tests 
113  
114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>) 
116    Reflog message: merge phedders/rdocs: Merge made by recursive. 
117    Author: Scott Chacon <schacon@gmail.com> 
118    Date:   Thu Dec 11 15:08:43 2008 -0800 
119  
120        Merge commit 'phedders/rdocs' 
121  
122It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. 
123  
124### Ancestry References ### 
125  
126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 
127Suppose you look at the history of your project: 
128  
129    $ git log --pretty=format:'%h %s' --graph 
130    * 734713b fixed refs handling, added gc auto, updated tests 
131    *   d921970 Merge commit 'phedders/rdocs' 
132    |\ 
133    | * 35cfb2b Some rdoc changes 
134    * | 1c002dd added some blame and merge stuff 
135    |/ 
136    * 1c36188 ignore *.gem 
137    * 9b29157 add open3_detach to gemspec file list 
138  
139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": 
140  
141    $ git show HEAD^ 
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
143    Merge: 1c002dd... 35cfb2b... 
144    Author: Scott Chacon <schacon@gmail.com> 
145    Date:   Thu Dec 11 15:08:43 2008 -0800 
146  
147        Merge commit 'phedders/rdocs' 
148  
149You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: 
150  
151    $ git show d921970^ 
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
153    Author: Scott Chacon <schacon@gmail.com> 
154    Date:   Thu Dec 11 14:58:32 2008 -0800 
155  
156        added some blame and merge stuff 
157  
158    $ git show d921970^2 
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 
160    Author: Paul Hedderly <paul+git@mjr.org> 
161    Date:   Wed Dec 10 22:22:03 2008 +0000 
162  
163        Some rdoc changes 
164  
165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be 
166  
167    $ git show HEAD~3 
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
169    Author: Tom Preston-Werner <tom@mojombo.com> 
170    Date:   Fri Nov 7 13:47:59 2008 -0500 
171  
172        ignore *.gem 
173  
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: 
175  
176    $ git show HEAD^^^ 
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
178    Author: Tom Preston-Werner <tom@mojombo.com> 
179    Date:   Fri Nov 7 13:47:59 2008 -0500 
180  
181        ignore *.gem 
182  
183You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. 
184  
185### Commit Ranges ### 
186  
187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 
188  
189#### Double Dot #### 
190  
191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. 
192  
193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
195  
196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: 
197  
198    $ git log master..experiment 
199    D 
200    C 
201  
202If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: 
203  
204    $ git log experiment..master 
205    F 
206    E 
207  
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: 
209  
210    $ git log origin/master..HEAD 
211  
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. 
213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. 
214  
215#### Multiple Points #### 
216  
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: 
218  
219    $ git log refA..refB 
220    $ git log ^refA refB 
221    $ git log refB --not refA 
222  
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: 
224  
225    $ git log refA refB ^refC 
226    $ git log refA refB --not refC 
227  
228This makes for a very powerful revision query system that should help you figure out what is in your branches. 
229  
230#### Triple Dot #### 
231  
232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. 
233If you want to see what is in `master` or `experiment` but not any common references, you can run 
234  
235    $ git log master...experiment 
236    F 
237    E 
238    D 
239    C 
240  
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. 
242  
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: 
244  
245    $ git log --left-right master...experiment 
246    < F 
247    < E 
248    > D 
249    > C 
250  
251With these tools, you can much more easily let Git know what commit or commits you want to inspect. 
252  
253## Interactive Staging ## 
254  
255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257  
258    $ git add -i 
259               staged     unstaged path 
260      1:    unchanged        +0/-1 TODO 
261      2:    unchanged        +1/-1 index.html 
262      3:    unchanged        +5/-1 lib/simplegit.rb 
263  
264    *** Commands *** 
265      1: status     2: update      3: revert     4: add untracked 
266      5: patch      6: diff        7: quit       8: help 
267    What now> 
268  
269You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. 
270  
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. 
272  
273### Staging and Unstaging Files ### 
274  
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: 
276  
277    What now> 2 
278               staged     unstaged path 
279      1:    unchanged        +0/-1 TODO 
280      2:    unchanged        +1/-1 index.html 
281      3:    unchanged        +5/-1 lib/simplegit.rb 
282    Update>> 
283  
284To stage the TODO and index.html files, you can type the numbers: 
285  
286    Update>> 1,2 
287               staged     unstaged path 
288    * 1:    unchanged        +0/-1 TODO 
289    * 2:    unchanged        +1/-1 index.html 
290      3:    unchanged        +5/-1 lib/simplegit.rb 
291    Update>> 
292  
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: 
294  
295    Update>> 
296    updated 2 paths 
297  
298    *** Commands *** 
299      1: status     2: update      3: revert     4: add untracked 
300      5: patch      6: diff        7: quit       8: help 
301    What now> 1 
302               staged     unstaged path 
303      1:        +0/-1      nothing TODO 
304      2:        +1/-1      nothing index.html 
305      3:    unchanged        +5/-1 lib/simplegit.rb 
306  
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: 
308  
309    *** Commands *** 
310      1: status     2: update      3: revert     4: add untracked 
311      5: patch      6: diff        7: quit       8: help 
312    What now> 3 
313               staged     unstaged path 
314      1:        +0/-1      nothing TODO 
315      2:        +1/-1      nothing index.html 
316      3:    unchanged        +5/-1 lib/simplegit.rb 
317    Revert>> 1 
318               staged     unstaged path 
319    * 1:        +0/-1      nothing TODO 
320      2:        +1/-1      nothing index.html 
321      3:    unchanged        +5/-1 lib/simplegit.rb 
322    Revert>> [enter] 
323    reverted one path 
324  
325Looking at your Git status again, you can see that you’ve unstaged the TODO file: 
326  
327    *** Commands *** 
328      1: status     2: update      3: revert     4: add untracked 
329      5: patch      6: diff        7: quit       8: help 
330    What now> 1 
331               staged     unstaged path 
332      1:    unchanged        +0/-1 TODO 
333      2:        +1/-1      nothing index.html 
334      3:    unchanged        +5/-1 lib/simplegit.rb 
335  
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: 
337  
338    *** Commands *** 
339      1: status     2: update      3: revert     4: add untracked 
340      5: patch      6: diff        7: quit       8: help 
341    What now> 6 
342               staged     unstaged path 
343      1:        +1/-1      nothing index.html 
344    Review diff>> 1 
345    diff --git a/index.html b/index.html 
346    index 4d07108..4335f49 100644 
347    --- a/index.html 
348    +++ b/index.html 
349    @@ -16,7 +16,7 @@ Date Finder 
350  
351     <p id="out">...</p> 
352  
353    -<div id="footer">contact : support@github.com</div> 
354    +<div id="footer">contact : email.support@github.com</div> 
355  
356     <script type="text/javascript"> 
357  
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily. 
359  
360### Staging Patches ### 
361  
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: 
363  
364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
365    index dd5ecc4..57399e0 100644 
366    --- a/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 
368    @@ -22,7 +22,7 @@ class SimpleGit 
369       end 
370  
371       def log(treeish = 'master') 
372    -    command("git log -n 25 #{treeish}") 
373    +    command("git log -n 30 #{treeish}") 
374       end 
375  
376       def blame(path) 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 
378  
379You have a lot of options at this point. Typing `?` shows a list of what you can do: 
380  
381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
382    y - stage this hunk 
383    n - do not stage this hunk 
384    a - stage this and all the remaining hunks in the file 
385    d - do not stage this hunk nor any of the remaining hunks in the file 
386    g - select a hunk to go to 
387    / - search for a hunk matching the given regex 
388    j - leave this hunk undecided, see next undecided hunk 
389    J - leave this hunk undecided, see next hunk 
390    k - leave this hunk undecided, see previous undecided hunk 
391    K - leave this hunk undecided, see previous hunk 
392    s - split the current hunk into smaller hunks 
393    e - manually edit the current hunk 
394    ? - print help 
395  
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: 
397  
398    What now> 1 
399               staged     unstaged path 
400      1:    unchanged        +0/-1 TODO 
401      2:        +1/-1      nothing index.html 
402      3:        +1/-1        +4/-0 lib/simplegit.rb 
403  
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. 
405  
406Finally, you don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using `git add -p` or `git add --patch` on the command line. 
407  
408## Stashing ## 
409  
410Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command. 
411  
412Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time. 
413  
414### Stashing Your Work ### 
415  
416To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state: 
417  
418    $ git status 
419    # On branch master 
420    # Changes to be committed: 
421    #   (use "git reset HEAD <file>..." to unstage) 
422    # 
423    #      modified:   index.html 
424    # 
425    # Changes not staged for commit: 
426    #   (use "git add <file>..." to update what will be committed) 
427    # 
428    #      modified:   lib/simplegit.rb 
429    # 
430  
431Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`: 
432  
433    $ git stash 
434    Saved working directory and index state \ 
435      "WIP on master: 049d078 added the index file" 
436    HEAD is now at 049d078 added the index file 
437    (To restore them type "git stash apply") 
438  
439Your working directory is clean: 
440  
441    $ git status 
442    # On branch master 
443    nothing to commit, working directory clean 
444  
445At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: 
446  
447    $ git stash list 
448    stash@{0}: WIP on master: 049d078 added the index file 
449    stash@{1}: WIP on master: c264051 Revert "added file_size" 
450    stash@{2}: WIP on master: 21d80a5 added number to log 
451  
452In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it: 
453  
454    $ git stash apply 
455    # On branch master 
456    # Changes not staged for commit: 
457    #   (use "git add <file>..." to update what will be committed) 
458    # 
459    #      modified:   index.html 
460    #      modified:   lib/simplegit.rb 
461    # 
462  
463You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly. 
464  
465The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position: 
466  
467    $ git stash apply --index 
468    # On branch master 
469    # Changes to be committed: 
470    #   (use "git reset HEAD <file>..." to unstage) 
471    # 
472    #      modified:   index.html 
473    # 
474    # Changes not staged for commit: 
475    #   (use "git add <file>..." to update what will be committed) 
476    # 
477    #      modified:   lib/simplegit.rb 
478    # 
479  
480The apply option only tries to apply the stashed work — you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove: 
481  
482    $ git stash list 
483    stash@{0}: WIP on master: 049d078 added the index file 
484    stash@{1}: WIP on master: c264051 Revert "added file_size" 
485    stash@{2}: WIP on master: 21d80a5 added number to log 
486    $ git stash drop stash@{0} 
487    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) 
488  
489You can also run `git stash pop` to apply the stash and then immediately drop it from your stack. 
490  
491### Un-applying a Stash ### 
492  
493In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
494  
495    $ git stash show -p stash@{0} | git apply -R 
496  
497Again, if you don’t specify a stash, Git assumes the most recent stash: 
498  
499    $ git stash show -p | git apply -R 
500  
501You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
502  
503    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
504    $ git stash apply 
505    $ #... work work work 
506    $ git stash-unapply 
507  
508### Creating a Branch from a Stash ### 
509  
510If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully: 
511  
512    $ git stash branch testchanges 
513    Switched to a new branch "testchanges" 
514    # On branch testchanges 
515    # Changes to be committed: 
516    #   (use "git reset HEAD <file>..." to unstage) 
517    # 
518    #      modified:   index.html 
519    # 
520    # Changes not staged for commit: 
521    #   (use "git add <file>..." to update what will be committed) 
522    # 
523    #      modified:   lib/simplegit.rb 
524    # 
525    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) 
526  
527This is a nice shortcut to recover stashed work easily and work on it in a new branch. 
528  
529## Rewriting History ## 
530  
531Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others. 
532  
533In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. 
534  
535### Changing the Last Commit ### 
536  
537Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 
538  
539If you only want to modify your last commit message, it’s very simple: 
540  
541    $ git commit --amend 
542  
543That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. 
544  
545If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. 
546  
547You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it. 
548  
549### Changing Multiple Commit Messages ### 
550  
551To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. 
552  
553For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: 
554  
555    $ git rebase -i HEAD~3 
556  
557Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change. 
558  
559Running this command gives you a list of commits in your text editor that looks something like this: 
560  
561    pick f7f3f6d changed my name a bit 
562    pick 310154e updated README formatting and added blame 
563    pick a5f4a0d added cat-file 
564  
565    # Rebase 710f0f8..a5f4a0d onto 710f0f8 
566    # 
567    # Commands: 
568    #  p, pick = use commit 
569    #  r, reword = use commit, but edit the commit message 
570    #  e, edit = use commit, but stop for amending 
571    #  s, squash = use commit, but meld into previous commit 
572    #  f, fixup = like "squash", but discard this commit's log message 
573    #  x, exec = run command (the rest of the line) using shell 
574    # 
575    # These lines can be re-ordered; they are executed from top to bottom. 
576    # 
577    # If you remove a line here THAT COMMIT WILL BE LOST. 
578    # 
579    # However, if you remove everything, the rebase will be aborted. 
580    # 
581    # Note that empty commits are commented out 
582  
583It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this: 
584  
585    $ git log --pretty=format:"%h %s" HEAD~3..HEAD 
586    a5f4a0d added cat-file 
587    310154e updated README formatting and added blame 
588    f7f3f6d changed my name a bit 
589  
590Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay. 
591  
592You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this: 
593  
594    edit f7f3f6d changed my name a bit 
595    pick 310154e updated README formatting and added blame 
596    pick a5f4a0d added cat-file 
597  
598When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message: 
599  
600<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  
601nor is the commit message. Please review  
602--> 
603  
604    $ git rebase -i HEAD~3 
605    Stopped at 7482e0d... updated the gemspec to hopefully work better 
606    You can amend the commit now, with 
607  
608           git commit --amend 
609  
610    Once you’re satisfied with your changes, run 
611  
612           git rebase --continue 
613  
614These instructions tell you exactly what to do. Type 
615  
616    $ git commit --amend 
617  
618Change the commit message, and exit the editor. Then, run 
619  
620    $ git rebase --continue 
621  
622This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished. 
623  
624### Reordering Commits ### 
625  
626You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this 
627  
628    pick f7f3f6d changed my name a bit 
629    pick 310154e updated README formatting and added blame 
630    pick a5f4a0d added cat-file 
631  
632to this: 
633  
634    pick 310154e updated README formatting and added blame 
635    pick f7f3f6d changed my name a bit 
636  
637When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely. 
638  
639### Squashing Commits ### 
640  
641It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message: 
642  
643    # 
644    # Commands: 
645    #  p, pick = use commit 
646    #  r, reword = use commit, but edit the commit message 
647    #  e, edit = use commit, but stop for amending 
648    #  s, squash = use commit, but meld into previous commit 
649    #  f, fixup = like "squash", but discard this commit's log message 
650    #  x, exec = run command (the rest of the line) using shell 
651    # 
652    # These lines can be re-ordered; they are executed from top to bottom. 
653    # 
654    # If you remove a line here THAT COMMIT WILL BE LOST. 
655    # 
656    # However, if you remove everything, the rebase will be aborted. 
657    # 
658    # Note that empty commits are commented out 
659  
660If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this: 
661  
662    pick f7f3f6d changed my name a bit 
663    squash 310154e updated README formatting and added blame 
664    squash a5f4a0d added cat-file 
665  
666When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages: 
667  
668    # This is a combination of 3 commits. 
669    # The first commit's message is: 
670    changed my name a bit 
671  
672    # This is the 2nd commit message: 
673  
674    updated README formatting and added blame 
675  
676    # This is the 3rd commit message: 
677  
678    added cat-file 
679  
680When you save that, you have a single commit that introduces the changes of all three previous commits. 
681  
682### Splitting a Commit ### 
683  
684Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit": 
685  
686    pick f7f3f6d changed my name a bit 
687    edit 310154e updated README formatting and added blame 
688    pick a5f4a0d added cat-file 
689  
690When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done: 
691  
692    $ git reset HEAD^ 
693    $ git add README 
694    $ git commit -m 'updated README formatting' 
695    $ git add lib/simplegit.rb 
696    $ git commit -m 'added blame' 
697    $ git rebase --continue 
698  
699Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this: 
700  
701    $ git log -4 --pretty=format:"%h %s" 
702    1c002dd added cat-file 
703    9b29157 added blame 
704    35cfb2b updated README formatting 
705    f3cc40e changed my name a bit 
706  
707Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository. 
708  
709### The Nuclear Option: filter-branch ### 
710  
711There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of. 
712  
713#### Removing a File from Every Commit #### 
714  
715This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`: 
716  
717    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 
718    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) 
719    Ref 'refs/heads/master' was rewritten 
720  
721The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`. 
722  
723You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. 
724  
725#### Making a Subdirectory the New Root #### 
726  
727Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too: 
728  
729    $ git filter-branch --subdirectory-filter trunk HEAD 
730    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) 
731    Ref 'refs/heads/master' was rewritten 
732  
733Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory. 
734  
735#### Changing E-Mail Addresses Globally #### 
736  
737Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`: 
738  
739    $ git filter-branch --commit-filter ' 
740            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; 
741            then 
742                    GIT_AUTHOR_NAME="Scott Chacon"; 
743                    GIT_AUTHOR_EMAIL="schacon@example.com"; 
744                    git commit-tree "$@"; 
745            else 
746                    git commit-tree "$@"; 
747            fi' HEAD 
748  
749This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address. 
750  
751### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
752  
753[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
754  
755See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
756  
757## Debugging with Git ## 
758  
759Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. 
760  
761### File Annotation ### 
762  
763If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: 
764  
765    $ git blame -L 12,22 simplegit.rb 
766    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master') 
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}") 
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end 
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15) 
770    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master') 
771    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}") 
772    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end 
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19) 
774    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path) 
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}") 
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end 
777  
778Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here. 
779  
780Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from: 
781  
782    $ git blame -C -L 141,153 GITPackUpload.m 
783    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
786    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
787    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
793    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 
796  
797This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. 
798  
799### Binary Search ### 
800  
801Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. 
802  
803Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: 
804  
805    $ git bisect start 
806    $ git bisect bad 
807    $ git bisect good v1.0 
808    Bisecting: 6 revisions left to test after this 
809    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo 
810  
811Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: 
812  
813    $ git bisect good 
814    Bisecting: 3 revisions left to test after this 
815    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing 
816  
817Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: 
818  
819    $ git bisect bad 
820    Bisecting: 1 revisions left to test after this 
821    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table 
822  
823This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: 
824  
825    $ git bisect good 
826    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit 
827    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 
828    Author: PJ Hyett <pjhyett@example.com> 
829    Date:   Tue Jan 27 14:48:32 2009 -0800 
830  
831        secure this thing 
832  
833    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 
834    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config 
835  
836When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: 
837  
838    $ git bisect reset 
839  
840This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: 
841  
842    $ git bisect start HEAD v1.0 
843    $ git bisect run test-error.sh 
844  
845Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. 
846  
847## Submodules ## 2=== Submodules 
848 3 
849It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other.4It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other.
850 5 
851Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available.6Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available.
852 7 
853Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.8Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.
854 9 
. 10[[_starting_submodules]]
855### Starting with Submodules ### 11==== Starting with Submodules 
856 12 
.857Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
 13We'll walk through developing a simple project that has been split up into a main project and a few sub-projects.
858 14 
. 15Let's start by adding an existing Git repository as a submodule of the repository that we're working on. To add a new submodule you use the `git submodule add` command with the URL of the project you would like to start tracking. In this example, we'll add a library called ``DbConnector''.
 16 
 17[source,console]
 18----
859    $ git submodule add git://github.com/chneukirchen/rack.git rack 19$ git submodule add https://github.com/chaconinc/DbConnector 
860    Initialized empty Git repository in /opt/subtest/rack/.git/ 20Cloning into 'DbConnector'... 
861    remote: Counting objects: 3181, done.21remote: Counting objects: 11, done.
862    remote: Compressing objects: 100% (1534/1534), done.22remote: Compressing objects: 100% (10/10), done.
863    remote: Total 3181 (delta 1951), reused 2623 (delta 1603)23remote: Total 11 (delta 0), reused 11 (delta 0)
864    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done.24Unpacking objects: 100% (11/11), done.
865    Resolving deltas: 100% (1951/1951), done.25Checking connectivity... done.
 26----
866 27 
.867Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
 28By default, submodules will add the subproject into a directory named the same as the repository, in this case ``DbConnector''. You can add a different path at the end of the command if you want it to go elsewhere.
868 29 
. 30If you run `git status` at this point, you'll notice a few things.
 31 
 32[source,console]
 33----
869    $ git status34$ git status
870    # On branch master35On branch master
 36Your branch is up-to-date with 'origin/master'.
 37 
871    # Changes to be committed:38Changes to be committed:
872    #   (use "git reset HEAD <file>..." to unstage)39  (use "git reset HEAD <file>..." to unstage)
873    # 40 
874    #      new file:   .gitmodules41    new file:   .gitmodules
875    #      new file:   rack 42    new file:   DbConnector 
876    # 43---- 
877 44 
.878First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into:45First you should notice the new `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into:
879 46 
. 47[source,console]
 48----
880    $ cat .gitmodules49$ cat .gitmodules
881    [submodule "rack"]50[submodule "DbConnector"]
882          path = rack 51    path = DbConnector 
883          url = git://github.com/chneukirchen/rack.git 52    url = https://github.com/chaconinc/DbConnector 
 53----
884 54 
885If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from.55If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from.
886 56 
. 57[NOTE]
 58=====
 59Since the URL in the .gitmodules file is what other people will first try to clone/fetch from, make sure to use a URL that they can access if possible. For example, if you use a different URL to push to than others would to pull from, use the one that others have access to. You can overwrite this value locally with `git config submodule.DbConnector.url PRIVATE_URL` for your own use.
 60=====
 61 
887The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting:62The other listing in the `git status` output is the project folder entry. If you run `git diff` on that, you see something interesting:
888 63 
. 64[source,console]
 65----
889    $ git diff --cached rack 66$ git diff --cached DbConnector 
890    diff --git a/rack b/rack 67diff --git a/DbConnector b/DbConnector 
891    new file mode 16000068new file mode 160000
892    index 0000000..08d709f 69index 0000000..c3f01dc 
893    --- /dev/null70--- /dev/null
894    +++ b/rack 71+++ b/DbConnector 
895    @@ -0,0 +1 @@72@@ -0,0 +1 @@
896    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 73+Subproject commit c3f01dc8862123d317dd46284b05b6892c7b29bc 
 74----
897 75 
.898Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 76Although `DbConnector` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git sees it as a particular commit from that repository. 
899 77 
.900This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
 78If you want a little nicer diff output, you can pass the `--submodule` option to `git diff`.
 79 
 80[source,console]
 81----
 82$ git diff --cached --submodule
 83diff --git a/.gitmodules b/.gitmodules
 84new file mode 100644
 85index 0000000..71fc376
 86--- /dev/null
 87+++ b/.gitmodules
 88@@ -0,0 +1,3 @@
 89+[submodule "DbConnector"]
 90+       path = DbConnector
 91+       url = https://github.com/chaconinc/DbConnector
 92Submodule DbConnector 0000000...c3f01dc (new submodule)
 93----
901 94 
902When you commit, you see something like this:95When you commit, you see something like this:
903 96 
. 97[source,console]
 98----
904    $ git commit -m 'first commit with submodule rack'99$ git commit -am 'added DbConnector module'
905    [master 0550271] first commit with submodule rack 100[master fb9093c] added DbConnector module 
906     2 files changed, 4 insertions(+), 0 deletions(-)101 2 files changed, 4 insertions(+)
907     create mode 100644 .gitmodules102 create mode 100644 .gitmodules
908     create mode 160000 rack 103 create mode 160000 DbConnector 
 104----
909 105 
.910Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file.106Notice the `160000` mode for the `DbConnector` entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file.
911  
912You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
913  
914    $ git log -1 
915    commit 0550271328a0038865aad6331e620cd7238601bb 
916    Author: Scott Chacon <schacon@gmail.com> 
917    Date:   Thu Apr 9 09:03:56 2009 -0700 
918  
919        first commit with submodule rack 
920    $ cd rack/ 
921    $ git log -1 
922    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
923    Author: Christian Neukirchen <chneukirchen@gmail.com> 
924    Date:   Wed Mar 25 14:49:04 2009 +0100 
925  
926        Document version change 
927 107 
. 108[[_cloning_submodules]]
928### Cloning a Project with Submodules ### 109==== Cloning a Project with Submodules 
929 110 
.930Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet:111Here we’ll clone a project with a submodule in it. When you clone such a project, by default you get the directories that contain submodules, but none of the files within them yet:
931 112 
. 113[source,console]
 114----
932    $ git clone git://github.com/schacon/myproject.git115$ git clone https://github.com/chaconinc/MainProject
933    Initialized empty Git repository in /opt/myproject/.git/ 116Cloning into 'MainProject'... 
934    remote: Counting objects: 6, done.117remote: Counting objects: 14, done.
935    remote: Compressing objects: 100% (4/4), done.118remote: Compressing objects: 100% (13/13), done.
936    remote: Total 6 (delta 0), reused 0 (delta 0)119remote: Total 14 (delta 1), reused 13 (delta 0)
937    Receiving objects: 100% (6/6), done.120Unpacking objects: 100% (14/14), done.
938    $ cd myproject 121Checking connectivity... done. 
939    $ ls -l 122$ cd MainProject 
940    total 8 123$ ls -la 
941    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 124total 16 
942    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 125drwxr-xr-x   9 schacon  staff  306 Sep 17 15:21 . 
943    $ ls rack/ 126drwxr-xr-x   7 schacon  staff  238 Sep 17 15:21 .. 
944    $ 127drwxr-xr-x  13 schacon  staff  442 Sep 17 15:21 .git 
 128-rw-r--r--   1 schacon  staff   92 Sep 17 15:21 .gitmodules
 129drwxr-xr-x   2 schacon  staff   68 Sep 17 15:21 DbConnector
 130-rw-r--r--   1 schacon  staff  756 Sep 17 15:21 Makefile
 131drwxr-xr-x   3 schacon  staff  102 Sep 17 15:21 includes
 132drwxr-xr-x   4 schacon  staff  136 Sep 17 15:21 scripts
 133drwxr-xr-x   4 schacon  staff  136 Sep 17 15:21 src
 134$ cd DbConnector/
 135$ ls
 136$
 137----
945 138 
.946The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject:139The `DbConnector` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject:
947 140 
. 141[source,console]
 142----
948    $ git submodule init143$ git submodule init
949    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack'144Submodule 'DbConnector' (https://github.com/chaconinc/DbConnector) registered for path 'DbConnector'
950    $ git submodule update145$ git submodule update
951    Initialized empty Git repository in /opt/myproject/rack/.git/ 146Cloning into 'DbConnector'... 
952    remote: Counting objects: 3181, done.147remote: Counting objects: 11, done.
953    remote: Compressing objects: 100% (1534/1534), done.148remote: Compressing objects: 100% (10/10), done.
954    remote: Total 3181 (delta 1951), reused 2623 (delta 1603)149remote: Total 11 (delta 0), reused 11 (delta 0)
955    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done.150Unpacking objects: 100% (11/11), done.
956    Resolving deltas: 100% (1951/1951), done.151Checking connectivity... done.
957    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433'152Submodule path 'DbConnector': checked out 'c3f01dc8862123d317dd46284b05b6892c7b29bc'
 153----
958 154 
.959Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 155Now your `DbConnector` subdirectory is at the exact state it was in when you committed earlier. 
 156 
 157There is another way to do this which is a little simpler, however. If you pass `--recursive` to the `git clone` command, it will automatically initialize and update each submodule in the repository.
 158 
 159[source,console]
 160----
 161$ git clone --recursive https://github.com/chaconinc/MainProject
 162Cloning into 'MainProject'...
 163remote: Counting objects: 14, done.
 164remote: Compressing objects: 100% (13/13), done.
 165remote: Total 14 (delta 1), reused 13 (delta 0)
 166Unpacking objects: 100% (14/14), done.
 167Checking connectivity... done.
 168Submodule 'DbConnector' (https://github.com/chaconinc/DbConnector) registered for path 'DbConnector'
 169Cloning into 'DbConnector'...
 170remote: Counting objects: 11, done.
 171remote: Compressing objects: 100% (10/10), done.
 172remote: Total 11 (delta 0), reused 11 (delta 0)
 173Unpacking objects: 100% (11/11), done.
 174Checking connectivity... done.
 175Submodule path 'DbConnector': checked out 'c3f01dc8862123d317dd46284b05b6892c7b29bc'
 176----
960 177 
.961    $ git merge origin/master 
962    Updating 0550271..85a3eee 
963    Fast forward 
964     rack |    2 +- 
965     1 files changed, 1 insertions(+), 1 deletions(-) 
966    [master*]$ git status 
967    # On branch master 
968    # Changes not staged for commit: 
969    #   (use "git add <file>..." to update what will be committed) 
970    #   (use "git checkout -- <file>..." to discard changes in working directory) 
971    # 
972    #      modified:   rack 
973    # 
974  
975You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
976  
977    $ git diff 
978    diff --git a/rack b/rack 
979    index 6c5e70b..08d709f 160000 
980    --- a/rack 
981    +++ b/rack 
982    @@ -1 +1 @@ 
983    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
984    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
985  
986This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
987  
988    $ git submodule update 
989    remote: Counting objects: 5, done. 
990    remote: Compressing objects: 100% (3/3), done. 
991    remote: Total 3 (delta 1), reused 2 (delta 0) 
992    Unpacking objects: 100% (3/3), done. 
993    From git@github.com:schacon/rack 
994       08d709f..6c5e70b  master     -> origin/master 
995    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
996  
997You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
998  
999One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1000  
1001    $ git submodule update 
1002    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1003    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1004  
1005You have to see who last changed the submodule: 
1006  
1007    $ git log -1 rack 
1008    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1009    Author: Scott Chacon <schacon@gmail.com> 
1010    Date:   Thu Apr 9 09:19:14 2009 -0700 
1011  
1012        added a submodule reference I will never make public. hahahahaha! 
1013  
1014Then, you e-mail that guy and yell at him. 
 178==== Working on a Project with Submodules
 179 
 180Now we have a copy of a project with submodules in it and will collaborate with our teammates on both the main project and the submodule project.
 181 
 182===== Pulling in Upstream Changes
 183 
 184The simplest model of using submodules in a project would be if you were simply consuming a subproject and wanted to get updates from it from time to time but were not actually modifying anything in your checkout. Let's walk though a simple example there.
 185 
 186If you want to check for new work in a submodule, you can go into the directory and run `git fetch` and `git merge` the upstream branch to update the local code.
 187 
 188[source,console]
 189----
 190$ git fetch
 191From https://github.com/chaconinc/DbConnector
 192   c3f01dc..d0354fc  master     -> origin/master
 193$ git merge origin/master
 194Updating c3f01dc..d0354fc
 195Fast-forward
 196 scripts/connect.sh | 1 +
 197 src/db.c           | 1 +
 198 2 files changed, 2 insertions(+)
 199----
 200 
 201Now if you go back into the main project and run `git diff --submodule` you can see that the submodule was updated and get a list of commits that were added to it. If you don't want to type `--submodule` every time you run `git diff`, you can set it as the default format by setting the `diff.submodule` config value to ``log''.
 202 
 203[source,console]
 204----
 205$ git config --global diff.submodule log
 206$ git diff
 207Submodule DbConnector c3f01dc..d0354fc:
 208  > more efficient db routine
 209  > better connection routine
 210----
 211 
 212If you commit at this point then you will lock the submodule into having the new code when other people update.
 213 
 214There is an easier way to do this as well, if you prefer to not manually fetch and merge in the subdirectory. If you run `git submodule update --remote`, Git will go into your submodules and fetch and update for you.
 215 
 216[source,console]
 217----
 218$ git submodule update --remote DbConnector
 219remote: Counting objects: 4, done.
 220remote: Compressing objects: 100% (2/2), done.
 221remote: Total 4 (delta 2), reused 4 (delta 2)
 222Unpacking objects: 100% (4/4), done.
 223From https://github.com/chaconinc/DbConnector
 224   3f19983..d0354fc  master     -> origin/master
 225Submodule path 'DbConnector': checked out 'd0354fc054692d3906c85c3af05ddce39a1c0644'
 226----
 227 
 228This command will by default assume that you want to update the checkout to the `master` branch of the submodule repository. You can, however, set this to something different if you want. For example, if you want to have the DbConnector submodule track that repository's ``stable'' branch, you can set it in either your `.gitmodules` file (so everyone else also tracks it), or just in your local `.git/config` file.  Let's set it in the `.gitmodules` file:
 229 
 230[source,console]
 231----
 232$ git config -f .gitmodules submodule.DbConnector.branch stable
 233 
 234$ git submodule update --remote
 235remote: Counting objects: 4, done.
 236remote: Compressing objects: 100% (2/2), done.
 237remote: Total 4 (delta 2), reused 4 (delta 2)
 238Unpacking objects: 100% (4/4), done.
 239From https://github.com/chaconinc/DbConnector
 240   27cf5d3..c87d55d  stable -> origin/stable
 241Submodule path 'DbConnector': checked out 'c87d55d4c6d4b05ee34fbc8cb6f7bf4585ae6687'
 242----
 243 
 244If you leave off the `-f .gitmodules` it will only make the change for you, but it probably makes more sense to track that information with the repository so everyone else does as well.
 245 
 246When we run `git status` at this point, Git will show us that we have ``new commits'' on the submodule.
 247 
 248[source,console]
 249----
 250$ git status
 251On branch master
 252Your branch is up-to-date with 'origin/master'.
 253 
 254Changes not staged for commit:
 255  (use "git add <file>..." to update what will be committed)
 256  (use "git checkout -- <file>..." to discard changes in working directory)
 257 
 258  modified:   .gitmodules
 259  modified:   DbConnector (new commits)
 260 
 261no changes added to commit (use "git add" and/or "git commit -a")
 262----
 263 
 264If you set the configuration setting `status.submodulesummary`, Git will also show you a short summary of changes to your submodules:
 265 
 266[source,console]
 267----
 268$ git config status.submodulesummary 1
 269 
 270$ git status
 271On branch master
 272Your branch is up-to-date with 'origin/master'.
 273 
 274Changes not staged for commit:
 275  (use "git add <file>..." to update what will be committed)
 276  (use "git checkout -- <file>..." to discard changes in working directory)
 277 
 278    modified:   .gitmodules
 279    modified:   DbConnector (new commits)
 280 
 281Submodules changed but not updated:
 282 
 283* DbConnector c3f01dc...c87d55d (4):
 284  > catch non-null terminated lines
 285----
 286 
 287At this point if you run `git diff` we can see both that we have modified our `.gitmodules` file and also that there are a number of commits that we've pulled down and are ready to commit to our submodule project.
 288 
 289[source,console]
 290----
 291$ git diff
 292diff --git a/.gitmodules b/.gitmodules
 293index 6fc0b3d..fd1cc29 100644
 294--- a/.gitmodules
 295+++ b/.gitmodules
 296@@ -1,3 +1,4 @@
 297 [submodule "DbConnector"]
 298        path = DbConnector
 299        url = https://github.com/chaconinc/DbConnector
 300+       branch = stable
 301 Submodule DbConnector c3f01dc..c87d55d:
 302  > catch non-null terminated lines
 303  > more robust error handling
 304  > more efficient db routine
 305  > better connection routine
 306----
 307 
 308This is pretty cool as we can actually see the log of commits that we're about to commit to in our submodule. Once committed, you can see this information after the fact as well when you run `git log -p`.
 309 
 310[source,console]
 311----
 312$ git log -p --submodule
 313commit 0a24cfc121a8a3c118e0105ae4ae4c00281cf7ae
 314Author: Scott Chacon <schacon@gmail.com>
 315Date:   Wed Sep 17 16:37:02 2014 +0200
 316 
 317    updating DbConnector for bug fixes
 318 
 319diff --git a/.gitmodules b/.gitmodules
 320index 6fc0b3d..fd1cc29 100644
 321--- a/.gitmodules
 322+++ b/.gitmodules
 323@@ -1,3 +1,4 @@
 324 [submodule "DbConnector"]
 325        path = DbConnector
 326        url = https://github.com/chaconinc/DbConnector
 327+       branch = stable
 328Submodule DbConnector c3f01dc..c87d55d:
 329  > catch non-null terminated lines
 330  > more robust error handling
 331  > more efficient db routine
 332  > better connection routine
 333----
 334 
 335Git will by default try to update **all** of your submodules when you run `git submodule update --remote` so if you have a lot of them, you may want to pass the name of just the submodule you want to try to update.
 336 
 337===== Working on a Submodule
 338 
 339It's quite likely that if you're using submodules, you're doing so because you really want to work on the code in the submodule at the same time as you're working on the code in the main project (or across several submodules). Otherwise you would probably instead be using a simpler dependency management system (such as Maven or Rubygems).
 340 
 341So now let's go through an example of making changes to the submodule at the same time as the main project and committing and publishing those changes at the same time.
 342 
 343So far, when we've run the `git submodule update` command to fetch changes from the submodule repositories, Git would get the changes and update the files in the subdirectory but will leave the sub-repository in what's called a ``detached HEAD'' state. This means that there is no local working branch (like ``master'', for example) tracking changes. So any changes you make aren't being tracked well.
 344 
 345In order to set up your submodule to be easier to go in and hack on, you need do two things. You need to go into each submodule and check out a branch to work on. Then you need to tell Git what to do if you have made changes and then `git submodule update --remote` pulls in new work from upstream. The options are that you can merge them into your local work, or you can try to rebase your local work on top of the new changes.
 346 
 347First of all, let's go into our submodule directory and check out a branch.
 348 
 349[source,console]
 350----
 351$ git checkout stable
 352Switched to branch 'stable'
 353----
 354 
 355Let's try it with the ``merge'' option. To specify it manually, we can just add the `--merge` option to our `update` call. Here we'll see that there was a change on the server for this submodule and it gets merged in.
 356 
 357[source,console]
 358----
 359$ git submodule update --remote --merge
 360remote: Counting objects: 4, done.
 361remote: Compressing objects: 100% (2/2), done.
 362remote: Total 4 (delta 2), reused 4 (delta 2)
 363Unpacking objects: 100% (4/4), done.
 364From https://github.com/chaconinc/DbConnector
 365   c87d55d..92c7337  stable     -> origin/stable
 366Updating c87d55d..92c7337
 367Fast-forward
 368 src/main.c | 1 +
 369 1 file changed, 1 insertion(+)
 370Submodule path 'DbConnector': merged in '92c7337b30ef9e0893e758dac2459d07362ab5ea'
 371----
 372 
 373If we go into the DbConnector directory, we have the new changes already merged into our local `stable` branch. Now let's see what happens when we make our own local change to the library and someone else pushes another change upstream at the same time.
 374 
 375[source,console]
 376----
 377$ cd DbConnector/
 378$ vim src/db.c
 379$ git commit -am 'unicode support'
 380[stable f906e16] unicode support
 381 1 file changed, 1 insertion(+)
 382----
 383 
 384Now if we update our submodule we can see what happens when we have made a local change and upstream also has a change we need to incorporate.
 385 
 386[source,console]
 387----
 388$ git submodule update --remote --rebase
 389First, rewinding head to replay your work on top of it...
 390Applying: unicode support
 391Submodule path 'DbConnector': rebased into '5d60ef9bbebf5a0c1c1050f242ceeb54ad58da94'
 392----
 393 
 394If you forget the `--rebase` or `--merge`, Git will just update the submodule to whatever is on the server and reset your project to a detached HEAD state.
 395 
 396[source,console]
 397----
 398$ git submodule update --remote
 399Submodule path 'DbConnector': checked out '5d60ef9bbebf5a0c1c1050f242ceeb54ad58da94'
 400----
 401 
 402If this happens, don't worry, you can simply go back into the directory and check out your branch again (which will still contain your work) and merge or rebase `origin/stable` (or whatever remote branch you want) manually.
 403 
 404If you haven't committed your changes in your submodule and you run a submodule update that would cause issues, Git will fetch the changes but not overwrite unsaved work in your submodule directory.
 405 
 406[source,console]
 407----
 408$ git submodule update --remote
 409remote: Counting objects: 4, done.
 410remote: Compressing objects: 100% (3/3), done.
 411remote: Total 4 (delta 0), reused 4 (delta 0)
 412Unpacking objects: 100% (4/4), done.
 413From https://github.com/chaconinc/DbConnector
 414   5d60ef9..c75e92a  stable     -> origin/stable
 415error: Your local changes to the following files would be overwritten by checkout:
 416    scripts/setup.sh
 417Please, commit your changes or stash them before you can switch branches.
 418Aborting
 419Unable to checkout 'c75e92a2b3855c9e5b66f915308390d9db204aca' in submodule path 'DbConnector'
 420----
 421 
 422If you made changes that conflict with something changed upstream, Git will let you know when you run the update.
 423 
 424[source,console]
 425----
 426$ git submodule update --remote --merge
 427Auto-merging scripts/setup.sh
 428CONFLICT (content): Merge conflict in scripts/setup.sh
 429Recorded preimage for 'scripts/setup.sh'
 430Automatic merge failed; fix conflicts and then commit the result.
 431Unable to merge 'c75e92a2b3855c9e5b66f915308390d9db204aca' in submodule path 'DbConnector'
 432----
 433 
 434You can go into the submodule directory and fix the conflict just as you normally would.
 435 
 436[[_publishing_submodules]]
 437===== Publishing Submodule Changes
 438 
 439Now we have some changes in our submodule directory. Some of these were brought in from upstream by our updates and others were made locally and aren't available to anyone else yet as we haven't pushed them yet.
 440 
 441[source,console]
 442----
 443$ git diff
 444Submodule DbConnector c87d55d..82d2ad3:
 445  > Merge from origin/stable
 446  > updated setup script
 447  > unicode support
 448  > remove unnecessary method
 449  > add new option for conn pooling
 450----
 451 
 452If we commit in the main project and push it up without pushing the submodule changes up as well, other people who try to check out our changes are going to be in trouble since they will have no way to get the submodule changes that are depended on. Those changes will only exist on our local copy.
 453 
 454In order to make sure this doesn't happen, you can ask Git to check that all your submodules have been pushed properly before pushing the main project. The `git push` command takes the `--recurse-submodules` argument which can be set to either ``check'' or ``on-demand''. The ``check'' option will make `push` simply fail if any of the committed submodule changes haven't been pushed.
 455 
 456[source,console]
 457----
 458$ git push --recurse-submodules=check
 459The following submodule paths contain changes that can
 460not be found on any remote:
 461  DbConnector
 462 
 463Please try
 464 
 465    git push --recurse-submodules=on-demand
 466 
 467or cd to the path and use
 468 
 469    git push
 470 
 471to push them to a remote.
 472----
 473 
 474As you can see, it also gives us some helpful advice on what we might want to do next. The simple option is to go into each submodule and manually push to the remotes to make sure they're externally available and then try this push again.
 475 
 476The other option is to use the ``on-demand'' value, which will try to do this for you.
 477 
 478[source,console]
 479----
 480$ git push --recurse-submodules=on-demand
 481Pushing submodule 'DbConnector'
 482Counting objects: 9, done.
 483Delta compression using up to 8 threads.
 484Compressing objects: 100% (8/8), done.
 485Writing objects: 100% (9/9), 917 bytes | 0 bytes/s, done.
 486Total 9 (delta 3), reused 0 (delta 0)
 487To https://github.com/chaconinc/DbConnector
 488   c75e92a..82d2ad3  stable -> stable
 489Counting objects: 2, done.
 490Delta compression using up to 8 threads.
 491Compressing objects: 100% (2/2), done.
 492Writing objects: 100% (2/2), 266 bytes | 0 bytes/s, done.
 493Total 2 (delta 1), reused 0 (delta 0)
 494To https://github.com/chaconinc/MainProject
 495   3d6d338..9a377d1  master -> master
 496----
 497 
 498As you can see there, Git went into the DbConnector module and pushed it before pushing the main project. If that submodule push fails for some reason, the main project push will also fail.
 499 
 500===== Merging Submodule Changes
 501 
 502If you change a submodule reference at the same time as someone else, you may run into some problems. That is, if the submodule histories have diverged and are committed to diverging branches in a superproject, it may take a bit of work for you to fix.
 503 
 504If one of the commits is a direct ancestor of the other (a fast-forward merge), then Git will simply choose the latter for the merge, so that works fine.
 505 
 506Git will not attempt even a trivial merge for you, however. If the submodule commits diverge and need to be merged, you will get something that looks like this:
 507 
 508[source,console]
 509----
 510$ git pull
 511remote: Counting objects: 2, done.
 512remote: Compressing objects: 100% (1/1), done.
 513remote: Total 2 (delta 1), reused 2 (delta 1)
 514Unpacking objects: 100% (2/2), done.
 515From https://github.com/chaconinc/MainProject
 516   9a377d1..eb974f8  master     -> origin/master
 517Fetching submodule DbConnector
 518warning: Failed to merge submodule DbConnector (merge following commits not found)
 519Auto-merging DbConnector
 520CONFLICT (submodule): Merge conflict in DbConnector
 521Automatic merge failed; fix conflicts and then commit the result.
 522----
 523 
 524So basically what has happened here is that Git has figured out that the two branches record points in the submodule's history that are divergent and need to be merged. It explains it as ``merge following commits not found'', which is confusing but we'll explain why that is in a bit.
 525 
 526To solve the problem, you need to figure out what state the submodule should be in. Strangely, Git doesn't really give you much information to help out here, not even the SHAs of the commits of both sides of the history. Fortunately, it's simple to figure out.  If you run `git diff` you can get the SHAs of the commits recorded in both branches you were trying to merge.
 527 
 528[source,console]
 529----
 530$ git diff
 531diff --cc DbConnector
 532index eb41d76,c771610..0000000
 533--- a/DbConnector
 534+++ b/DbConnector
 535----
 536 
 537So, in this case, `eb41d76` is the commit in our submodule that *we* had and `c771610` is the commit that upstream had. If we go into our submodule directory, it should already be on `eb41d76` as the merge would not have touched it. If for whatever reason it's not, you can simply create and checkout a branch pointing to it.
 538 
 539What is important is the SHA of the commit from the other side. This is what you'll have to merge in and resolve. You can either just try the merge with the SHA directly, or you can create a branch for it and then try to merge that in. We would suggest the latter, even if only to make a nicer merge commit message.
 540 
 541So, we will go into our submodule directory, create a branch based on that second SHA from `git diff` and manually merge.
 542 
 543[source,console]
 544----
 545$ cd DbConnector
 546 
 547$ git rev-parse HEAD
 548eb41d764bccf88be77aced643c13a7fa86714135
 549 
 550$ git branch try-merge c771610
 551(DbConnector) $ git merge try-merge
 552Auto-merging src/main.c
 553CONFLICT (content): Merge conflict in src/main.c
 554Recorded preimage for 'src/main.c'
 555Automatic merge failed; fix conflicts and then commit the result.
 556----
 557 
 558We got an actual merge conflict here, so if we resolve that and commit it, then we can simply update the main project with the result.
 559 
 560[source,console]
 561----
 562$ vim src/main.c <1>
 563$ git add src/main.c
 564$ git commit -am 'merged our changes'
 565Recorded resolution for 'src/main.c'.
 566[master 9fd905e] merged our changes
 567 
 568$ cd .. <2>
 569$ git diff <3>
 570diff --cc DbConnector
 571index eb41d76,c771610..0000000
 572--- a/DbConnector
 573+++ b/DbConnector
 574@@@ -1,1 -1,1 +1,1 @@@
 575- Subproject commit eb41d764bccf88be77aced643c13a7fa86714135
 576 -Subproject commit c77161012afbbe1f58b5053316ead08f4b7e6d1d
 577++Subproject commit 9fd905e5d7f45a0d4cbc43d1ee550f16a30e825a
 578$ git add DbConnector <4>
 579 
 580$ git commit -m "Merge Tom's Changes" <5>
 581[master 10d2c60] Merge Tom's Changes
 582----
 583 
 584<1> First we resolve the conflict
 585<2> Then we go back to the main project directory
 586<3> We can check the SHAs again
 587<4> Resolve the conflicted submodule entry
 588<5> Commit our merge
 589 
 590It can be a bit confusing, but it's really not very hard.
 591 
 592Interestingly, there is another case that Git handles.
 593If a merge commit exists in the submodule directory that contains **both** commits in it's history, Git will suggest it to you as a possible solution. It sees that at some point in the submodule project, someone merged branches containing these two commits, so maybe you'll want that one.
 594 
 595This is why the error message from before was ``merge following commits not found'', because it could not do *this*. It's confusing because who would expect it to **try** to do this?
 596 
 597If it does find a single acceptable merge commit, you'll see something like this:
 598 
 599[source,console]
 600----
 601$ git merge origin/master
 602warning: Failed to merge submodule DbConnector (not fast-forward)
 603Found a possible merge resolution for the submodule:
 604 9fd905e5d7f45a0d4cbc43d1ee550f16a30e825a: > merged our changes
 605If this is correct simply add it to the index for example
 606by using:
 607 
 608  git update-index --cacheinfo 160000 9fd905e5d7f45a0d4cbc43d1ee550f16a30e825a "DbConnector"
 609 
 610which will accept this suggestion.
 611Auto-merging DbConnector
 612CONFLICT (submodule): Merge conflict in DbConnector
 613Automatic merge failed; fix conflicts and then commit the result.
 614----
 615 
 616What it's suggesting that you do is to update the index like you had run `git add`, which clears the conflict, then commit. You probably shouldn't do this though. You can just as easily go into the submodule directory, see what the difference is, fast-forward to this commit, test it properly, and then commit it.
 617 
 618[source,console]
 619----
 620$ cd DbConnector/
 621$ git merge 9fd905e
 622Updating eb41d76..9fd905e
 623Fast-forward
 624 
 625$ cd ..
 626$ git add DbConnector
 627$ git commit -am 'Fast forwarded to a common submodule child'
 628----
 629 
 630This accomplishes the same thing, but at least this way you can verify that it works and you have the code in your submodule directory when you're done.
 631 
 632 
 633==== Submodule Tips
 634 
 635There are a few things you can do to make working with submodules a little easier.
 636 
 637===== Submodule Foreach
 638 
 639There is a `foreach` submodule command to run some arbitrary command in each submodule. This can be really helpful if you have a number of submodules in the same project.
 640 
 641For example, let's say we want to start a new feature or do a bugfix and we have work going on in several submodules. We can easily stash all the work in all our submodules.
 642 
 643[source,console]
 644----
 645$ git submodule foreach 'git stash'
 646Entering 'CryptoLibrary'
 647No local changes to save
 648Entering 'DbConnector'
 649Saved working directory and index state WIP on stable: 82d2ad3 Merge from origin/stable
 650HEAD is now at 82d2ad3 Merge from origin/stable
 651----
 652 
 653Then we can create a new branch and switch to it in all our submodules.
 654 
 655[source,console]
 656----
 657$ git submodule foreach 'git checkout -b featureA'
 658Entering 'CryptoLibrary'
 659Switched to a new branch 'featureA'
 660Entering 'DbConnector'
 661Switched to a new branch 'featureA'
 662----
 663 
 664You get the idea. One really useful thing you can do is produce a nice unified diff of what is changed in your main project and all your subprojects as well.
 665 
 666[source,console]
 667----
 668$ git diff; git submodule foreach 'git diff'
 669Submodule DbConnector contains modified content
 670diff --git a/src/main.c b/src/main.c
 671index 210f1ae..1f0acdc 100644
 672--- a/src/main.c
 673+++ b/src/main.c
 674@@ -245,6 +245,8 @@ static int handle_alias(int *argcp, const char ***argv)
 675 
 676      commit_pager_choice();
 677 
 678+     url = url_decode(url_orig);
 679+
 680      /* build alias_argv */
 681      alias_argv = xmalloc(sizeof(*alias_argv) * (argc + 1));
 682      alias_argv[0] = alias_string + 1;
 683Entering 'DbConnector'
 684diff --git a/src/db.c b/src/db.c
 685index 1aaefb6..5297645 100644
 686--- a/src/db.c
 687+++ b/src/db.c
 688@@ -93,6 +93,11 @@ char *url_decode_mem(const char *url, int len)
 689        return url_decode_internal(&url, len, NULL, &out, 0);
 690 }
 691 
 692+char *url_decode(const char *url)
 693+{
 694+       return url_decode_mem(url, strlen(url));
 695+}
 696+
 697 char *url_decode_parameter_name(const char **query)
 698 {
 699        struct strbuf out = STRBUF_INIT;
 700----
 701 
 702Here we can see that we're defining a function in a submodule and calling it in the main project. This is obviously a simplified example, but hopefully it gives you an idea of how this may be useful.
 703 
 704===== Useful Aliases
 705 
 706You may want to set up some aliases for some of these commands as they can be quite long and you can't set configuration options for most of them to make them defaults. We covered setting up Git aliases in <<_git_aliases>>, but here is an example of what you may want to set up if you plan on working with submodules in Git a lot.
 707 
 708[source,console]
 709----
 710$ git config alias.sdiff '!'"git diff && git submodule foreach 'git diff'"
 711$ git config alias.spush 'push --recurse-submodules=on-demand'
 712$ git config alias.supdate 'submodule update --remote --merge'
 713----
1015 714 
.1016 715This way you can simply run `git supdate` when you want to update your submodules, or `git spush` to push with submodule dependency checking. 
1017  
1018### Superprojects ### 
1019  
1020Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1021  
1022A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1023 716 
.1024### Issues with Submodules ### 717==== Issues with Submodules 
1025 718 
.1026Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 719Using submodules isn’t without hiccups, however. 
1027  
1028To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1029 720 
.1030Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory:721For instance switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory:
1031 722 
. 723[source,console]
 724----
1032    $ git checkout -b rack 725$ git checkout -b add-crypto 
1033    Switched to a new branch "rack" 726Switched to a new branch 'add-crypto' 
 727 
1034    $ git submodule add git@github.com:schacon/rack.git rack 728$ git submodule add https://github.com/chaconinc/CryptoLibrary 
1035    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1036    ... 
1037    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1038    Resolving deltas: 100% (1952/1952), done. 
 729Cloning into 'CryptoLibrary'...
 730...
 731 
1039    $ git commit -am 'added rack submodule'732$ git commit -am 'adding crypto library'
1040    [rack cc49a69] added rack submodule 733[add-crypto 4445836] adding crypto library 
1041     2 files changed, 4 insertions(+), 0 deletions(-)734 2 files changed, 4 insertions(+)
1042     create mode 100644 .gitmodules 
1043     create mode 160000 rack 
 735 create mode 160000 CryptoLibrary
 736 
1044    $ git checkout master737$ git checkout master
 738warning: unable to rmdir CryptoLibrary: Directory not empty
1045    Switched to branch "master" 739Switched to branch 'master' 
 740Your branch is up-to-date with 'origin/master'.
 741 
1046    $ git status742$ git status
1047    # On branch master743On branch master
 744Your branch is up-to-date with 'origin/master'.
 745 
1048    # Untracked files:746Untracked files:
1049    #   (use "git add <file>..." to include in what will be committed)747  (use "git add <file>..." to include in what will be committed)
1050    # 748 
1051    #      rack/749    CryptoLibrary/
1052 750 
. 751nothing added to commit but untracked files present (use "git add" to track)
 752----
1053You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 753 
 754Removing the directory isn't difficult, but it can be a bit confusing to have that in there. If you do remove it and then switch back to the branch that has that submodule, you will need to run `submodule update --init` to repopulate it.
 755 
 756[source,console]
 757----
 758$ git clean -fdx
 759Removing CryptoLibrary/
 760 
 761$ git checkout add-crypto
 762Switched to branch 'add-crypto'
 763 
 764$ ls CryptoLibrary/
 765 
 766$ git submodule update --init
 767Submodule path 'CryptoLibrary': checked out 'b8dda6aa182ea4464f3f3264b11e0268545172af'
 768 
 769$ ls CryptoLibrary/
 770Makefile    includes    scripts     src
 771----
 772 
 773Again, not really very difficult, but it can be a little confusing.
1054 774 
.1055The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you:775The other main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you:
1056 776 
. 777[source,console]
 778----
1057    $ rm -Rf rack/779$ rm -Rf CryptoLibrary/
1058    $ git submodule add git@github.com:schacon/rack.git rack 780$ git submodule add https://github.com/chaconinc/CryptoLibrary 
1059    'rack' already exists in the index781'CryptoLibrary' already exists in the index
 782----
1060 783 
.1061You have to unstage the `rack` directory first. Then you can add the submodule:784You have to unstage the `CryptoLibrary` directory first. Then you can add the submodule:
1062 785 
. 786[source,console]
 787----
1063    $ git rm -r rack 788$ git rm -r CryptoLibrary 
1064    $ git submodule add git@github.com:schacon/rack.git rack 789$ git submodule add https://github.com/chaconinc/CryptoLibrary 
1065    Initialized empty Git repository in /opt/testsub/rack/.git/ 790Cloning into 'CryptoLibrary'... 
1066    remote: Counting objects: 3184, done.791remote: Counting objects: 11, done.
1067    remote: Compressing objects: 100% (1465/1465), done.792remote: Compressing objects: 100% (10/10), done.
1068    remote: Total 3184 (delta 1952), reused 2770 (delta 1675)793remote: Total 11 (delta 0), reused 11 (delta 0)
1069    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done.794Unpacking objects: 100% (11/11), done.
1070    Resolving deltas: 100% (1952/1952), done.795Checking connectivity... done.
 796----
1071 797 
.1072Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule you get this error:798Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule you get this error:
1073 799 
. 800[source,console]
 801----
1074    $ git checkout master802$ git checkout master
1075    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 803error: The following untracked working tree files would be overwritten by checkout: 
 804  CryptoLibrary/Makefile
 805  CryptoLibrary/includes/crypto.h
 806  ...
 807Please move or remove them before you can switch branches.
 808Aborting
 809----
1076 810 
.1077You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1078  
1079    $ mv rack /tmp/ 
1080    $ git checkout master 
1081    Switched to branch "master" 
1082    $ ls 
1083    README  rack 
 811You can force it to switch with `checkout -f`, but be careful that you don't have unsaved changes in there as they could be overwritten with that command.
 812 
 813[source,console]
 814----
 815$ git checkout -f master
 816warning: unable to rmdir CryptoLibrary: Directory not empty
 817Switched to branch 'master'
 818----
1084 819 
.1085Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory.820Then, when you switch back, you get an empty `CryptoLibrary` directory for some reason and `git submodule update` may not fix it either. You may need to go into your submodule directory and run a `git checkout .` to get all your files back. You could run this in a `submodule foreach` script to run it for multiple submodules.
 821 
 822It's important to note that submodules these days keep all their Git data in the top project's `.git` directory, so unlike much older versions of Git, destroying a submodule directory won't lose any commits or branches that you had.
 823 
1086 824With these tools, submodules can be a fairly simple and effective method for developing on several related but still separate projects simultaneously. 
1087## Subtree Merging ## 
1088  
1089Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1090  
1091However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1092  
1093The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing. 
1094  
1095You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch: 
1096  
1097    $ git remote add rack_remote git@github.com:schacon/rack.git 
1098    $ git fetch rack_remote 
1099    warning: no common commits 
1100    remote: Counting objects: 3184, done. 
1101    remote: Compressing objects: 100% (1465/1465), done. 
1102    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1103    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. 
1104    Resolving deltas: 100% (1952/1952), done. 
1105    From git@github.com:schacon/rack 
1106     * [new branch]      build      -> rack_remote/build 
1107     * [new branch]      master     -> rack_remote/master 
1108     * [new branch]      rack-0.4   -> rack_remote/rack-0.4 
1109     * [new branch]      rack-0.9   -> rack_remote/rack-0.9 
1110    $ git checkout -b rack_branch rack_remote/master 
1111    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. 
1112    Switched to a new branch "rack_branch" 
1113  
1114Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots: 
1115  
1116    $ ls 
1117    AUTHORS        KNOWN-ISSUES   Rakefile      contrib        lib 
1118    COPYING        README         bin           example        test 
1119    $ git checkout master 
1120    Switched to branch "master" 
1121    $ ls 
1122    README 
1123  
1124You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: 
1125  
1126    $ git read-tree --prefix=rack/ -u rack_branch 
1127  
1128When you commit, it looks like you have all the Rack files under that subdirectory — as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling: 
1129  
1130    $ git checkout rack_branch 
1131    $ git pull 
1132  
1133Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option: 
1134  
1135    $ git checkout master 
1136    $ git merge --squash -s subtree --no-commit rack_branch 
1137    Squash commit -- not updating HEAD 
1138    Automatic merge went well; stopped before committing as requested 
1139  
1140All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite — make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream. 
1141  
1142To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch — to see if you need to merge them — you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to: 
1143  
1144    $ git diff-tree -p rack_branch 
1145  
1146Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run 
1147  
1148    $ git diff-tree -p rack_remote/master 
1149  
1150## Summary ## 
1151  
1152You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. 
1153 825 
+
+ diff --git a/book/07-git-tools/sections/diff-subtree-merges.htm b/book/07-git-tools/sections/diff-subtree-merges.htm new file mode 100644 index 00000000..87a1f365 --- /dev/null +++ b/book/07-git-tools/sections/diff-subtree-merges.htm @@ -0,0 +1,4815 @@ + + + + +WinMerge File Compare Report + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
C:\Users\15625\Documents\Git\progit\en\06-git-tools\01-chapter6.markdownC:\Users\15625\Documents\Git\progit2-ja\book\07-git-tools\sections\subtree-merges.asc
.1# Git Tools # 1[[_subtree_merge]] 
2  
3By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. 
4  
5Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. 
6  
7## Revision Selection ## 
8  
9Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. 
10  
11### Single Revisions ### 
12  
13You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. 
14  
15### Short SHA ### 
16  
17Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. 
18  
19For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: 
20  
21    $ git log 
22    commit 734713bc047d87bf7eac9674765ae793478c50d3 
23    Author: Scott Chacon <schacon@gmail.com> 
24    Date:   Fri Jan 2 18:32:33 2009 -0800 
25  
26        fixed refs handling, added gc auto, updated tests 
27  
28    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
29    Merge: 1c002dd... 35cfb2b... 
30    Author: Scott Chacon <schacon@gmail.com> 
31    Date:   Thu Dec 11 15:08:43 2008 -0800 
32  
33        Merge commit 'phedders/rdocs' 
34  
35    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
36    Author: Scott Chacon <schacon@gmail.com> 
37    Date:   Thu Dec 11 14:58:32 2008 -0800 
38  
39        added some blame and merge stuff 
40  
41In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): 
42  
43    $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
44    $ git show 1c002dd4b536e7479f 
45    $ git show 1c002d 
46  
47Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: 
48  
49    $ git log --abbrev-commit --pretty=oneline 
50    ca82a6d changed the version number 
51    085bb3b removed unnecessary test code 
52    a11bef0 first commit 
53  
54Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. 
55  
56### A SHORT NOTE ABOUT SHA-1 ### 
57  
58A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? 
59  
60If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. 
61  
62However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. 
63  
64Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. 
65  
66### Branch References ### 
67  
68The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: 
69  
70    $ git show ca82a6dff817ec66f44342007202690a93763949 
71    $ git show topic1 
72  
73If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. 
74  
75    $ git rev-parse topic1 
76    ca82a6dff817ec66f44342007202690a93763949 
77  
78### RefLog Shortnames ### 
79  
80One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. 
81  
82You can see your reflog by using `git reflog`: 
83  
84    $ git reflog 
85    734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated 
86    d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. 
87    1c002dd HEAD@{2}: commit: added some blame and merge stuff 
88    1c36188 HEAD@{3}: rebase -i (squash): updating HEAD 
89    95df984 HEAD@{4}: commit: # This is a combination of two commits. 
90    1c36188 HEAD@{5}: rebase -i (squash): updating HEAD 
91    7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD 
92  
93Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: 
94  
95    $ git show HEAD@{5} 
96  
97You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type 
98  
99    $ git show master@{yesterday} 
100  
101That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. 
102  
103To see reflog information formatted like the `git log` output, you can run `git log -g`: 
104  
105    $ git log -g master 
106    commit 734713bc047d87bf7eac9674765ae793478c50d3 
107    Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) 
108    Reflog message: commit: fixed refs handling, added gc auto, updated 
109    Author: Scott Chacon <schacon@gmail.com> 
110    Date:   Fri Jan 2 18:32:33 2009 -0800 
111  
112        fixed refs handling, added gc auto, updated tests 
113  
114    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
115    Reflog: master@{1} (Scott Chacon <schacon@gmail.com>) 
116    Reflog message: merge phedders/rdocs: Merge made by recursive. 
117    Author: Scott Chacon <schacon@gmail.com> 
118    Date:   Thu Dec 11 15:08:43 2008 -0800 
119  
120        Merge commit 'phedders/rdocs' 
121  
122It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. 
123  
124### Ancestry References ### 
125  
126The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. 
127Suppose you look at the history of your project: 
128  
129    $ git log --pretty=format:'%h %s' --graph 
130    * 734713b fixed refs handling, added gc auto, updated tests 
131    *   d921970 Merge commit 'phedders/rdocs' 
132    |\ 
133    | * 35cfb2b Some rdoc changes 
134    * | 1c002dd added some blame and merge stuff 
135    |/ 
136    * 1c36188 ignore *.gem 
137    * 9b29157 add open3_detach to gemspec file list 
138  
139Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": 
140  
141    $ git show HEAD^ 
142    commit d921970aadf03b3cf0e71becdaab3147ba71cdef 
143    Merge: 1c002dd... 35cfb2b... 
144    Author: Scott Chacon <schacon@gmail.com> 
145    Date:   Thu Dec 11 15:08:43 2008 -0800 
146  
147        Merge commit 'phedders/rdocs' 
148  
149You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: 
150  
151    $ git show d921970^ 
152    commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b 
153    Author: Scott Chacon <schacon@gmail.com> 
154    Date:   Thu Dec 11 14:58:32 2008 -0800 
155  
156        added some blame and merge stuff 
157  
158    $ git show d921970^2 
159    commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 
160    Author: Paul Hedderly <paul+git@mjr.org> 
161    Date:   Wed Dec 10 22:22:03 2008 +0000 
162  
163        Some rdoc changes 
164  
165The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be 
166  
167    $ git show HEAD~3 
168    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
169    Author: Tom Preston-Werner <tom@mojombo.com> 
170    Date:   Fri Nov 7 13:47:59 2008 -0500 
171  
172        ignore *.gem 
173  
174This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: 
175  
176    $ git show HEAD^^^ 
177    commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d 
178    Author: Tom Preston-Werner <tom@mojombo.com> 
179    Date:   Fri Nov 7 13:47:59 2008 -0500 
180  
181        ignore *.gem 
182  
183You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. 
184  
185### Commit Ranges ### 
186  
187Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" 
188  
189#### Double Dot #### 
190  
191The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. 
192  
193Insert 18333fig0601.png 
194Figure 6-1. Example history for range selection. 
195  
196You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: 
197  
198    $ git log master..experiment 
199    D 
200    C 
201  
202If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: 
203  
204    $ git log experiment..master 
205    F 
206    E 
207  
208This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: 
209  
210    $ git log origin/master..HEAD 
211  
212This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. 
213You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. 
214  
215#### Multiple Points #### 
216  
217The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: 
218  
219    $ git log refA..refB 
220    $ git log ^refA refB 
221    $ git log refB --not refA 
222  
223This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: 
224  
225    $ git log refA refB ^refC 
226    $ git log refA refB --not refC 
227  
228This makes for a very powerful revision query system that should help you figure out what is in your branches. 
229  
230#### Triple Dot #### 
231  
232The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. 
233If you want to see what is in `master` or `experiment` but not any common references, you can run 
234  
235    $ git log master...experiment 
236    F 
237    E 
238    D 
239    C 
240  
241Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. 
242  
243A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: 
244  
245    $ git log --left-right master...experiment 
246    < F 
247    < E 
248    > D 
249    > C 
250  
251With these tools, you can much more easily let Git know what commit or commits you want to inspect. 
252  
253## Interactive Staging ## 
254  
255Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. 
256If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: 
257  
258    $ git add -i 
259               staged     unstaged path 
260      1:    unchanged        +0/-1 TODO 
261      2:    unchanged        +1/-1 index.html 
262      3:    unchanged        +5/-1 lib/simplegit.rb 
263  
264    *** Commands *** 
265      1: status     2: update      3: revert     4: add untracked 
266      5: patch      6: diff        7: quit       8: help 
267    What now> 
268  
269You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. 
270  
271After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. 
272  
273### Staging and Unstaging Files ### 
274  
275If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: 
276  
277    What now> 2 
278               staged     unstaged path 
279      1:    unchanged        +0/-1 TODO 
280      2:    unchanged        +1/-1 index.html 
281      3:    unchanged        +5/-1 lib/simplegit.rb 
282    Update>> 
283  
284To stage the TODO and index.html files, you can type the numbers: 
285  
286    Update>> 1,2 
287               staged     unstaged path 
288    * 1:    unchanged        +0/-1 TODO 
289    * 2:    unchanged        +1/-1 index.html 
290      3:    unchanged        +5/-1 lib/simplegit.rb 
291    Update>> 
292  
293The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: 
294  
295    Update>> 
296    updated 2 paths 
297  
298    *** Commands *** 
299      1: status     2: update      3: revert     4: add untracked 
300      5: patch      6: diff        7: quit       8: help 
301    What now> 1 
302               staged     unstaged path 
303      1:        +0/-1      nothing TODO 
304      2:        +1/-1      nothing index.html 
305      3:    unchanged        +5/-1 lib/simplegit.rb 
306  
307Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: 
308  
309    *** Commands *** 
310      1: status     2: update      3: revert     4: add untracked 
311      5: patch      6: diff        7: quit       8: help 
312    What now> 3 
313               staged     unstaged path 
314      1:        +0/-1      nothing TODO 
315      2:        +1/-1      nothing index.html 
316      3:    unchanged        +5/-1 lib/simplegit.rb 
317    Revert>> 1 
318               staged     unstaged path 
319    * 1:        +0/-1      nothing TODO 
320      2:        +1/-1      nothing index.html 
321      3:    unchanged        +5/-1 lib/simplegit.rb 
322    Revert>> [enter] 
323    reverted one path 
324  
325Looking at your Git status again, you can see that you’ve unstaged the TODO file: 
326  
327    *** Commands *** 
328      1: status     2: update      3: revert     4: add untracked 
329      5: patch      6: diff        7: quit       8: help 
330    What now> 1 
331               staged     unstaged path 
332      1:    unchanged        +0/-1 TODO 
333      2:        +1/-1      nothing index.html 
334      3:    unchanged        +5/-1 lib/simplegit.rb 
335  
336To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: 
337  
338    *** Commands *** 
339      1: status     2: update      3: revert     4: add untracked 
340      5: patch      6: diff        7: quit       8: help 
341    What now> 6 
342               staged     unstaged path 
343      1:        +1/-1      nothing index.html 
344    Review diff>> 1 
345    diff --git a/index.html b/index.html 
346    index 4d07108..4335f49 100644 
347    --- a/index.html 
348    +++ b/index.html 
349    @@ -16,7 +16,7 @@ Date Finder 
350  
351     <p id="out">...</p> 
352  
353    -<div id="footer">contact : support@github.com</div> 
354    +<div id="footer">contact : email.support@github.com</div> 
355  
356     <script type="text/javascript"> 
357  
358With these basic commands, you can use the interactive add mode to deal with your staging area a little more easily. 
359  
360### Staging Patches ### 
361  
362It’s also possible for Git to stage certain parts of files and not the rest. For example, if you make two changes to your simplegit.rb file and want to stage one of them and not the other, doing so is very easy in Git. From the interactive prompt, type `5` or `p` (for patch). Git will ask you which files you would like to partially stage; then, for each section of the selected files, it will display hunks of the file diff and ask if you would like to stage them, one by one: 
363  
364    diff --git a/lib/simplegit.rb b/lib/simplegit.rb 
365    index dd5ecc4..57399e0 100644 
366    --- a/lib/simplegit.rb 
367    +++ b/lib/simplegit.rb 
368    @@ -22,7 +22,7 @@ class SimpleGit 
369       end 
370  
371       def log(treeish = 'master') 
372    -    command("git log -n 25 #{treeish}") 
373    +    command("git log -n 30 #{treeish}") 
374       end 
375  
376       def blame(path) 
377    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 
378  
379You have a lot of options at this point. Typing `?` shows a list of what you can do: 
380  
381    Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? 
382    y - stage this hunk 
383    n - do not stage this hunk 
384    a - stage this and all the remaining hunks in the file 
385    d - do not stage this hunk nor any of the remaining hunks in the file 
386    g - select a hunk to go to 
387    / - search for a hunk matching the given regex 
388    j - leave this hunk undecided, see next undecided hunk 
389    J - leave this hunk undecided, see next hunk 
390    k - leave this hunk undecided, see previous undecided hunk 
391    K - leave this hunk undecided, see previous hunk 
392    s - split the current hunk into smaller hunks 
393    e - manually edit the current hunk 
394    ? - print help 
395  
396Generally, you’ll type `y` or `n` if you want to stage each hunk, but staging all of them in certain files or skipping a hunk decision until later can be helpful too. If you stage one part of the file and leave another part unstaged, your status output will look like this: 
397  
398    What now> 1 
399               staged     unstaged path 
400      1:    unchanged        +0/-1 TODO 
401      2:        +1/-1      nothing index.html 
402      3:        +1/-1        +4/-0 lib/simplegit.rb 
403  
404The status of the simplegit.rb file is interesting. It shows you that a couple of lines are staged and a couple are unstaged. You’ve partially staged this file. At this point, you can exit the interactive adding script and run `git commit` to commit the partially staged files. 
405  
406Finally, you don’t need to be in interactive add mode to do the partial-file staging — you can start the same script by using `git add -p` or `git add --patch` on the command line. 
407  
408## Stashing ## 
409  
410Often, when you’ve been working on part of your project, things are in a messy state and you want to switch branches for a bit to work on something else. The problem is, you don’t want to do a commit of half-done work just so you can get back to this point later. The answer to this issue is the `git stash` command. 
411  
412Stashing takes the dirty state of your working directory — that is, your modified tracked files and staged changes — and saves it on a stack of unfinished changes that you can reapply at any time. 
413  
414### Stashing Your Work ### 
415  
416To demonstrate, you’ll go into your project and start working on a couple of files and possibly stage one of the changes. If you run `git status`, you can see your dirty state: 
417  
418    $ git status 
419    # On branch master 
420    # Changes to be committed: 
421    #   (use "git reset HEAD <file>..." to unstage) 
422    # 
423    #      modified:   index.html 
424    # 
425    # Changes not staged for commit: 
426    #   (use "git add <file>..." to update what will be committed) 
427    # 
428    #      modified:   lib/simplegit.rb 
429    # 
430  
431Now you want to switch branches, but you don’t want to commit what you’ve been working on yet; so you’ll stash the changes. To push a new stash onto your stack, run `git stash`: 
432  
433    $ git stash 
434    Saved working directory and index state \ 
435      "WIP on master: 049d078 added the index file" 
436    HEAD is now at 049d078 added the index file 
437    (To restore them type "git stash apply") 
438  
439Your working directory is clean: 
440  
441    $ git status 
442    # On branch master 
443    nothing to commit, working directory clean 
444  
445At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: 
446  
447    $ git stash list 
448    stash@{0}: WIP on master: 049d078 added the index file 
449    stash@{1}: WIP on master: c264051 Revert "added file_size" 
450    stash@{2}: WIP on master: 21d80a5 added number to log 
451  
452In this case, two stashes were done previously, so you have access to three different stashed works. You can reapply the one you just stashed by using the command shown in the help output of the original stash command: `git stash apply`. If you want to apply one of the older stashes, you can specify it by naming it, like this: `git stash apply stash@{2}`. If you don’t specify a stash, Git assumes the most recent stash and tries to apply it: 
453  
454    $ git stash apply 
455    # On branch master 
456    # Changes not staged for commit: 
457    #   (use "git add <file>..." to update what will be committed) 
458    # 
459    #      modified:   index.html 
460    #      modified:   lib/simplegit.rb 
461    # 
462  
463You can see that Git re-modifies the files you uncommitted when you saved the stash. In this case, you had a clean working directory when you tried to apply the stash, and you tried to apply it on the same branch you saved it from; but having a clean working directory and applying it on the same branch aren’t necessary to successfully apply a stash. You can save a stash on one branch, switch to another branch later, and try to reapply the changes. You can also have modified and uncommitted files in your working directory when you apply a stash — Git gives you merge conflicts if anything no longer applies cleanly. 
464  
465The changes to your files were reapplied, but the file you staged before wasn’t restaged. To do that, you must run the `git stash apply` command with a `--index` option to tell the command to try to reapply the staged changes. If you had run that instead, you’d have gotten back to your original position: 
466  
467    $ git stash apply --index 
468    # On branch master 
469    # Changes to be committed: 
470    #   (use "git reset HEAD <file>..." to unstage) 
471    # 
472    #      modified:   index.html 
473    # 
474    # Changes not staged for commit: 
475    #   (use "git add <file>..." to update what will be committed) 
476    # 
477    #      modified:   lib/simplegit.rb 
478    # 
479  
480The apply option only tries to apply the stashed work — you continue to have it on your stack. To remove it, you can run `git stash drop` with the name of the stash to remove: 
481  
482    $ git stash list 
483    stash@{0}: WIP on master: 049d078 added the index file 
484    stash@{1}: WIP on master: c264051 Revert "added file_size" 
485    stash@{2}: WIP on master: 21d80a5 added number to log 
486    $ git stash drop stash@{0} 
487    Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) 
488  
489You can also run `git stash pop` to apply the stash and then immediately drop it from your stack. 
490  
491### Un-applying a Stash ### 
492  
493In some use case scenarios you might want to apply stashed changes, do some work, but then un-apply those changes that originally came from the stash. Git does not provide such a `stash unapply` command, but it is possible to achieve the effect by simply retrieving the patch associated with a stash and applying it in reverse: 
494  
495    $ git stash show -p stash@{0} | git apply -R 
496  
497Again, if you don’t specify a stash, Git assumes the most recent stash: 
498  
499    $ git stash show -p | git apply -R 
500  
501You may want to create an alias and effectively add a `stash-unapply` command to your Git. For example: 
502  
503    $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
504    $ git stash apply 
505    $ #... work work work 
506    $ git stash-unapply 
507  
508### Creating a Branch from a Stash ### 
509  
510If you stash some work, leave it there for a while, and continue on the branch from which you stashed the work, you may have a problem reapplying the work. If the apply tries to modify a file that you’ve since modified, you’ll get a merge conflict and will have to try to resolve it. If you want an easier way to test the stashed changes again, you can run `git stash branch`, which creates a new branch for you, checks out the commit you were on when you stashed your work, reapplies your work there, and then drops the stash if it applies successfully: 
511  
512    $ git stash branch testchanges 
513    Switched to a new branch "testchanges" 
514    # On branch testchanges 
515    # Changes to be committed: 
516    #   (use "git reset HEAD <file>..." to unstage) 
517    # 
518    #      modified:   index.html 
519    # 
520    # Changes not staged for commit: 
521    #   (use "git add <file>..." to update what will be committed) 
522    # 
523    #      modified:   lib/simplegit.rb 
524    # 
525    Dropped refs/stash@{0} (f0dfc4d5dc332d1cee34a634182e168c4efc3359) 
526  
527This is a nice shortcut to recover stashed work easily and work on it in a new branch. 
528  
529## Rewriting History ## 
530  
531Many times, when working with Git, you may want to revise your commit history for some reason. One of the great things about Git is that it allows you to make decisions at the last possible moment. You can decide what files go into which commits right before you commit with the staging area, you can decide that you didn’t mean to be working on something yet with the stash command, and you can rewrite commits that already happened so they look like they happened in a different way. This can involve changing the order of the commits, changing messages or modifying files in a commit, squashing together or splitting apart commits, or removing commits entirely — all before you share your work with others. 
532  
533In this section, you’ll cover how to accomplish these very useful tasks so that you can make your commit history look the way you want before you share it with others. 
534  
535### Changing the Last Commit ### 
536  
537Changing your last commit is probably the most common rewriting of history that you’ll do. You’ll often want to do two basic things to your last commit: change the commit message, or change the snapshot you just recorded by adding, changing and removing files. 
538  
539If you only want to modify your last commit message, it’s very simple: 
540  
541    $ git commit --amend 
542  
543That drops you into your text editor, which has your last commit message in it, ready for you to modify the message. When you save and close the editor, the editor writes a new commit containing that message and makes it your new last commit. 
544  
545If you’ve committed and then you want to change the snapshot you committed by adding or changing files, possibly because you forgot to add a newly created file when you originally committed, the process works basically the same way. You stage the changes you want by editing a file and running `git add` on it or `git rm` to a tracked file, and the subsequent `git commit --amend` takes your current staging area and makes it the snapshot for the new commit. 
546  
547You need to be careful with this technique because amending changes the SHA-1 of the commit. It’s like a very small rebase — don’t amend your last commit if you’ve already pushed it. 
548  
549### Changing Multiple Commit Messages ### 
550  
551To modify a commit that is farther back in your history, you must move to more complex tools. Git doesn’t have a modify-history tool, but you can use the rebase tool to rebase a series of commits onto the HEAD they were originally based on instead of moving them to another one. With the interactive rebase tool, you can then stop after each commit you want to modify and change the message, add files, or do whatever you wish. You can run rebase interactively by adding the `-i` option to `git rebase`. You must indicate how far back you want to rewrite commits by telling the command which commit to rebase onto. 
552  
553For example, if you want to change the last three commit messages, or any of the commit messages in that group, you supply as an argument to `git rebase -i` the parent of the last commit you want to edit, which is `HEAD~2^` or `HEAD~3`. It may be easier to remember the `~3` because you’re trying to edit the last three commits; but keep in mind that you’re actually designating four commits ago, the parent of the last commit you want to edit: 
554  
555    $ git rebase -i HEAD~3 
556  
557Remember again that this is a rebasing command — every commit included in the range `HEAD~3..HEAD` will be rewritten, whether you change the message or not. Don’t include any commit you’ve already pushed to a central server — doing so will confuse other developers by providing an alternate version of the same change. 
558  
559Running this command gives you a list of commits in your text editor that looks something like this: 
560  
561    pick f7f3f6d changed my name a bit 
562    pick 310154e updated README formatting and added blame 
563    pick a5f4a0d added cat-file 
564  
565    # Rebase 710f0f8..a5f4a0d onto 710f0f8 
566    # 
567    # Commands: 
568    #  p, pick = use commit 
569    #  r, reword = use commit, but edit the commit message 
570    #  e, edit = use commit, but stop for amending 
571    #  s, squash = use commit, but meld into previous commit 
572    #  f, fixup = like "squash", but discard this commit's log message 
573    #  x, exec = run command (the rest of the line) using shell 
574    # 
575    # These lines can be re-ordered; they are executed from top to bottom. 
576    # 
577    # If you remove a line here THAT COMMIT WILL BE LOST. 
578    # 
579    # However, if you remove everything, the rebase will be aborted. 
580    # 
581    # Note that empty commits are commented out 
582  
583It’s important to note that these commits are listed in the opposite order than you normally see them using the `log` command. If you run a `log`, you see something like this: 
584  
585    $ git log --pretty=format:"%h %s" HEAD~3..HEAD 
586    a5f4a0d added cat-file 
587    310154e updated README formatting and added blame 
588    f7f3f6d changed my name a bit 
589  
590Notice the reverse order. The interactive rebase gives you a script that it’s going to run. It will start at the commit you specify on the command line (`HEAD~3`) and replay the changes introduced in each of these commits from top to bottom. It lists the oldest at the top, rather than the newest, because that’s the first one it will replay. 
591  
592You need to edit the script so that it stops at the commit you want to edit. To do so, change the word pick to the word edit for each of the commits you want the script to stop after. For example, to modify only the third commit message, you change the file to look like this: 
593  
594    edit f7f3f6d changed my name a bit 
595    pick 310154e updated README formatting and added blame 
596    pick a5f4a0d added cat-file 
597  
598When you save and exit the editor, Git rewinds you back to the last commit in that list and drops you on the command line with the following message: 
599  
600<!-- This is actually weird, as the SHA-1 of 7482e0d is not present in the list,  
601nor is the commit message. Please review  
602--> 
603  
604    $ git rebase -i HEAD~3 
605    Stopped at 7482e0d... updated the gemspec to hopefully work better 
606    You can amend the commit now, with 
607  
608           git commit --amend 
609  
610    Once you’re satisfied with your changes, run 
611  
612           git rebase --continue 
613  
614These instructions tell you exactly what to do. Type 
615  
616    $ git commit --amend 
617  
618Change the commit message, and exit the editor. Then, run 
619  
620    $ git rebase --continue 
621  
622This command will apply the other two commits automatically, and then you’re done. If you change pick to edit on more lines, you can repeat these steps for each commit you change to edit. Each time, Git will stop, let you amend the commit, and continue when you’re finished. 
623  
624### Reordering Commits ### 
625  
626You can also use interactive rebases to reorder or remove commits entirely. If you want to remove the "added cat-file" commit and change the order in which the other two commits are introduced, you can change the rebase script from this 
627  
628    pick f7f3f6d changed my name a bit 
629    pick 310154e updated README formatting and added blame 
630    pick a5f4a0d added cat-file 
631  
632to this: 
633  
634    pick 310154e updated README formatting and added blame 
635    pick f7f3f6d changed my name a bit 
636  
637When you save and exit the editor, Git rewinds your branch to the parent of these commits, applies `310154e` and then `f7f3f6d`, and then stops. You effectively change the order of those commits and remove the "added cat-file" commit completely. 
638  
639### Squashing Commits ### 
640  
641It’s also possible to take a series of commits and squash them down into a single commit with the interactive rebasing tool. The script puts helpful instructions in the rebase message: 
642  
643    # 
644    # Commands: 
645    #  p, pick = use commit 
646    #  r, reword = use commit, but edit the commit message 
647    #  e, edit = use commit, but stop for amending 
648    #  s, squash = use commit, but meld into previous commit 
649    #  f, fixup = like "squash", but discard this commit's log message 
650    #  x, exec = run command (the rest of the line) using shell 
651    # 
652    # These lines can be re-ordered; they are executed from top to bottom. 
653    # 
654    # If you remove a line here THAT COMMIT WILL BE LOST. 
655    # 
656    # However, if you remove everything, the rebase will be aborted. 
657    # 
658    # Note that empty commits are commented out 
659  
660If, instead of "pick" or "edit", you specify "squash", Git applies both that change and the change directly before it and makes you merge the commit messages together. So, if you want to make a single commit from these three commits, you make the script look like this: 
661  
662    pick f7f3f6d changed my name a bit 
663    squash 310154e updated README formatting and added blame 
664    squash a5f4a0d added cat-file 
665  
666When you save and exit the editor, Git applies all three changes and then puts you back into the editor to merge the three commit messages: 
667  
668    # This is a combination of 3 commits. 
669    # The first commit's message is: 
670    changed my name a bit 
671  
672    # This is the 2nd commit message: 
673  
674    updated README formatting and added blame 
675  
676    # This is the 3rd commit message: 
677  
678    added cat-file 
679  
680When you save that, you have a single commit that introduces the changes of all three previous commits. 
681  
682### Splitting a Commit ### 
683  
684Splitting a commit undoes a commit and then partially stages and commits as many times as commits you want to end up with. For example, suppose you want to split the middle commit of your three commits. Instead of "updated README formatting and added blame", you want to split it into two commits: "updated README formatting" for the first, and "added blame" for the second. You can do that in the `rebase -i` script by changing the instruction on the commit you want to split to "edit": 
685  
686    pick f7f3f6d changed my name a bit 
687    edit 310154e updated README formatting and added blame 
688    pick a5f4a0d added cat-file 
689  
690When you save and exit the editor, Git rewinds to the parent of the first commit in your list, applies the first commit (`f7f3f6d`), applies the second (`310154e`), and drops you to the console. There, you can do a mixed reset of that commit with `git reset HEAD^`, which effectively undoes that commit and leaves the modified files unstaged. Now you can take the changes that have been reset, and create multiple commits out of them. Simply stage and commit files until you have several commits, and run `git rebase --continue` when you’re done: 
691  
692    $ git reset HEAD^ 
693    $ git add README 
694    $ git commit -m 'updated README formatting' 
695    $ git add lib/simplegit.rb 
696    $ git commit -m 'added blame' 
697    $ git rebase --continue 
698  
699Git applies the last commit (`a5f4a0d`) in the script, and your history looks like this: 
700  
701    $ git log -4 --pretty=format:"%h %s" 
702    1c002dd added cat-file 
703    9b29157 added blame 
704    35cfb2b updated README formatting 
705    f3cc40e changed my name a bit 
706  
707Once again, this changes the SHAs of all the commits in your list, so make sure no commit shows up in that list that you’ve already pushed to a shared repository. 
708  
709### The Nuclear Option: filter-branch ### 
710  
711There is another history-rewriting option that you can use if you need to rewrite a larger number of commits in some scriptable way — for instance, changing your e-mail address globally or removing a file from every commit.  The command is `filter-branch`, and it can rewrite huge swaths of your history, so you probably shouldn’t use it unless your project isn’t yet public and other people haven’t based work off the commits you’re about to rewrite.  However, it can be very useful. You’ll learn a few of the common uses so you can get an idea of some of the things it’s capable of. 
712  
713#### Removing a File from Every Commit #### 
714  
715This occurs fairly commonly. Someone accidentally commits a huge binary file with a thoughtless `git add .`, and you want to remove it everywhere. Perhaps you accidentally committed a file that contained a password, and you want to make your project open source. `filter-branch` is the tool you probably want to use to scrub your entire history. To remove a file named passwords.txt from your entire history, you can use the `--tree-filter` option to `filter-branch`: 
716  
717    $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD 
718    Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) 
719    Ref 'refs/heads/master' was rewritten 
720  
721The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "rm -f *~" HEAD`. 
722  
723You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. 
724  
725#### Making a Subdirectory the New Root #### 
726  
727Suppose you’ve done an import from another source control system and have subdirectories that make no sense (trunk, tags, and so on). If you want to make the `trunk` subdirectory be the new project root for every commit, `filter-branch` can help you do that, too: 
728  
729    $ git filter-branch --subdirectory-filter trunk HEAD 
730    Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) 
731    Ref 'refs/heads/master' was rewritten 
732  
733Now your new project root is what was in the `trunk` subdirectory each time. Git will also automatically remove commits that did not affect the subdirectory. 
734  
735#### Changing E-Mail Addresses Globally #### 
736  
737Another common case is that you forgot to run `git config` to set your name and e-mail address before you started working, or perhaps you want to open-source a project at work and change all your work e-mail addresses to your personal address. In any case, you can change e-mail addresses in multiple commits in a batch with `filter-branch` as well. You need to be careful to change only the e-mail addresses that are yours, so you use `--commit-filter`: 
738  
739    $ git filter-branch --commit-filter ' 
740            if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; 
741            then 
742                    GIT_AUTHOR_NAME="Scott Chacon"; 
743                    GIT_AUTHOR_EMAIL="schacon@example.com"; 
744                    git commit-tree "$@"; 
745            else 
746                    git commit-tree "$@"; 
747            fi' HEAD 
748  
749This goes through and rewrites every commit to have your new address. Because commits contain the SHA-1 values of their parents, this command changes every commit SHA in your history, not just those that have the matching e-mail address. 
750  
751### The Very Fast Nuclear Option: Big Friendly Giant Repo Cleaner (BFG) ### 
752  
753[Roberto Tyley](https://github.com/rtyley) has written a similar tool to `filter-branch` called the BFG. BFG cannot do as much as `filter-branch`, but it is _very_ fast and on a large repository this can make a big difference. If the change you want to make is in the scope of BFG capability, and you have performance issues, then you should consider using it. 
754  
755See the [BFG](http://rtyley.github.io/bfg-repo-cleaner/) website for details. 
756  
757## Debugging with Git ## 
758  
759Git also provides a couple of tools to help you debug issues in your projects. Because Git is designed to work with nearly any type of project, these tools are pretty generic, but they can often help you hunt for a bug or culprit when things go wrong. 
760  
761### File Annotation ### 
762  
763If you track down a bug in your code and want to know when it was introduced and why, file annotation is often your best tool. It shows you what commit was the last to modify each line of any file. So, if you see that a method in your code is buggy, you can annotate the file with `git blame` to see when each line of the method was last edited and by whom. This example uses the `-L` option to limit the output to lines 12 through 22: 
764  
765    $ git blame -L 12,22 simplegit.rb 
766    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 12)  def show(tree = 'master') 
767    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 13)   command("git show #{tree}") 
768    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 14)  end 
769    ^4832fe2 (Scott Chacon  2008-03-15 10:31:28 -0700 15) 
770    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 16)  def log(tree = 'master') 
771    79eaf55d (Scott Chacon  2008-04-06 10:15:08 -0700 17)   command("git log #{tree}") 
772    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 18)  end 
773    9f6560e4 (Scott Chacon  2008-03-17 21:52:20 -0700 19) 
774    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20)  def blame(path) 
775    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21)   command("git blame #{path}") 
776    42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22)  end 
777  
778Notice that the first field is the partial SHA-1 of the commit that last modified that line. The next two fields are values extracted from that commit—the author name and the authored date of that commit — so you can easily see who modified that line and when. After that come the line number and the content of the file. Also note the `^4832fe2` commit lines, which designate that those lines were in this file’s original commit. That commit is when this file was first added to this project, and those lines have been unchanged since. This is a tad confusing, because now you’ve seen at least three different ways that Git uses the `^` to modify a commit SHA, but that is what it means here. 
779  
780Another cool thing about Git is that it doesn’t track file renames explicitly. It records the snapshots and then tries to figure out what was renamed implicitly, after the fact. One of the interesting features of this is that you can ask it to figure out all sorts of code movement as well. If you pass `-C` to `git blame`, Git analyzes the file you’re annotating and tries to figure out where snippets of code within it originally came from if they were copied from elsewhere. Recently, I was refactoring a file named `GITServerHandler.m` into multiple files, one of which was `GITPackUpload.m`. By blaming `GITPackUpload.m` with the `-C` option, I could see where sections of the code originally came from: 
781  
782    $ git blame -C -L 141,153 GITPackUpload.m 
783    f344f58d GITServerHandler.m (Scott 2009-01-04 141) 
784    f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC 
785    f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 
786    70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI 
787    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145) 
788    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha; 
789    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g 
790    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148) 
791    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI 
792    ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150) 
793    56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) { 
794    56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb 
795    56ef2caf GITServerHandler.m (Scott 2009-01-05 153) 
796  
797This is really useful. Normally, you get as the original commit the commit where you copied the code over, because that is the first time you touched those lines in this file. Git tells you the original commit where you wrote those lines, even if it was in another file. 
798  
799### Binary Search ### 
800  
801Annotating a file helps if you know where the issue is to begin with. If you don’t know what is breaking, and there have been dozens or hundreds of commits since the last state where you know the code worked, you’ll likely turn to `git bisect` for help. The `bisect` command does a binary search through your commit history to help you identify as quickly as possible which commit introduced an issue. 
802  
803Let’s say you just pushed out a release of your code to a production environment, you’re getting bug reports about something that wasn’t happening in your development environment, and you can’t imagine why the code is doing that. You go back to your code, and it turns out you can reproduce the issue, but you can’t figure out what is going wrong. You can bisect the code to find out. First you run `git bisect start` to get things going, and then you use `git bisect bad` to tell the system that the current commit you’re on is broken. Then, you must tell bisect when the last known good state was, using `git bisect good [good_commit]`: 
804  
805    $ git bisect start 
806    $ git bisect bad 
807    $ git bisect good v1.0 
808    Bisecting: 6 revisions left to test after this 
809    [ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo 
810  
811Git figured out that about 12 commits came between the commit you marked as the last good commit (v1.0) and the current bad version, and it checked out the middle one for you. At this point, you can run your test to see if the issue exists as of this commit. If it does, then it was introduced sometime before this middle commit; if it doesn’t, then the problem was introduced sometime after the middle commit. It turns out there is no issue here, and you tell Git that by typing `git bisect good` and continue your journey: 
812  
813    $ git bisect good 
814    Bisecting: 3 revisions left to test after this 
815    [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing 
816  
817Now you’re on another commit, halfway between the one you just tested and your bad commit. You run your test again and find that this commit is broken, so you tell Git that with `git bisect bad`: 
818  
819    $ git bisect bad 
820    Bisecting: 1 revisions left to test after this 
821    [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table 
822  
823This commit is fine, and now Git has all the information it needs to determine where the issue was introduced. It tells you the SHA-1 of the first bad commit and show some of the commit information and which files were modified in that commit so you can figure out what happened that may have introduced this bug: 
824  
825    $ git bisect good 
826    b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit 
827    commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 
828    Author: PJ Hyett <pjhyett@example.com> 
829    Date:   Tue Jan 27 14:48:32 2009 -0800 
830  
831        secure this thing 
832  
833    :040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730 
834    f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config 
835  
836When you’re finished, you should run `git bisect reset` to reset your HEAD to where you were before you started, or you’ll end up in a weird state: 
837  
838    $ git bisect reset 
839  
840This is a powerful tool that can help you check hundreds of commits for an introduced bug in minutes. In fact, if you have a script that will exit 0 if the project is good or non-0 if the project is bad, you can fully automate `git bisect`. First, you again tell it the scope of the bisect by providing the known bad and good commits. You can do this by listing them with the `bisect start` command if you want, listing the known bad commit first and the known good commit second: 
841  
842    $ git bisect start HEAD v1.0 
843    $ git bisect run test-error.sh 
844  
845Doing so automatically runs `test-error.sh` on each checked-out commit until Git finds the first broken commit. You can also run something like `make` or `make tests` or whatever you have that runs automated tests for you. 
846  
847## Submodules ## 
848  
849It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other. 
850  
851Here’s an example. Suppose you’re developing a web site and creating Atom feeds. Instead of writing your own Atom-generating code, you decide to use a library. You’re likely to have to either include this code from a shared library like a CPAN install or Ruby gem, or copy the source code into your own project tree. The issue with including the library is that it’s difficult to customize the library in any way and often more difficult to deploy it, because you need to make sure every client has that library available. The issue with vendoring the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available. 
852  
853Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate. 
854  
855### Starting with Submodules ### 
856  
857Suppose you want to add the Rack library (a Ruby web server gateway interface) to your project, possibly maintain your own changes to it, but continue to merge in upstream changes. The first thing you should do is clone the external repository into your subdirectory. You add external projects as submodules with the `git submodule add` command: 
858  
859    $ git submodule add git://github.com/chneukirchen/rack.git rack 
860    Initialized empty Git repository in /opt/subtest/rack/.git/ 
861    remote: Counting objects: 3181, done. 
862    remote: Compressing objects: 100% (1534/1534), done. 
863    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
864    Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. 
865    Resolving deltas: 100% (1951/1951), done. 
866  
867Now you have the Rack project under a subdirectory named `rack` within your project. You can go into that subdirectory, make changes, add your own writable remote repository to push your changes into, fetch and merge from the original repository, and more. If you run `git status` right after you add the submodule, you see two things: 
868  
869    $ git status 
870    # On branch master 
871    # Changes to be committed: 
872    #   (use "git reset HEAD <file>..." to unstage) 
873    # 
874    #      new file:   .gitmodules 
875    #      new file:   rack 
876    # 
877  
878First you notice the `.gitmodules` file. This is a configuration file that stores the mapping between the project’s URL and the local subdirectory you’ve pulled it into: 
879  
880    $ cat .gitmodules 
881    [submodule "rack"] 
882          path = rack 
883          url = git://github.com/chneukirchen/rack.git 
884  
885If you have multiple submodules, you’ll have multiple entries in this file. It’s important to note that this file is version-controlled with your other files, like your `.gitignore` file. It’s pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from. 
886  
887The other listing in the `git status` output is the rack entry. If you run `git diff` on that, you see something interesting: 
888  
889    $ git diff --cached rack 
890    diff --git a/rack b/rack 
891    new file mode 160000 
892    index 0000000..08d709f 
893    --- /dev/null 
894    +++ b/rack 
895    @@ -0,0 +1 @@ 
896    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
897  
898Although `rack` is a subdirectory in your working directory, Git sees it as a submodule and doesn’t track its contents when you’re not in that directory. Instead, Git records it as a particular commit from that repository. When you make changes and commit in that subdirectory, the superproject notices that the HEAD there has changed and records the exact commit you’re currently working off of; that way, when others clone this project, they can re-create the environment exactly. 
899  
900This is an important point with submodules: you record them as the exact commit they’re at. You can’t record a submodule at `master` or some other symbolic reference. 
901  
902When you commit, you see something like this: 
903  
904    $ git commit -m 'first commit with submodule rack' 
905    [master 0550271] first commit with submodule rack 
906     2 files changed, 4 insertions(+), 0 deletions(-) 
907     create mode 100644 .gitmodules 
908     create mode 160000 rack 
909  
910Notice the 160000 mode for the rack entry. That is a special mode in Git that basically means you’re recording a commit as a directory entry rather than a subdirectory or a file. 
911  
912You can treat the `rack` directory as a separate project and then update your superproject from time to time with a pointer to the latest commit in that subproject. All the Git commands work independently in the two directories: 
913  
914    $ git log -1 
915    commit 0550271328a0038865aad6331e620cd7238601bb 
916    Author: Scott Chacon <schacon@gmail.com> 
917    Date:   Thu Apr 9 09:03:56 2009 -0700 
918  
919        first commit with submodule rack 
920    $ cd rack/ 
921    $ git log -1 
922    commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
923    Author: Christian Neukirchen <chneukirchen@gmail.com> 
924    Date:   Wed Mar 25 14:49:04 2009 +0100 
925  
926        Document version change 
927  
928### Cloning a Project with Submodules ### 
929  
930Here you’ll clone a project with a submodule in it. When you receive such a project, you get the directories that contain submodules, but none of the files yet: 
931  
932    $ git clone git://github.com/schacon/myproject.git 
933    Initialized empty Git repository in /opt/myproject/.git/ 
934    remote: Counting objects: 6, done. 
935    remote: Compressing objects: 100% (4/4), done. 
936    remote: Total 6 (delta 0), reused 0 (delta 0) 
937    Receiving objects: 100% (6/6), done. 
938    $ cd myproject 
939    $ ls -l 
940    total 8 
941    -rw-r--r--  1 schacon  admin   3 Apr  9 09:11 README 
942    drwxr-xr-x  2 schacon  admin  68 Apr  9 09:11 rack 
943    $ ls rack/ 
944    $ 
945  
946The `rack` directory is there, but empty. You must run two commands: `git submodule init` to initialize your local configuration file, and `git submodule update` to fetch all the data from that project and check out the appropriate commit listed in your superproject: 
947  
948    $ git submodule init 
949    Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' 
950    $ git submodule update 
951    Initialized empty Git repository in /opt/myproject/rack/.git/ 
952    remote: Counting objects: 3181, done. 
953    remote: Compressing objects: 100% (1534/1534), done. 
954    remote: Total 3181 (delta 1951), reused 2623 (delta 1603) 
955    Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. 
956    Resolving deltas: 100% (1951/1951), done. 
957    Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' 
958  
959Now your `rack` subdirectory is at the exact state it was in when you committed earlier. If another developer makes changes to the rack code and commits, and you pull that reference down and merge it in, you get something a bit odd: 
960  
961    $ git merge origin/master 
962    Updating 0550271..85a3eee 
963    Fast forward 
964     rack |    2 +- 
965     1 files changed, 1 insertions(+), 1 deletions(-) 
966    [master*]$ git status 
967    # On branch master 
968    # Changes not staged for commit: 
969    #   (use "git add <file>..." to update what will be committed) 
970    #   (use "git checkout -- <file>..." to discard changes in working directory) 
971    # 
972    #      modified:   rack 
973    # 
974  
975You merged in what is basically a change to the pointer for your submodule; but it doesn’t update the code in the submodule directory, so it looks like you have a dirty state in your working directory: 
976  
977    $ git diff 
978    diff --git a/rack b/rack 
979    index 6c5e70b..08d709f 160000 
980    --- a/rack 
981    +++ b/rack 
982    @@ -1 +1 @@ 
983    -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
984    +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 
985  
986This is the case because the pointer you have for the submodule isn’t what is actually in the submodule directory. To fix this, you must run `git submodule update` again: 
987  
988    $ git submodule update 
989    remote: Counting objects: 5, done. 
990    remote: Compressing objects: 100% (3/3), done. 
991    remote: Total 3 (delta 1), reused 2 (delta 0) 
992    Unpacking objects: 100% (3/3), done. 
993    From git@github.com:schacon/rack 
994       08d709f..6c5e70b  master     -> origin/master 
995    Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' 
996  
997You have to do this every time you pull down a submodule change in the main project. It’s strange, but it works. 
998  
999One common problem happens when a developer makes a change locally in a submodule but doesn’t push it to a public server. Then, they commit a pointer to that non-public state and push up the superproject. When other developers try to run `git submodule update`, the submodule system can’t find the commit that is referenced, because it exists only on the first developer’s system. If that happens, you see an error like this: 
1000  
1001    $ git submodule update 
1002    fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 
1003    Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' 
1004  
1005You have to see who last changed the submodule: 
1006  
1007    $ git log -1 rack 
1008    commit 85a3eee996800fcfa91e2119372dd4172bf76678 
1009    Author: Scott Chacon <schacon@gmail.com> 
1010    Date:   Thu Apr 9 09:19:14 2009 -0700 
1011  
1012        added a submodule reference I will never make public. hahahahaha! 
1013  
1014Then, you e-mail that guy and yell at him. 
1015  
1016### Superprojects ### 
1017  
1018Sometimes, developers want to get a combination of a large project’s subdirectories, depending on what team they’re on. This is common if you’re coming from CVS or Subversion, where you’ve defined a module or collection of subdirectories, and you want to keep this type of workflow. 
1019  
1020A good way to do this in Git is to make each of the subdirectories a separate Git repository and then create superproject Git repositories that contain multiple submodules. A benefit of this approach is that you can more specifically define the relationships between the projects with tags and branches in the superprojects. 
1021  
1022### Issues with Submodules ### 
1023  
1024Using submodules isn’t without hiccups, however. First, you must be relatively careful when working in the submodule directory. When you run `git submodule update`, it checks out the specific version of the project, but not within a branch. This is called having a detached HEAD — it means the HEAD file points directly to a commit, not to a symbolic reference. The issue is that you generally don’t want to work in a detached HEAD environment, because it’s easy to lose changes. If you do an initial `submodule update`, commit in that submodule directory without creating a branch to work in, and then run `git submodule update` again from the superproject without committing in the meantime, Git will overwrite your changes without telling you.  Technically you won’t lose the work, but you won’t have a branch pointing to it, so it will be somewhat difficult to retrieve. 
1025  
1026To avoid this issue, create a branch when you work in a submodule directory with `git checkout -b work` or something equivalent. When you do the submodule update a second time, it will still revert your work, but at least you have a pointer to get back to. 
1027  
1028Switching branches with submodules in them can also be tricky. If you create a new branch, add a submodule there, and then switch back to a branch without that submodule, you still have the submodule directory as an untracked directory: 
1029  
1030    $ git checkout -b rack 
1031    Switched to a new branch "rack" 
1032    $ git submodule add git@github.com:schacon/rack.git rack 
1033    Initialized empty Git repository in /opt/myproj/rack/.git/ 
1034    ... 
1035    Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. 
1036    Resolving deltas: 100% (1952/1952), done. 
1037    $ git commit -am 'added rack submodule' 
1038    [rack cc49a69] added rack submodule 
1039     2 files changed, 4 insertions(+), 0 deletions(-) 
1040     create mode 100644 .gitmodules 
1041     create mode 160000 rack 
1042    $ git checkout master 
1043    Switched to branch "master" 
1044    $ git status 
1045    # On branch master 
1046    # Untracked files: 
1047    #   (use "git add <file>..." to include in what will be committed) 
1048    # 
1049    #      rack/ 
1050  
1051You have to either move it out of the way or remove it, in which case you have to clone it again when you switch back—and you may lose local changes or branches that you didn’t push up. 
1052  
1053The last main caveat that many people run into involves switching from subdirectories to submodules. If you’ve been tracking files in your project and you want to move them out into a submodule, you must be careful or Git will get angry at you. Assume that you have the rack files in a subdirectory of your project, and you want to switch it to a submodule. If you delete the subdirectory and then run `submodule add`, Git yells at you: 
1054  
1055    $ rm -Rf rack/ 
1056    $ git submodule add git@github.com:schacon/rack.git rack 
1057    'rack' already exists in the index 
1058  
1059You have to unstage the `rack` directory first. Then you can add the submodule: 
1060  
1061    $ git rm -r rack 
1062    $ git submodule add git@github.com:schacon/rack.git rack 
1063    Initialized empty Git repository in /opt/testsub/rack/.git/ 
1064    remote: Counting objects: 3184, done. 
1065    remote: Compressing objects: 100% (1465/1465), done. 
1066    remote: Total 3184 (delta 1952), reused 2770 (delta 1675) 
1067    Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. 
1068    Resolving deltas: 100% (1952/1952), done. 
1069  
1070Now suppose you did that in a branch. If you try to switch back to a branch where those files are still in the actual tree rather than a submodule — you get this error: 
1071  
1072    $ git checkout master 
1073    error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. 
1074  
1075You have to move the `rack` submodule directory out of the way before you can switch to a branch that doesn’t have it: 
1076  
1077    $ mv rack /tmp/ 
1078    $ git checkout master 
1079    Switched to branch "master" 
1080    $ ls 
1081    README  rack 
1082  
1083Then, when you switch back, you get an empty `rack` directory. You can either run `git submodule update` to reclone, or you can move your `/tmp/rack` directory back into the empty directory. 
1084  
1085## Subtree Merging ## 2===== Subtree Merging 
1086  
1087Now that you’ve seen the difficulties of the submodule system, let’s look at an alternate way to solve the same problem. When Git merges, it looks at what it has to merge together and then chooses an appropriate merging strategy to use. If you’re merging two branches, Git uses a _recursive_ strategy. If you’re merging more than two branches, Git picks the _octopus_ strategy. These strategies are automatically chosen for you because the recursive strategy can handle complex three-way merge situations — for example, more than one common ancestor — but it can only handle merging two branches. The octopus merge can handle multiple branches but is more cautious to avoid difficult conflicts, so it’s chosen as the default strategy if you’re trying to merge more than two branches. 
1088  
1089However, there are other strategies you can choose as well. One of them is the _subtree_ merge, and you can use it to deal with the subproject issue. Here you’ll see how to do the same rack embedding as in the last section, but using subtree merges instead. 
1090 3 
.1091The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is smart enough to figure out that one is a subtree of the other and merge appropriately — it’s pretty amazing.4The idea of the subtree merge is that you have two projects, and one of the projects maps to a subdirectory of the other one and vice versa. When you specify a subtree merge, Git is often smart enough to figure out that one is a subtree of the other and merge appropriately.
 5 
 6We'll go through an example of adding a separate project into an existing project and then merging the code of the second into a subdirectory of the first.
1092 7 
.1093You first add the Rack application to your project. You add the Rack project as a remote reference in your own project and then check it out into its own branch:8First, we'll add the Rack application to our project. We'll add the Rack project as a remote reference in our own project and then check it out into its own branch:
1094 9 
. 10[source,console]
 11----
1095    $ git remote add rack_remote git@github.com:schacon/rack.git 12$ git remote add rack_remote https://github.com/rack/rack 
1096    $ git fetch rack_remote13$ git fetch rack_remote
1097    warning: no common commits14warning: no common commits
1098    remote: Counting objects: 3184, done.15remote: Counting objects: 3184, done.
1099    remote: Compressing objects: 100% (1465/1465), done.16remote: Compressing objects: 100% (1465/1465), done.
1100    remote: Total 3184 (delta 1952), reused 2770 (delta 1675)17remote: Total 3184 (delta 1952), reused 2770 (delta 1675)
1101    Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done.18Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done.
1102    Resolving deltas: 100% (1952/1952), done.19Resolving deltas: 100% (1952/1952), done.
1103    From git@github.com:schacon/rack20From https://github.com/rack/rack
1104     * [new branch]      build      -> rack_remote/build21 * [new branch]      build      -> rack_remote/build
1105     * [new branch]      master     -> rack_remote/master22 * [new branch]      master     -> rack_remote/master
1106     * [new branch]      rack-0.4   -> rack_remote/rack-0.423 * [new branch]      rack-0.4   -> rack_remote/rack-0.4
1107     * [new branch]      rack-0.9   -> rack_remote/rack-0.924 * [new branch]      rack-0.9   -> rack_remote/rack-0.9
1108    $ git checkout -b rack_branch rack_remote/master25$ git checkout -b rack_branch rack_remote/master
1109    Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master.26Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master.
1110    Switched to a new branch "rack_branch"27Switched to a new branch "rack_branch"
 28----
1111 29 
.1112Now you have the root of the Rack project in your `rack_branch` branch and your own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots:30Now we have the root of the Rack project in our `rack_branch` branch and our own project in the `master` branch. If you check out one and then the other, you can see that they have different project roots:
1113 31 
. 32[source,console]
 33----
1114    $ ls34$ ls
1115    AUTHORS           KNOWN-ISSUES   Rakefile      contrib           lib35AUTHORS         KNOWN-ISSUES   Rakefile      contrib         lib
1116    COPYING           README         bin           example           test36COPYING         README         bin           example         test
1117    $ git checkout master37$ git checkout master
1118    Switched to branch "master"38Switched to branch "master"
1119    $ ls39$ ls
1120    README40README
 41----
 42 
 43This is sort of a strange concept. Not all the branches in your repository actually have to be branches of the same project. It's not common, because it's rarely helpful, but it's fairly easy to have branches contain completely different histories.
1121 44 
.1122You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project:45In this case, we want to pull the Rack project into our `master` project as a subdirectory. We can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in <<_git_internals>>, but for now know that it reads the root tree of one branch into your current staging area and working directory. We just switched back to your `master` branch, and we pull the `rack` branch into the `rack` subdirectory of our `master` branch of our main project:
1123 46 
. 47[source,console]
 48----
1124    $ git read-tree --prefix=rack/ -u rack_branch49$ git read-tree --prefix=rack/ -u rack_branch
 50----
1125 51 
.1126When you commit, it looks like you have all the Rack files under that subdirectory as though you copied them in from a tarball. What gets interesting is that you can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, you can pull in upstream changes by switching to that branch and pulling:52When we commit, it looks like we have all the Rack files under that subdirectory as though we copied them in from a tarball. What gets interesting is that we can fairly easily merge changes from one of the branches to the other. So, if the Rack project updates, we can pull in upstream changes by switching to that branch and pulling:
1127 53 
. 54[source,console]
 55----
1128    $ git checkout rack_branch56$ git checkout rack_branch
1129    $ git pull57$ git pull
 58----
1130 59 
.1131Then, you can merge those changes back into your master branch. You can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which you probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option:60Then, we can merge those changes back into our `master` branch. We can use `git merge -s subtree` and it will work fine; but Git will also merge the histories together, which we probably don’t want. To pull in the changes and prepopulate the commit message, use the `--squash` and `--no-commit` options as well as the `-s subtree` strategy option:
1132 61 
. 62[source,console]
 63----
1133    $ git checkout master64$ git checkout master
1134    $ git merge --squash -s subtree --no-commit rack_branch65$ git merge --squash -s subtree --no-commit rack_branch
1135    Squash commit -- not updating HEAD66Squash commit -- not updating HEAD
1136    Automatic merge went well; stopped before committing as requested67Automatic merge went well; stopped before committing as requested
 68----
1137 69 
.1138All the changes from your Rack project are merged in and ready to be committed locally. You can also do the opposite make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream.70All the changes from the Rack project are merged in and ready to be committed locally. You can also do the opposite make changes in the `rack` subdirectory of your master branch and then merge them into your `rack_branch` branch later to submit them to the maintainers or push them upstream.
 71 
 72This gives us a way to have a workflow somewhat similar to the submodule workflow without using submodules (which we will cover in <<_git_submodules>>). We can keep branches with other related projects in our repository and subtree merge them into our project occasionally. It is nice in some ways, for example all the code is committed to a single place. However, it has other drawbacks in that it's a bit more complex and easier to make mistakes in reintegrating changes or accidentally pushing a branch into an unrelated repository.
1139 73 
.1140To get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch to see if you need to merge them you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to:74Another slightly weird thing is that to get a diff between what you have in your `rack` subdirectory and the code in your `rack_branch` branch to see if you need to merge them you can’t use the normal `diff` command. Instead, you must run `git diff-tree` with the branch you want to compare to:
1141 75 
. 76[source,console]
 77----
1142    $ git diff-tree -p rack_branch78$ git diff-tree -p rack_branch
 79----
1143 80 
1144Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run81Or, to compare what is in your `rack` subdirectory with what the `master` branch on the server was the last time you fetched, you can run
1145 82 
. 83[source,console]
 84----
1146    $ git diff-tree -p rack_remote/master85$ git diff-tree -p rack_remote/master
1147 86---- 
1148## Summary ## 
1149  
1150You’ve seen a number of advanced tools that allow you to manipulate your commits and staging area more precisely. When you notice issues, you should be able to easily figure out what commit introduced them, when, and by whom. If you want to use subprojects in your project, you’ve learned a few ways to accommodate those needs. At this point, you should be able to do most of the things in Git that you’ll need on the command line day to day and feel comfortable doing so. 
1151 87 
+
+ diff --git a/book/07-git-tools/sections/interactive-staging.asc b/book/07-git-tools/sections/interactive-staging.asc index 06bc7366..709e303f 100644 --- a/book/07-git-tools/sections/interactive-staging.asc +++ b/book/07-git-tools/sections/interactive-staging.asc @@ -1,11 +1,21 @@ [[_interactive_staging]] +////////////////////////// === Interactive Staging +////////////////////////// +=== 対話的なステージング +////////////////////////// Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: +////////////////////////// +Git には、コマンドラインでの作業をしやすくするためのスクリプトがいくつか付属しています。 +ここでは、対話コマンドをいくつか紹介しましょう。これらを使うと、コミットの内容に細工をして特定のコミットだけとかファイルの中の一部だけとかを含めるようにすることが簡単にできるようになります。 +大量のファイルを変更した後に、それをひとつの馬鹿でかいコミットにしてしまうのではなくテーマごとの複数のコミットに分けて処理したい場合などに非常に便利です。 +このようにして各コミットを論理的に独立した状態にしておけば、同僚によるレビューも容易になります。 +`git add` に `-i` あるいは `--interactive` というオプションをつけて実行すると、Git は対話シェルモードに移行し、このように表示されます。 [source,console] ---- @@ -21,15 +31,28 @@ $ git add -i What now> ---- +////////////////////////// You can see that this command shows you a much different view of your staging area – basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. +////////////////////////// +このコマンドは、ステージングエリアに関する情報を違った観点で表示します。`git status` で得られる情報と基本的には同じですが、より簡潔で有益なものとなっています。 +ステージした変更が左側、そしてステージしていない変更が右側に表示されます。 +////////////////////////// After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. +////////////////////////// +Commands セクションでは、さまざまなことができるようになっています。 +ファイルをステージしたりステージングエリアから戻したり、ファイルの一部だけをステージしたりまだ追跡されていないファイルを追加したり、あるいは何がステージされたのかを diff で見たりといったことが可能です。 +////////////////////////// ==== Staging and Unstaging Files +////////////////////////// +////////////////////////// If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: +////////////////////////// +`What now>` プロンプトで `2` または `u` と入力すると、どのファイルをステージするかを聞いてきます。 [source,console] ---- @@ -41,7 +64,10 @@ What now> 2 Update>> ---- +////////////////////////// To stage the TODO and index.html files, you can type the numbers: +////////////////////////// +TODO と index.html をステージするには、その番号を入力します。 [source,console] ---- @@ -53,8 +79,12 @@ Update>> 1,2 Update>> ---- +////////////////////////// The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: +////////////////////////// +ファイル名の横に `*` がついていれば、そのファイルがステージ対象として選択されたことを意味します。 +`Update>>` プロンプトで何も入力せずに Enter を押すと、選択されたすべてのファイルを Git がステージします。 [source,console] ---- @@ -71,8 +101,11 @@ What now> 1 3: unchanged +5/-1 lib/simplegit.rb ---- +////////////////////////// Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: +////////////////////////// +TODO と index.html がステージされ、simplegit.rb はまだステージされていないままです。ここで仮に TODO ファイルのステージを取り消したくなったとしたら、`3` あるいは `r` (revert の r) を選択します。 [source,console] ---- @@ -93,7 +126,10 @@ Revert>> [enter] reverted one path ---- +////////////////////////// Looking at your Git status again, you can see that you’ve unstaged the TODO file: +////////////////////////// +もう一度 Git のステータスを見ると、TODO ファイルのステージが取り消されていることがわかります。 [source,console] ---- @@ -107,9 +143,14 @@ What now> 1 3: unchanged +5/-1 lib/simplegit.rb ---- +////////////////////////// To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: +////////////////////////// +ステージした変更の diff を見るには、`6` あるいは `d` (diff の d) を使用します。 +このコマンドは、ステージしたファイルの一覧を表示します。その中から、ステージされた diff を見たいファイルを選択します。 +これは、コマンドラインで `git diff --cached` を使用するのと同じようなことです。 [source,console] ---- @@ -134,14 +175,26 @@ index 4d07108..4335f49 100644