git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Could this be done simpler?

From
MAMatthias Andree <matthias.andree@gmx.de>
Date
Jun 25, 2009, 21:54 UTC
Message-ID
<op.uv3ogqin1e62zd@merlin.emma.line.org>
In-Reply-To
<7v3a9ogr8f.fsf@alter.siamese.dyndns.org>
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
Previous: Junio C HamanoNext: Junio C Hamano
Message 6 of 15 in “Could this be done simpler?”
  1. Linus TorvaldsJun 24, 2009
  2. Junio C HamanoJun 25, 2009
  3. Randal L. SchwartzJun 25, 2009
  4. Matthias AndreeJun 25, 2009
  5. Junio C HamanoJun 25, 2009
  6. Matthias AndreeJun 25, 2009
  7. Junio C HamanoJun 27, 2009
  8. Junio C HamanoJun 25, 2009
  9. Michael J GruberJun 25, 2009
  10. Christian CouderJun 25, 2009
  11. Christian CouderJun 25, 2009
  12. Junio C HamanoJun 25, 2009
  13. Linus TorvaldsJun 25, 2009
  14. Junio C HamanoJun 25, 2009
  15. Christian CouderJun 25, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.