If you run "git branch" at this point, you'll see that git has
temporarily moved you to a new branch named "bisect". This branch
points to a commit (with commit id 65934...) that is reachable from
-v2.6.19 but not from v2.6.18. Compile and test it, and see whether
+"master" but not from v2.6.18. Compile and test it, and see whether
it crashes. Assume it does crash. Then:
-------------------------------------------------
$ 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
fundamentally different ways to fix the problem:
1. You can create a new commit that undoes whatever was done
- by the previous commit. This is the correct thing if your
+ by the old commit. This is the correct thing if your
mistake has already been made public.
2. You can go back and modify the old commit. You should
Dangling objects are not a problem. At worst they may take up a little
extra disk space. They can sometimes provide a last-resort method for
recovering lost work--see <<dangling-objects>> for details. However, if
-you wish, you can remove them with gitlink:git-prune[1] or the --prune
+you wish, you can remove them with gitlink:git-prune[1] or the `--prune`
option to gitlink:git-gc[1]:
-------------------------------------------------
Reflogs
^^^^^^^
-Say you modify a branch with gitlink:git-reset[1] --hard, and then
+Say you modify a branch with `gitlink:git-reset[1] --hard`, and then
realize that the branch was the only reference you had to that point in
history.
$ git log master@{1}
-------------------------------------------------
-This lists the commits reachable from the previous version of the head.
-This syntax can be used to with any git command that accepts a commit,
-not just with git log. Some other examples:
+This lists the commits reachable from the previous version of the
+"master" branch head. This syntax can be used with any git command
+that accepts a commit, not just with git log. Some other examples:
-------------------------------------------------
$ git show master@{2} # See where the branch pointed 2,
More generally, a branch that is created from a remote branch will pull
by default from that branch. See the descriptions of the
branch.<name>.remote and branch.<name>.merge options in
-gitlink:git-config[1], and the discussion of the --track option in
+gitlink:git-config[1], and the discussion of the `--track` option in
gitlink:git-checkout[1], to learn how to control these defaults.
In addition to saving you keystrokes, "git pull" also helps you by
$ git pull /path/to/other/repository
-------------------------------------------------
-or an ssh url:
+or an ssh URL:
-------------------------------------------------
$ git clone ssh://yourhost/~you/repository
This is the preferred method.
If someone else administers the server, they should tell you what
-directory to put the repository in, and what git:// url it will appear
+directory to put the repository in, and what git:// URL it will appear
at. You can then skip to the section
"<<pushing-changes-to-a-public-repository,Pushing changes to a public
repository>>", below.
gitlink:git-update-server-info[1], and the documentation
link:hooks.html[Hooks used by git].)
-Advertise the url of proj.git. Anybody else should then be able to
-clone or pull from that url, for example with a command line like:
+Advertise the URL of proj.git. Anybody else should then be able to
+clone or pull from that URL, for example with a command line like:
-------------------------------------------------
$ git clone http://yourserver.com/~you/proj.git
and git will continue applying the rest of the patches.
-At any point you may use the --abort option to abort this process and
+At any point you may use the `--abort` option to abort this process and
return mywork to the state it had before you started the rebase:
-------------------------------------------------
and browse through the list of patches in the mywork branch using gitk,
applying them (possibly in a different order) to mywork-new using
-cherry-pick, and possibly modifying them as you go using commit --amend.
+cherry-pick, and possibly modifying them as you go using `commit --amend`.
The gitlink:git-gui[1] command may also help as it allows you to
individually select diff hunks for inclusion in the index (by
right-clicking on the diff hunk and choosing "Stage Hunk for Commit").
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
==========================