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

Re: two-way merge corner case bug

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 1, 2013, 16:57 UTC
Message-ID
<7va9qngisg.fsf@alter.siamese.dyndns.org>
In-Reply-To
<20130301092201.GA17254@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
Show 5 quoted lines
> PS I wonder if the "initial_checkout" hack can just go away under this
>    new rule. Although we don't seem to use "o->reset" for the initial
>    checkout. Which seems kind of weird. I would think the initial
>    checkout would actually just be a oneway merge. Is the point to try
>    to leave any existing working tree contents untouched or something?

An initial checkout is *supposed* to happen in an empty working tree, so if we code it not to overwrite an existing path in the working tree, the user cannot lose possibly precious contents with an mistaken initial checkout (they will instead appear as modified relative to the index), while in the normal case we will write out the contents from the HEAD through the index. We could attempt "we do not have to if the user behaves, but with this we could help misbehaving users" if we used twoway merge for an initial checkout.

Having said that, I notice that in the normal codepath (e.g. "git clone" without the "--no-checkout" option) we no longer use twoway merge for the initial checkout. Back when "git clone" was a scripted Porcelain, I think we used to do a twoway read-tree. It may be that we broke it when "clone" was rewritten in C, but the breakage is to the "we do not have to..." thing, so it may not be a big deal.

The only case that matters in today's code is "git checkout" (without any option or argument) immediately after "git clone -n", I think. The special casing for this initial checkout in twoway merge is needed because we go from HEAD to HEAD in that case, and we do not want to keep the artificial local removals from the index; we start from not even having the $GIT_INDEX_FILE, so without the special case all paths appear to have been "rm --cached", which is usually not what the user would want to see ;-)

> ... My worry would be that somebody is
> using "--reset" but expecting the removal to be carried through
> (technically, "--reset" is documented as "-m but discard unmerged
> entries", but we are not really treating it that way here).
I've checked all in-tree uses of "read-tree --reset -u".

Nobody seems to use that combination, either from scripts or from C (i.e. when opts.update==1 and opts.merge==1, opts.reset is not set) with a twoway merge, other than "git am --abort/--skip".

Previous: Jeff KingNext: Jeff King
Message 5 of 10 in “two-way merge corner case bug”
  1. Junio C HamanoFeb 26, 2013
  2. Jeff KingFeb 26, 2013
  3. Junio C HamanoFeb 26, 2013
  4. Jeff KingMar 1, 2013
  5. Junio C HamanoMar 1, 2013
  6. Jeff KingMar 1, 2013
  7. Junio C HamanoMar 1, 2013
  8. Jeff KingMar 1, 2013
  9. Junio C HamanoMar 1, 2013
  10. Jeff KingMar 2, 2013

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.