There are two additional forms of git diff that bear some explanation, especially in contrast to git log.
The git diff command supports a double-dot syntax to represent the difference between two commits. Thus, the following two commands are equivalent:
git diff master bug/pr-1 git diff master..bug/pr-1
Unfortunately, the double-dot syntax in git diff means something quite different from the same syntax in git log, which you learned about in Chapter 6. It’s worth comparing git diff and git log because doing so highlights the relationships of these two commands to changes made in repositories. Some points to keep in mind for the following example:
git diff doesn’t care about the history of the files it compares or anything about branches.
git log is extremely conscious of how one file changed to become another—say, when two branches diverged and what happened on each branch.
The log and diff commands perform two fundamentally different operations. Whereas log operates on a set of commits, diff operates on two different endpoints.
Imagine the following sequence of events:
Someone creates a new branch off the master
branch to fix bug pr-1
, calling the new branch
bug/pr-1
.
The same developer adds the line “Fix Problem report
1” to a file in the bug/pr-1
branch.
Meanwhile, another developer fixes bug pr-3
in the master
branch, adding the line “Fix
Problem report 3” to the same file in the
master
branch.
In short, one line was added to a file in each branch. If you look
at the changes to branches at a high level, you can see when the
bug/pr-1
branch was launched and when each change was
made:
$ git show-branch master bug/pr-1
* [master] Added a bug fix for pr-3.
! [bug/pr-1] Fix Problem Report 1
--
* [master] Added a bug fix for pr-3.
+ [bug/pr-1] Fix Problem Report 1
*+ [master^] Added Bob's fixes.
If you type git log -p master..bug/pr-1, you
will see one commit, because the syntax
master..bug/pr-1
represents all those commits in
bug/pr-1
that are not also in
master
. The command traces back to the point where
bug/pr-1
diverged from master
, but
it does not look at anything that happened to master
since that point:
$ git log -p master..bug/pr-1
commit 8f4cf5757a3a83b0b3dbecd26244593c5fc820ea
Author: Jon Loeliger <[email protected]>
Date: Wed May 14 17:53:54 2008 -0500
Fix Problem Report 1
diff --git a/ready b/ready
index f3b6f0e..abbf9c5 100644
--- a/ready
+++ b/ready
@@ -1,3 +1,4 @@
stupid
znill
frot-less
+Fix Problem report 1
In contrast, git diff master..bug/pr-1 shows
the total set of differences between the two trees represented by the
heads of the master
and bug/pr-1
branches. History doesn’t matter; only the current state of the files
does:
$ git diff master..bug/pr-1
diff --git a/NewStuff b/NewStuff
index b4d8596..0f2416e 100644
--- a/NewStuff
+++ b/NewStuff
@@ -1,2 +1 @@
Something
-Fix Problem report 3
diff --git a/ready b/ready
index f3b6f0e..abbf9c5 100644
--- a/ready
+++ b/ready
@@ -1,3 +1,4 @@
stupid
znill
frot-less
+Fix Problem report 1
To paraphrase the git diff output, you can
change the file in the master
branch to the version
in the bug/pr-1
branch by removing the line
“Fix Problem report 3” from and then adding the line
“Fix Problem report 1” to the file.
As you can see, this diff includes commits from both branches. This may not seem crucial with this small example, but consider the example in Figure 8-2 with more expansive lines of development on two branches.
In this case, git log master..maint represents
the five individual commits V
,
W
,..., Z
. On the other hand,
git diff master..maint represents the differences in
the trees at H
and Z
, an
accumulated eleven commits: C
,
D
,..., H
and
V
,..., Z
.
Similarly, both git log and git
diff accept the form
commit1
...commit2
to produce a symmetrical difference. As before,
however, git log
commit1
...commit2
and git diff
commit1
...commit2
yield different results.
As discussed in Commit Ranges,
the command git log
commit1
...commit2
displays the commits reachable from either commit but not
both. Thus, git log master...maint in the previous
example would yield C
, D
,...,
H
and V
,...,
Z
.
The symmetric difference in git diff shows the
differences between commit2
and a commit that
is a common ancestor (or merge base) of
commit1
and
commit2
. Given the same genealogy in Figure 8-2, git diff
master...maint combines the changes in the commits
V
, W
, ... ,
Z
.
18.119.112.7