Am 25.06.2009, 19:25 Uhr, schrieb Junio C Hamano <gitster@xxxxxxxxx>:
Matthias Andree <matthias.andree@xxxxxx> writes:
Could we ditch the current git-pull --append description? Can then
please somebody rewrite this paragraph? This somebody must have
completely understood
(1) what this feature is good for (practically speaking)
(2) how it works (technically speaking, to provide reference
information)
That would be much more useful, and the use would last longer :-)
I don't dare ask Junio directly.
But if you run blame and mailing list archive search, you would discover
that "fetch --append" was my invention. After all, the entire Octopus
idea originates from me at 211232b (Octopus merge of the following five
patches., 2005-05-05). It is interesting to realize that it was actually
a Pentapus made on the day of 5/5/5 ;-)
Fair enough, but I hadn't looked at who wrote it because more people than
just the original author can be able to write it. In fact, I've drifted
into doing that. Suggestions at the very end if you're not interested in
the rationale, but if you are only interested the solution. :-)
I've seen your later message on the octopus merges, and therefore suggest
that we get this --append stuff documented first.
I thought I was going to take blame on the incomprehensive documentation
and pass it on to me being non-native speaker/writer of English, but the
situation is bit funny. Documentation/fetch-options.txt says this:
Neither am I a native writer, why bother… it's more important to write
things clearly than to polish things, and writing something correctly from
the beginning is a very hard problem. Writing something that works, and
later polish, are two simpler problems.
Language isn't the concern here, but understanding the feature is.
-a::
--append::
Append ref names and object names of fetched refs to the
existing contents of `.git/FETCH_HEAD`. Without this
option old data in `.git/FETCH_HEAD` will be overwritten.
Perhaps there has a cut&paste error? I haven't looked.
Nevermind, that's irrelevant. The key problem is that Linus could not tell
from this description that it was the feature he was looking for. So let's
fix that and make documentation clearer. Particularly: let's fix the
git-fetch manpage, let's untangle it from git-pull, and let git-pull
reference the git-fetch description rather than copy it.
This quoted section "Append ref... overwritten." explains how the beast
works technically. So what? What is it good for? What can I do with it?
You made FETCH_HEAD the focus point of the description, but that's not the
point. (It may be the point of the implementation, but I don't care).
In order for a reader to understand this feature from the docs, he must
know what FETCH_HEAD is good for in the whole git context (as a
requisite), but that is just a diversion, not the key point.
The point is that you can mark several branches for merge, or in other
words, accumulate other tips/heads that you want to merge, before doing
the merge. It is useful for merges of more than one branch at a time,
"octopus merges" or similar.
Preface: the next comments don't mean to criticize what you are
presenting, but just to select which should and which shouldn't go in the
reference manual, and if yes, where. I think we've got the whole
description organized backwards, let's fix that, too.
(2) "git fetch" leaves list of <commit object, repo, branch, flag> for
each ref fetched from repository in .git/FETCH_HEAD, where flag
tells
if it is meant for merging. "git pull" runs "git fetch", reads from
this file to learn which ones to pass to "git merge". The
information also is given to "git fmt-merge-msg" to come up with the
message.
This is a technical detail - this belongs into a separate FETCH_HEAD
document in section 5 (file formats).
Usually "git fetch" first empties the existing contents of the file
and stores the list of refs it fetched. With --append, it doesn't
empty the file; refs fetched by the previous invocation of "git
fetch" will be kept and the refs it fetched are appenede.
OK. Also for later, so I know how it differs from regular behaviour.
So, this is technically more comprehensive, but that leaves the old
question unanswered - what is FETCH_HEAD good for?
Let's change roles (or perspective) for a moment, for the sake of clarity
and usability: I am just a Git user. I don't want to hack Git. I couldn't
care less about implementation details such as FETCH_HEAD, I only need to
know how I can tell Git to merge branches foo, bar, baz into master in one
single merge.
So:
$ git fetch one a
$ git fetch --append two b
$ git pull --apend three c
will end up having all the three refs from different repositories in
.git/FETCH_HEAD. I.e.
branch a, from repo one, to be merged
branch b, from repo two, to be merged
branch c, from repo three, to be merged
when "git fetch" run by the the last "git pull" returns. "git pull"
reads the file and learn what to give to "git fmt-merge-msg" (to
come
up with the message for the merge commit) and "git merge" (to create
the merge commit).
Let's leave git pull out of this picture. If you mention it, you must
explain the interaction between pull and fetch, but you don't want this
here. You only want to explain the interaction between fetching more than
one branch and merging all of them.
"git pull" (at bird eye's view) is just a short-cut for "git fetch
something" and "git merge with somehow configured branch" (somehow =
implicitly through setting up tracking branches, or clone), or explicitly
through git branch, or git remote -- let's leave this aside.
So, here's my first stab at it (just content, not ASCIIDOC markup, as I'm
not fluent in ASCIIDOC and you can easily do that when merging later) -
feel free to correct edit, rewrite, amend to it...
I'm not sure
FETCH_HEAD(5)
-------------------------------------------------
This file in the git directory records which heads have been downloaded,
from where, and for what purpose. Each line in this file is one
TAB-delimited record with three fields. From left to right, these fields
contain:
1 - the commit of the remote head
2 - "not-for-merge" if the branch is not meant to be merged, otherwise,
this field remains empty
3 - branch 'xxx' of UUU, where xxx and UUU are the remote repository's
refname and base URL, respectively.
This file is written by git-fetch and used by git-merge.
-------------------------------------------------
git-fetch(1)
-------------------------------------------------
...
-a::
--append::
This option allows you to fetch and accumulate multiple remote refs for
future merging. Normally, git-fetch records the latest fetch for a later
merge, by writing them to .git/FETCH_HEAD (there can be multiple recorded
heads in FETCH_HEAD although the name suggests there were just one). The
--append option lets git-fetch keep, rather than delete, prior contents of
the file. This can be ueful when consolidating multiple topic branches in
one single merge (a so-called octopus merge, see git-merge(1)). Example:
$ git fetch one a
$ git fetch --append two b
$ git pull --append three c
(git pull first runs git fetch --append three c, and then git merge with
all remotes that have been recorded for merging in .git/FETCH_HEAD).
...
You can use git-pull as short-cut for the all too common
"git-fetch"-"git-merge" sequence.
-------------------------------------------------
NOTE: git-fetch accepts command lines without refspec. These mark fetched
heads as "not-for-merge". IOW, a refspec is needed that heads are marked
as for-merge. I haven't found this documented in git-fetch.
--
Matthias Andree
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html