475 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			475 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| ---
 | |
| layout: reference
 | |
| ---
 | |
| 
 | |
| <div class="box">
 | |
|   <h2>
 | |
|     <span class="docs">
 | |
|       <a target="new" href="http://progit.org/book/ch2-3.html">book</a>
 | |
|     </span>
 | |
|     Inspection and Comparison
 | |
|   </h2>
 | |
|   <div class="block">
 | |
|     <p>
 | |
|     So now you have a bunch of branches that you are using for short lived
 | |
|     topics, long lived features and what not.  How do you keep track of them?
 | |
|     Git has a couple of tools to help you figure out where work was done, what
 | |
|     the difference between two branches are and more.
 | |
|     </p>
 | |
| 
 | |
|     <p class="nutshell">
 | |
|     <b>In a nutshell</b> you can use <code>git log</code> to find specific
 | |
|     commits in your project history - by author, date, content or
 | |
|     history.  You can use <code>git diff</code> to compare two different points
 | |
|     in your history - generally to see how two branches differ or what has
 | |
|     changed from one version of your software to another.
 | |
|     </p>
 | |
|   </div>
 | |
| </div>
 | |
| 
 | |
| <div class="box">
 | |
|   <h2>
 | |
|     <span class="docs">
 | |
|       <a target="new" href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html">docs</a>  
 | |
|       <a target="new" href="http://progit.org/book/ch2-3.html">book</a>
 | |
|     </span>
 | |
|     <a name="log">git log</a>
 | |
|     <span class="desc">filter your commit history</span>
 | |
|   </h2>
 | |
| 
 | |
|   <div class="block">
 | |
|     <p>We've already seen how to use <code>git log</code> to compare branches,
 | |
|     by looking at the commits on one branch that are not reachable from another.
 | |
