Re: Could this be done simpler?
Am 25.06.2009, 19:25 Uhr, schrieb Junio C Hamano <gitster@pobox.com>:
Show 20 quoted lines
> Matthias Andree <matthias.andree@gmx.de> 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.
Show 7 quoted lines
> -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.
Show 7 quoted lines
> (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.
Show 18 quoted lines
> 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