@ -658,16 +658,23 @@ gitlink:git-diff[1]:
@@ -658,16 +658,23 @@ gitlink:git-diff[1]:
$ git diff master..test
-------------------------------------------------
Sometimes what you want instead is a set of patches:
That will produce the diff between the tips of the two branches. If
you'd prefer to find the diff from their common ancestor to test, you
can use three dots instead of two:
-------------------------------------------------
$ git diff master...test
-------------------------------------------------
Sometimes what you want instead is a set of patches; for this you can
use gitlink:git-format-patch[1]:
-------------------------------------------------
$ git format-patch master..test
-------------------------------------------------
will generate a file with a patch for each commit reachable from test
but not from master. Note that if master also has commits which are
not reachable from test, then the combined result of these patches
will not be the same as the diff produced by the git-diff example.
but not from master.
[[viewing-old-file-versions]]
Viewing old file versions
@ -2554,6 +2561,72 @@ branches into their own work.
@@ -2554,6 +2561,72 @@ branches into their own work.
For true distributed development that supports proper merging,
published branches should never be rewritten.
[[bisect-merges]]
Why bisecting merge commits can be harder than bisecting linear history
-----------------------------------------------------------------------
The gitlink:git-bisect[1] command correctly handles history that
includes merge commits. However, when the commit that it finds is a
merge commit, the user may need to work harder than usual to figure out
why that commit introduced a problem.
Imagine this history:
................................................
---Z---o---X---...---o---A---C---D
\ /
o---o---Y---...---o---B
................................................
Suppose that on the upper line of development, the meaning of one
of the functions that exists at Z is changed at commit X. The
commits from Z leading to A change both the function's
implementation and all calling sites that exist at Z, as well
as new calling sites they add, to be consistent. There is no
bug at A.
Suppose that in the meantime on the lower line of development somebody
adds a new calling site for that function at commit Y. The
commits from Z leading to B all assume the old semantics of that
function and the callers and the callee are consistent with each
other. There is no bug at B, either.
Suppose further that the two development lines merge cleanly at C,
so no conflict resolution is required.
Nevertheless, the code at C is broken, because the callers added
on the lower line of development have not been converted to the new
semantics introduced on the upper line of development. So if all
you know is that D is bad, that Z is good, and that
gitlink:git-bisect[1] identifies C as the culprit, how will you
figure out that the problem is due to this change in semantics?
When the result of a git-bisect is a non-merge commit, you should
normally be able to discover the problem by examining just that commit.
Developers can make this easy by breaking their changes into small
self-contained commits. That won't help in the case above, however,
because the problem isn't obvious from examination of any single
commit; instead, a global view of the development is required. To
make matters worse, the change in semantics in the problematic
function may be just one small part of the changes in the upper
line of development.
On the other hand, if instead of merging at C you had rebased the
history between Z to B on top of A, you would have gotten this
linear history:
................................................................
---Z---o---X--...---o---A---o---o---Y*--...---o---B*--D*
................................................................
Bisecting between Z and D* would hit a single culprit commit Y*,
and understanding why Y* was broken would probably be easier.
Partly for this reason, many experienced git users, even when
working on an otherwise merge-heavy project, keep the history
linear by rebasing against the latest upstream version before
publishing.
[[advanced-branch-management]]
Advanced branch management
==========================