|     (If you don't remember, it looks like this: <code>git log branchA ^branchB</code>.
 | |
|     However, you can also use <code>git log</code> to look for specific commits.
 | |
|     Here we'll be looking at some of the more commonly used <code>git log</code>
 | |
|     options, but there are many.  Take a look at the official docs for the whole
 | |
|     list.
 | |
|     </p>
 | |
| 
 | |
|     <h4>
 | |
|       git log --author
 | |
|       <small>look for only commits from a specific author</small>
 | |
|     </h4>
 | |
| 
 | |
|     <p>
 | |
|     To filter your commit history to only the ones done by a specific author,
 | |
|     you can use the <code>--author</code> option.  For example, let's say we're
 | |
|     looking for the commits in the Git source code done by Linus.  We would
 | |
|     type something like <code>git log --author=Linus</code>. The search is
 | |
|     case sensitive and also will search the email address.  I'll do the
 | |
|     example using the <code>-[number]</code> option, which will limit the
 | |
|     results to the last [number] commits.
 | |
|     </p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --author=Linus --oneline -5</b>
 | |
| 81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
 | |
| 3bb7256 make "index-pack" a built-in
 | |
| 377d027 make "git pack-redundant" a built-in
 | |
| b532581 make "git unpack-file" a built-in
 | |
| 112dd51 make "mktag" a built-in
 | |
| </pre>
 | |
| 
 | |
|     <h4>
 | |
|       git log --since --before
 | |
|       <small>filter commits by date authored</small>
 | |
|     </h4>
 | |
| 
 | |
|     <p>
 | |
|     If you want to specify a date range that you're interested in filtering your
 | |
|     commits down to, you can use a number of options - I use <code>--since</code>
 | |
|     and <code>--before</code>, but you can also use <code>--until</code> and
 | |
|     <code>--after</code>.  For example, if I wanted to see all the commits in
 | |
|     the Git project before 3 weeks ago but after April 18th, I could run this
 | |
|     (I'm also going to use <code>--no-merges</code> to remove merge commits):
 | |
|     </p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges</b>
 | |
| 5469e2d Git 1.7.1-rc2
 | |
| d43427d Documentation/remote-helpers: Fix typos and improve language
 | |
| 272a36b Fixup: Second argument may be any arbitrary string
 | |
| b6c8d2d Documentation/remote-helpers: Add invocation section
 | |
| 5ce4f4e Documentation/urls: Rewrite to accomodate transport::address
 | |
| 00b84e9 Documentation/remote-helpers: Rewrite description
 | |
| 03aa87e Documentation: Describe other situations where -z affects git diff
 | |
| 77bc694 rebase-interactive: silence warning when no commits rewritten
 | |
| 636db2c t3301: add tests to use --format="%N"
 | |
| </pre>
 | |
| 
 | |
|     <h4>
 | |
|       git log --grep
 | |
|       <small>filter commits by commit message</small>
 | |
|     </h4>
 | |
| 
 | |
|     <p>
 | |
|       You may also want to look for commits with a certain phrase in the commit
 | |
|       message.  You can use <code>--grep</code> for that.  Let's say I knew there
 | |
|       was a commit that dealt with using the P4EDITOR environment variable and
 | |
|       I wanted to remember what that change looked like - I could find the commit
 | |
|       with <code>--grep</code>.
 | |
|     </p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --grep=P4EDITOR --no-merges</b>
 | |
| <span class="yellow">commit 82cea9ffb1c4677155e3e2996d76542502611370</span>
 | |
| Author: Shawn Bohrer
 | |
| Date:   Wed Mar 12 19:03:24 2008 -0500
 | |
| 
 | |
|     git-p4: Use P4EDITOR environment variable when set
 | |
| 
 | |
|     Perforce allows you to set the P4EDITOR environment variable to your
 | |
|     preferred editor for use in perforce.  Since we are displaying a
 | |
|     perforce changelog to the user we should use it when it is defined.
 | |
| 
 | |
|     Signed-off-by: Shawn Bohrer <shawn.bohrer@gmail.com>
 | |
|     Signed-off-by: Simon Hausmann <simon@lst.de>
 | |
| </pre>
 | |
| 
 | |
|     <p>
 | |
|     Git will logically OR all <code>--grep</code> and <code>--author</code>
 | |
|     arguments.  If you want to use <code>--grep</code> and <code>--author</code>
 | |
|     to see commits that were authored by someone AND have a specific message
 | |
|     content, you have to add the <code>--all-match</code> option. In these
 | |
|     examples, I'm going to use the <code>--format</code> option, so we can see
 | |
|     who the author of each commit was.
 | |
|     </p>
 | |
| 
 | |
|     <p>If I look for the commit messages with 'p4 depo' in them, I get these
 | |
|     three commits:</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --grep="p4 depo" --format="%h %an %s"</b>
 | |
| ee4fd1a Junio C Hamano Merge branch 'master' of git://repo.or.cz/git/fastimport
 | |
| da4a660 Benjamin Sergeant git-p4 fails when cloning a p4 depo.
 | |
| 1cd5738 Simon Hausmann Make incremental imports easier to use by storing the p4 d
 | |
| </pre>
 | |
| 
 | |
|     <p>If I add a <code>--author=Hausmann</code> argument, instead of further
 | |
|     filtering it down to the one commit by Simon, it instead will show me all
 | |
|     commits by Simon OR commits with "p4 depo" in the message:</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --grep="p4 depo" --format="%h %an %s" --author="Hausmann"</b>
 | |
| cdc7e38 Simon Hausmann Make it possible to abort the submission of a change to Pe
 | |
| f5f7e4a Simon Hausmann Clean up the git-p4 documentation
 | |
| 30b5940 Simon Hausmann git-p4: Fix import of changesets with file deletions
 | |
| 4c750c0 Simon Hausmann git-p4: git-p4 submit cleanups.
 | |
| 0e36f2d Simon Hausmann git-p4: Removed git-p4 submit --direct.
 | |
| edae1e2 Simon Hausmann git-p4: Clean up git-p4 submit's log message handling.
 | |
| 4b61b5c Simon Hausmann git-p4: Remove --log-substitutions feature.
 | |
| 36ee4ee Simon Hausmann git-p4: Ensure the working directory and the index are cle
 | |
| e96e400 Simon Hausmann git-p4: Fix submit user-interface.
 | |
| 38f9f5e Simon Hausmann git-p4: Fix direct import from perforce after fetching cha
 | |
| 2094714 Simon Hausmann git-p4: When skipping a patch as part of "git-p4 submit" m
 | |
| 1ca3d71 Simon Hausmann git-p4: Added support for automatically importing newly ap
 | |
| ...
 | |
| </pre>
 | |
| 
 | |
|     <p>However, if I add a <code>--all-match</code>, I get the results I'm
 | |
|     looking for:</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --grep="p4 depo" --format="%h %an %s" --author="Hausmann" --all-match</b>
 | |
| 1cd5738 Simon Hausmann Make incremental imports easier to use by storing the p4 d
 | |
| </pre>
 | |
| 
 | |
|     <h4>
 | |
|       git log -S
 | |
|       <small>filter by introduced diff</small>
 | |
|     </h4>
 | |
| 
 | |
|     <p>
 | |
|       What if you write really horrible commit messages?  Or, what if you are
 | |
|       looking for when a function was introduced, or where variables started
 | |
|       to be used?  You can also tell Git to look through the diff of each
 | |
|       commit for a string.  For example, if we wanted to find which commits
 | |
|       modified anything that looked like the function name
 | |
|       'userformat_find_requirements', we would run this: (note there is no '='
 | |
|       between the '-S' and what you are searching for)
 | |
|     </p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log -Suserformat_find_requirements</b>
 | |
| <span class="yellow">commit 5b16360330822527eac1fa84131d185ff784c9fb</span>
 | |
| Author: Johannes Gilger
 | |
| Date:   Tue Apr 13 22:31:12 2010 +0200
 | |
| 
 | |
|     pretty: Initialize notes if %N is used
 | |
| 
 | |
|     When using git log --pretty='%N' without an explicit --show-notes, git
 | |
|     would segfault. This patches fixes this behaviour by loading the needed
 | |
|     notes datastructures if --pretty is used and the format contains %N.
 | |
|     When --pretty='%N' is used together with --no-notes, %N won't be
 | |
|     expanded.
 | |
| 
 | |
|     This is an extension to a proposed patch by Jeff King.
 | |
| 
 | |
|     Signed-off-by: Johannes Gilger
 | |
|     Signed-off-by: Junio C Hamano
 | |
| </pre>
 | |
| 
 | |
|     <h4>
 | |
|       git log -p
 | |
|       <small>show patch introduced at each commit</small>
 | |
|     </h4>
 | |
| 
 | |
|     <p>
 | |
|     Each commit is a snapshot of the project, but since each commit records the
 | |
|     snapshot it was based off of, Git can always calculate the difference and
 | |
|     show it to you as a patch.  That means for any commit you can get the patch
 | |
|     that commit introduced to the project.  You can either do this by running
 | |
|     <code>git show [SHA]</code> with a specific commit SHA, or you can run
 | |
|     <code>git log -p</code>, which tells Git to put the patch after each commit.
 | |
|     It is a great way to summarize what has happened on a branch or between
 | |
|     commits.
 | |
|     </p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log -p --no-merges -2</b>
 | |
| <span class="yellow">commit 594f90bdee4faf063ad07a4a6f503fdead3ef606</span>
 | |
| Author: Scott Chacon schacon@gmail.com
 | |
| Date:   Fri Jun 4 15:46:55 2010 +0200
 | |
| 
 | |
|     reverted to old class name
 | |
| 
 | |
| <span class="umber">diff --git a/ruby.rb b/ruby.rb
 | |
| index bb86f00..192151c 100644
 | |
| --- a/ruby.rb
 | |
| +++ b/ruby.rb</span>
 | |
| <span class="lblue">@@ -1,7 +1,7 @@</span>
 | |
| <span class="red">-class HiWorld</span>
 | |
| <span class="green">+class HelloWorld</span>
 | |
|    def self.hello
 | |
|      puts "Hello World from Ruby"
 | |
|    end
 | |
|  end
 | |
| 
 | |
| <span class="red">-HiWorld.hello</span>
 | |
| <span class="green">+HelloWorld.hello</span>
 | |
| 
 | |
| <span class="yellow">commit 3cbb6aae5c0cbd711c098e113ae436801371c95e</span>
 | |
| Author: Scott Chacon schacon@gmail.com
 | |
| Date:   Fri Jun 4 12:58:53 2010 +0200
 | |
| 
 | |
|     fixed readme title differently
 | |
| 
 | |
| <span class="umber">diff --git a/README b/README
 | |
| index d053cc8..9103e27 100644
 | |
| --- a/README
 | |
| +++ b/README</span>
 | |
| <span class="lblue">@@ -1,4 +1,4 @@</span>
 | |
| <span class="red">-Hello World Examples</span>
 | |
| <span class="green">+Many Hello World Examples</span>
 | |
|  ======================
 | |
| 
 | |
|  This project has examples of hello world in
 | |
| </pre>
 | |
| 
 | |
|     <p>This is a really nice way of summarizing changes or reviewing a series
 | |
|     of commits before merging them or releasing something.</p>
 | |
| 
 | |
|     <h4>
 | |
|       git log --stat
 | |
|       <small>show diffstat of changes introduced at each commit</small>
 | |
|     </h4>
 | |
| 
 | |
|     <p>If the <code>-p</code> option is too verbose for you, you can summarize
 | |
|     the changes with <code>--stat</code> instead. Here is the same log output
 | |
|     with <code>--stat</code> instead of <code>-p</code></p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --stat --no-merges -2</b>
 | |
| <span class="yellow">commit 594f90bdee4faf063ad07a4a6f503fdead3ef606</span>
 | |
| Author: Scott Chacon schacon@gmail.com
 | |
| Date:   Fri Jun 4 15:46:55 2010 +0200
 | |
| 
 | |
|     reverted to old class name
 | |
| 
 | |
|  ruby.rb |    4 <span class="green">++</span><span class="red">--</span>
 | |
|  1 files changed, 2 insertions(+), 2 deletions(-)
 | |
| 
 | |
| <span class="yellow">commit 3cbb6aae5c0cbd711c098e113ae436801371c95e</span>
 | |
| Author: Scott Chacon schacon@gmail.com
 | |
| Date:   Fri Jun 4 12:58:53 2010 +0200
 | |
| 
 | |
|     fixed readme title differently
 | |
| 
 | |
|  README |    2 <span class="green">+</span><span class="red">-</span>
 | |
|  1 files changed, 1 insertions(+), 1 deletions(-)
 | |
| </pre>
 | |
| 
 | |
|     <p>Same basic information, but a little more compact - it still lets you
 | |
|     see relative changes and which files were modified.</p>
 | |
| 
 | |
|   </div>
 | |
| </div>
 | |
| 
 | |
| <div class="box">
 | |
|   <h2>
 | |
|     <span class="docs">
 | |
|       <a target="new" href="http://www.kernel.org/pub/software/scm/git/docs/git-diff.html">docs</a>  
 | |
|       <a target="new" href="http://progit.org/book/ch5-3.html#determining_what_is_introduced">book</a>
 | |
|     </span>
 | |
|     <a name="diff">git diff</a>
 | |
|     <span class="desc"></span>
 | |
|   </h2>
 | |
| 
 | |
|   <div class="block">
 | |
| 
 | |
|     <p>Finally, to see the absolute changes between any two commit snapshots,
 | |
|     you can use the <code>git diff</code> command. This is largely used in two
 | |
|     main situations - seeing how two branches differ from one another and
 | |
|     seeing what has changed since a release or some other older point in
 | |
|     history.  Let's look at both of these situations.</p>
 | |
| 
 | |
|     <p>To see what has changed since the last release, you can simply run
 | |
|     <code>git diff [version]</code> (or whatever you tagged the release).
 | |
|     For example, if we want to see what has changed in our project since
 | |
|     the v0.9 release, we can run <code>git diff v0.9</code>.
 | |
|     </p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git diff v0.9</b>
 | |
| <span class="umber">diff --git a/README b/README
 | |
| index d053cc8..d4173d5 100644
 | |
| --- a/README
 | |
| +++ b/README</span>
 | |
| <span class="lblue">@@ -1,4 +1,4 @@</span>
 | |
| <span class="red">-Hello World Examples</span>
 | |
| <span class="green">+Many Hello World Lang Examples</span>
 | |
|  ======================
 | |
| 
 | |
|  This project has examples of hello world in
 | |
| <span class="umber">diff --git a/ruby.rb b/ruby.rb
 | |
| index bb86f00..192151c 100644
 | |
| --- a/ruby.rb
 | |
| +++ b/ruby.rb</span>
 | |
| <span class="lblue">@@ -1,7 +1,7 @@</span>
 | |
| <span class="red">-class HiWorld</span>
 | |
| <span class="green">+class HelloWorld</span>
 | |
|    def self.hello
 | |
|      puts "Hello World from Ruby"
 | |
|    end
 | |
|  end
 | |
| 
 | |
| <span class="red">-HiWorld.hello</span>
 | |
| <span class="green">+HelloWorld.hello</span>
 | |
| </pre>
 | |
| 
 | |
|     <p>Just like <code>git log</code>, you can use the <code>--stat</code>
 | |
|       option with it.</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git diff v0.9 --stat</b>
 | |
|  README  |    2 +-
 | |
|  ruby.rb |    4 ++--
 | |
|  2 files changed, 3 insertions(+), 3 deletions(-)
 | |
| </pre>
 | |
| 
 | |
|     <p>To compare two divergant branches, however, you can run something like
 | |
|     <code>git diff branchA branchB</code> but the problem is that it will do
 | |
|     exactly what you are asking - it will basically give you a patch file that
 | |
|     would turn the snapshot at the tip of branchA into the snapshot at the tip
 | |
|     of branchB.  This means if the two branches have diverged - gone in different
 | |
|     directions - it will remove all the work that was introduced into branchA
 | |
|     and then add everything that was introduced into branchB.  This is probably
 | |
|     not what you want - you want the changes added to branchB that are not in
 | |
|     branchA, so you really want the difference between where the two branches
 | |
|     diverged and the tip of branchB. So, if our history looks like this:</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git log --graph --oneline --decorate --all</b>
 | |
| * 594f90b (HEAD, tag: v1.0, master) reverted to old class name
 | |
| | * 1834130 (erlang) added haskell
 | |
| | * ab5ab4c added erlang
 | |
| |/
 | |
| *   8d585ea Merge branch 'fix_readme'
 | |
| ...
 | |
| </pre>
 | |
| 
 | |
|     <p>And we want to see what is on the "erlang" branch compared to the "master"
 | |
|     branch, running <code>git diff master erlang</code> will give us the wrong
 | |
|     thing.</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git diff --stat master erlang</b>
 | |
|  erlang_hw.erl |    5 +++++
 | |
|  haskell.hs    |    4 ++++
 | |
|  ruby.rb       |    4 ++--
 | |
|  3 files changed, 11 insertions(+), 2 deletions(-)
 | |
| </pre>
 | |
| 
 | |
|     <p>You see that it adds the erlang and haskell files, which is what we did
 | |
|     in that branch, but then the output also reverts the changes to the ruby file
 | |
|     that we did in the master branch.  What we really want to see is just the
 | |
|     changes that happened in the "erlang" branch (adding the two files).  We can
 | |
|     get the desired result by doing the diff from the common commit they diverged
 | |
|     from:</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git diff --stat 8d585ea erlang</b>
 | |
|  erlang_hw.erl |    5 +++++
 | |
|  haskell.hs    |    4 ++++
 | |
|  2 files changed, 9 insertions(+), 0 deletions(-)
 | |
| </pre>
 | |
| 
 | |
|     <p>That's what we're looking for, but we don't want to have to figure out
 | |
|     what commit the two branches diverged from every time. Luckily, Git has a
 | |
|     shortcut for this. If you run <code>git diff master...erlang</code> (with        three dots in between the branch names), Git will automatically figure out
 | |
|     what the common commit (otherwise known as the "merge base") of the two
 | |
|     commit is and do the diff off of that.</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git diff --stat master erlang</b>
 | |
|  erlang_hw.erl |    5 +++++
 | |
|  haskell.hs    |    4 ++++
 | |
|  ruby.rb       |    4 ++--
 | |
|  3 files changed, 11 insertions(+), 2 deletions(-)
 | |
| <b>$ git diff --stat master...erlang</b>
 | |
|  erlang_hw.erl |    5 +++++
 | |
|  haskell.hs    |    4 ++++
 | |
|  2 files changed, 9 insertions(+), 0 deletions(-)
 | |
| </pre>
 | |
| 
 | |
|     <p>Nearly every time you want to compare two branches, you'll want to use
 | |
|     the triple-dot syntax, because it will almost always give you what you want.
 | |
|     </p>
 | |
| 
 | |
|     <p>As a bit of an aside, you can also have git manually calculate the
 | |
|     merge-base (first common ancestor commit) of any two commits would be with
 | |
|     the <code>git merge-base</code> command:</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git merge-base master erlang</b>
 | |
| 8d585ea6faf99facd39b55d6f6a3b3f481ad0d3d
 | |
| </pre>
 | |
| 
 | |
|     <p>So, you can do the equivalent of <code>git diff master...erlang</code>
 | |
|     by running this:</p>
 | |
| 
 | |
| <pre>
 | |
| <b>$ git diff --stat $(git merge-base master erlang) erlang</b>
 | |
|  erlang_hw.erl |    5 +++++
 | |
|  haskell.hs    |    4 ++++
 | |
|  2 files changed, 9 insertions(+), 0 deletions(-)
 | |
| </pre>
 | |
| 
 | |
|     <p>I would of course recommend using the easier syntax, though.</p>
 | |
| 
 | |
| 
 | |
|     <p class="nutshell">
 | |
|     <b>In a nutshell</b> you can use <code>git diff</code> to see how a project
 | |
|     has changed since a known point in the past or to see what unique work is
 | |
|     in one branch since it diverged from another.  Always use
 | |
|     <code>git diff branchA...branchB</code> to inspect branchB relative to
 | |
|     branchA to make things easier.
 | |
|     </p>
 | |
| 
 | |
|   </div>
 | |
| </div>
 | |
| 
 | |
| <p>And that's it!  For more information, try reading the
 | |
| <a href="http://progit.org">Pro Git book</a>.</p>
 |