From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
For the previous round [1], I wrote something like this to clarify why
merging with dirty trees is safe. I hope it also makes git-merge.1
more useful for other purposes. I have not changed the warning in
question, which belongs to a different topic.
Patches 1-3 move some material towards the end of the 'merge' manual,
to make the manpage easier to read straight through.
Patch 4 adds a brief introduction for the reader who might not yet be
familiar with branching and merging. I am especially interested in
feedback on this one. My writing tends not to be as clear as I would
like. Already some advice from Junio helped a great deal.
Patches 5-7 organize the material on how the merge works into short,
digestible pieces. Patch 5 explains how a merge can abort without
doing anything, patch 6 the fast-forward merge, and patch 7 the true
merge, all from the point of view of what matters for the person
invoking ‘git merge’. Patch 7 is basically rewritten using Thomas’s
advice.
The patches are against doc-style/for-next of Thomas’s repo at
git://repo.or.cz/git/trast .
The advice from last round was very helpful. Apologies for taking so
long to respond to it.
Enjoy,
Jonathan Nieder (7):
Documentation: merge: move configuration section to end
Documentation: suggest `reset --merge` in How Merge Works section
Documentation: merge: move merge strategy list to end
Documentation: merge: add an overview
Documentation: emphasize when git merge terminates early
Documentation: merge: add a section about fast-forward
Documentation: simplify How Merge Works
Documentation/git-merge.txt | 164 ++++++++++++++++++++++++-------------------
1 files changed, 92 insertions(+), 72 deletions(-)
[1] http://thread.gmane.org/gmane.comp.version-control.git/136356/focus=136617
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
Configuration and environment variables belong to the back matter
of a manual page.
Signed-off-by: Jonathan Nieder <redacted>
Acked-by: Petr Baudis <redacted>
---
Documentation/git-merge.txt | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
@@ -48,15 +48,6 @@ include::merge-strategies.txt[] If you tried a merge which resulted in complex conflicts and want to start over, you can recover with 'git reset'.-CONFIGURATION---------------include::merge-config.txt[]--branch.<name>.mergeoptions::- Sets default options for merging into branch <name>. The syntax and- supported options are the same as those of 'git merge', but option- values containing whitespace characters are currently not supported.- HOW MERGE WORKS ---------------
@@ -249,6 +240,15 @@ changes into a merge commit. Small fixups like bumping release/version name would be acceptable.+CONFIGURATION+-------------+include::merge-config.txt[]++branch.<name>.mergeoptions::+ Sets default options for merging into branch <name>. The syntax and+ supported options are the same as those of 'git merge', but option+ values containing whitespace characters are currently not supported.+ SEE ALSO -------- linkgit:git-fmt-merge-msg[1], linkgit:git-pull[1],
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
The 'merge' manual suggests 'reset' to cancel a merge at the end
of the Merge Strategies list. It is more logical to explain this
right before explaining how merge conflicts work, so the daunted
reader can have a way out when he or she needs it most.
While at it, make the advice more dependable and self-contained
by providing the --merge option.
Signed-off-by: Jonathan Nieder <redacted>
---
This should make the reference to 'git reset' easier to find on
second reading. Something like this ought to happen if we are
going to move the Merge Strategies list down towards the end of
the man page.
Documentation/git-merge.txt | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
@@ -45,9 +45,6 @@ include::merge-options.txt[] include::merge-strategies.txt[]-If you tried a merge which resulted in complex conflicts and-want to start over, you can recover with 'git reset'.- HOW MERGE WORKS ---------------
@@ -115,6 +112,9 @@ When there are conflicts, the following happens: same and the index entries for them stay as they were, i.e. matching `HEAD`.+If you tried a merge which resulted in complex conflicts and+want to start over, you can recover with `git reset --merge`.+ HOW CONFLICTS ARE PRESENTED ---------------------------
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
So the section layout changes as follows:
NAME
SYNOPSIS
DESCRIPTION
OPTIONS
-MERGE STRATEGIES
HOW MERGE WORKS
HOW CONFLICTS ARE PRESENTED
HOW TO RESOLVE CONFLICTS
EXAMPLES
+MERGE STRATEGIES
CONFIGURATION
SEE ALSO
AUTHOR
DOCUMENTATION
GIT
NOTES
The first-time user will care more about conflicts than about
strategies other than 'recursive'.
One of the examples uses -s ours, but I do not think this hinders
readability.
Suggested-by: Thomas Rast <redacted>
Signed-off-by: Jonathan Nieder <redacted>
---
Thomas Rast wrote [1]:
While I agree with the general intent of deferring the strategies
further back, wouldn't it be better go all the way and instead put
them before (or even after, but one of them uses -s ours) "EXAMPLES"?
The average user will care more about conflicts than about strategies
other than 'recursive'.
@@ -42,8 +42,6 @@ include::merge-options.txt[] You need at least one <commit>. Specifying more than one <commit> obviously means you are trying an Octopus.-include::merge-strategies.txt[]- HOW MERGE WORKS ---------------
@@ -240,6 +238,8 @@ changes into a merge commit. Small fixups like bumping release/version name would be acceptable.+include::merge-strategies.txt[]+ CONFIGURATION ------------- include::merge-config.txt[]
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
The reader unfamiliar with the concepts of branching and merging
would have been completely lost. Try to help him with a diagram.
Signed-off-by: Jonathan Nieder <redacted>
---
The advice in [1] was very helpful. I fear I’ve made a mess of
the language even so. At least it does seem much clearer now.
Thoughts?
[1] http://thread.gmane.org/gmane.comp.version-control.git/136356/focus=136629
Documentation/git-merge.txt | 28 ++++++++++++++++++++++++++--
1 files changed, 26 insertions(+), 2 deletions(-)
@@ -15,8 +15,32 @@ SYNOPSIS DESCRIPTION ------------Merges the history specified by <commit> into HEAD, optionally using a-specific merge strategy.+Incorporates changes from the named commits (since the time their+histories diverged from the current branch) into the current+branch. This command is used by 'git pull' to incorporate changes+from another repository and can be used by hand to merge changes+from one branch into another.++Assume the following history exists and the current branch is+"`master`":++------------+ A---B---C topic+ /+ D---E---F---G master+------------++Then "`git merge topic`" will replay the changes made on the+`topic` branch since it diverged from `master` (i.e., `E`) until+its current commit (`C`) on top of `master`, and record the result+in a new commit along with the names of the two parent commits and+a log message from the user describing the changes.++------------+ A---B---C topic+ / \+ D---E---F---G---H master+------------ The second syntax (<msg> `HEAD` <commit>...) is supported for historical reasons. Do not use it from the command line or in
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
A merge-based operation in git can fail in two ways: one that
stops before touching anything, or one that goes ahead and
results in conflicts.
As the 'git merge' manual explains:
| A merge is always between the current `HEAD` and one or more
| commits (usually, branch head or tag), and the index file must
| match the tree of `HEAD` commit (i.e. the contents of the last commit)
| when it starts out.
Unfortunately, the placement of this sentence makes it easy to
skip over, and its formulation leaves the important point, that
any other attempted merge will be gracefully aborted, unspoken.
So give this point its own section and expand upon it.
Probably this could be simplified somewhat: after all, a change
registered in the index is just a special kind of local
uncommited change, so the second added paragraph is only a
special case of the first. It seemed more helpful to be explicit
here.
Inspired by <http://gitster.livejournal.com/25801.html>.
Signed-off-by: Jonathan Nieder <redacted>
---
Too technical?
Documentation/git-merge.txt | 31 +++++++++++++++++++++----------
1 files changed, 21 insertions(+), 10 deletions(-)
@@ -67,21 +67,32 @@ include::merge-options.txt[] <commit> obviously means you are trying an Octopus.+PRE-MERGE CHECKS+----------------++Before applying outside changes, you should get your own work in+good shape and committed locally, so it will not be clobbered if+there are conflicts. See also linkgit:git-stash[1].+'git pull' and 'git merge' will stop without doing anything when+local uncommitted changes overlap with files that 'git pull'/'git+merge' may need to update.++To avoid recording unrelated changes in the merge commit,+'git pull' and 'git merge' will also abort if there are any changes+registered in the index relative to the `HEAD` commit. (One+exception is when the changed index entries are in the state that+would result from the merge already.)++If all named commits are already ancestors of `HEAD`, 'git merge'+will exit early with the message "Already up-to-date."+ HOW MERGE WORKS --------------- A merge is always between the current `HEAD` and one or more-commits (usually, branch head or tag), and the index file must-match the tree of `HEAD` commit (i.e. the contents of the last commit)-when it starts out. In other words, `git diff --cached HEAD` must-report no changes. (One exception is when the changed index-entries are already in the same state that would result from-the merge anyway.)--Three kinds of merge can happen:+commits (usually a branch head or tag).-* The merged commit is already contained in `HEAD`. This is the- simplest case, called "Already up-to-date."+Two kinds of merge can happen: * `HEAD` is already contained in the merged commit. This is the most common case especially when invoked from 'git pull':
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
Novices sometimes find the behavior of 'git merge' in the
fast-forward case surprising. Describe it thoroughly.
Signed-off-by: Jonathan Nieder <redacted>
---
Sometimes people ask on IRC.
Documentation/git-merge.txt | 31 ++++++++++++++++++-------------
1 files changed, 18 insertions(+), 13 deletions(-)
@@ -86,25 +86,30 @@ would result from the merge already.) If all named commits are already ancestors of `HEAD`, 'git merge' will exit early with the message "Already up-to-date."+FAST-FORWARD MERGE+------------------++Often the current branch head is an ancestor of the named commit.+This is the most common case especially when invoked from 'git+pull': you are tracking an upstream repository, you have committed+no local changes, and now you want to update to a newer upstream+revision. In this case, a new commit is not needed to store the+combined history; instead, the `HEAD` (along with the index) is+updated to point at the named commit, without creating an extra+merge commit.++This behavior can be suppressed with the `--no-ff` option.+ HOW MERGE WORKS --------------- A merge is always between the current `HEAD` and one or more commits (usually a branch head or tag).-Two kinds of merge can happen:--* `HEAD` is already contained in the merged commit. This is the- most common case especially when invoked from 'git pull':- you are tracking an upstream repository, have committed no local- changes and now you want to update to a newer upstream revision.- Your `HEAD` (and the index) is updated to point at the merged- commit, without creating an extra merge commit. This is- called "Fast-forward".--* Both the merged commit and `HEAD` are independent and must be- tied together by a merge commit that has both of them as its parents.- The rest of this section describes this "True merge" case.+Except in a fast-forward merge (see above), the branches to be+merged must be tied together by a merge commit that has both of them+as its parents.+The rest of this section describes this "True merge" case. The chosen merge strategy merges the two commits into a single new source tree.
From: Jonathan Nieder <hidden> Date: 2016-06-15 22:48:05
The user most likely does not care about the exact order of
operations because he cannot see it happening anyway. Instead,
try to explain what it means to merge two commits into a single
tree.
While at it:
- Change the heading to TRUE MERGE. The entire manual page is
about how merges work.
- Document MERGE_HEAD. It is a useful feature, since it makes
the parents of the intended merge commit easier to refer to.
- Do not assume commits named on the 'git merge' command line come
from another repository. For simplicity, the discussion of
conflicts still does assume that there is only one and it is a
branch head.
- Do not start list items with `code`. Otherwise, a toolchain bug
produces a line break in the generated nroff, resulting in odd
extra space.
Suggested-by: Thomas Rast <redacted>
Signed-off-by: Jonathan Nieder <redacted>
---
This is the end of series. Thanks for reading.
Thomas Rast wrote: [1]
@@ -100,52 +100,32 @@ merge commit. This behavior can be suppressed with the `--no-ff` option.-HOW MERGE WORKS------------------A merge is always between the current `HEAD` and one or more-commits (usually a branch head or tag).+TRUE MERGE+---------- Except in a fast-forward merge (see above), the branches to be merged must be tied together by a merge commit that has both of them as its parents.-The rest of this section describes this "True merge" case.--The chosen merge strategy merges the two commits into a single-new source tree.-When things merge cleanly, this is what happens:--1. The results are updated both in the index file and in your- working tree;-2. Index file is written out as a tree;-3. The tree gets committed; and-4. The `HEAD` pointer gets advanced.-Because of 2., we require that the original state of the index-file matches exactly the current `HEAD` commit; otherwise we-will write out your local changes already registered in your-index file along with the merge result, which is not good.-Because 1. involves only those paths differing between your-branch and the branch you are merging-(which is typically a fraction of the whole tree), you can-have local modifications in your working tree as long as they do-not overlap with what the merge updates.+A merged version reconciling the changes from all branches to be+merged is committed, and your `HEAD`, index, and working tree are+updated to it. It is possible to have modifications in the working+tree as long as they do not overlap; the update will preserve them.-When there are conflicts, the following happens:+When it is not obvious how to reconcile the changes, the following+happens:-1. `HEAD` stays the same.--2. Cleanly merged paths are updated both in the index file and+1. The `HEAD` pointer stays the same.+2. The `MERGE_HEAD` ref is set to point to the other branch head.+3. Paths that merged cleanly are updated both in the index file and in your working tree.--3. For conflicting paths, the index file records up to three- versions; stage1 stores the version from the common ancestor,- stage2 from `HEAD`, and stage3 from the other branch (you+4. For conflicting paths, the index file records up to three+ versions: stage 1 stores the version from the common ancestor,+ stage 2 from `HEAD`, and stage 3 from `MERGE_HEAD` (you can inspect the stages with `git ls-files -u`). The working tree files contain the result of the "merge" program; i.e. 3-way- merge results with familiar conflict markers `<<< === >>>`.--4. No other changes are done. In particular, the local+ merge results with familiar conflict markers `<<<` `===` `>>>`.+5. No other changes are made. In particular, the local modifications you had before you started merge will stay the same and the index entries for them stay as they were, i.e. matching `HEAD`.
From: Thomas Rast <hidden> Date: 2016-06-15 22:48:05
On Saturday 23 January 2010 10:25:51 Jonathan Nieder wrote:
Jonathan Nieder (7):
Documentation: merge: move configuration section to end
Documentation: suggest `reset --merge` in How Merge Works section
Documentation: merge: move merge strategy list to end
Documentation: merge: add an overview
Documentation: emphasize when git merge terminates early
Documentation: merge: add a section about fast-forward
Documentation: simplify How Merge Works
[and in the other thread]
Jonathan Nieder (1):
Documentation: merge: use MERGE_HEAD to refer to the remote branch
Thanks Jonathan! Ack on all of them.
I still had the following patches in my little documentation queue:
Jonathan Nieder (2):
Documentation: git gc packs refs by default now
Documentation: tiny git config manual tweaks
Thomas Rast (2):
Documentation: show-files is now called git-ls-files
Documentation: emphasise 'git shortlog' in its synopsis
I actually forgot to post the last one, which I'll do shortly, but
it's trivial so I just included it at the bottom.
Junio, I gathered all of the above patches and pushed them again to
git://repo.or.cz/git/trast.git doc-style/for-next
If that's ok and you merge it, I'll declare this the end of this
little topic. Admittedly it grew a bit outside the original area of
style fixes into a half-rewrite of git-merge(1).
-- 8< --
Subject: [PATCH] Documentation: emphasise 'git shortlog' in its synopsis
The accepted style in the SYNOPSIS section is for a command to be
'emphasised'. Do so for the git-shortlog(1) manpage.
Signed-off-by: Thomas Rast <redacted>
From: Raja R Harinath <hidden> Date: 2016-06-15 22:48:14
Hi,
Jonathan Nieder [off-list ref] writes:
[snip]
+Assume the following history exists and the current branch is
+"`master`":
+
+------------
+ A---B---C topic
+ /
+ D---E---F---G master
+------------
+
+Then "`git merge topic`" will replay the changes made on the
+`topic` branch since it diverged from `master` (i.e., `E`) until
+its current commit (`C`) on top of `master`, and record the result
+in a new commit along with the names of the two parent commits and
+a log message from the user describing the changes.