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

Re: [PATCH v3] checkout: eliminate unnecessary merge for trivial checkout

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 24, 2016, 18:26 UTC
Message-ID
<xmqqd1jtyx01.fsf@gitster.mtv.corp.google.com>
In-Reply-To
<99A866BEF8944598A50C6E061A703297@PhilipOakley>
"Philip Oakley" <philipoakley@iee.org> writes:
Show 25 quoted lines
>> > >"git checkout -b foo" (without -f -m or <start_point>) is defined in
>> > >the manual as being a shortcut for/equivalent to:
>> > >
>> > >        (1a) "git branch foo"
>> > >        (1b) "git checkout foo"
>> > >
>> > >However, it has been our experience in our observed use cases and all
>> > >the existing git tests, that it can be treated as equivalent to:
>> > >
>> > >        (2a) "git branch foo"
>> > >        (2b) "git symbolic-ref HEAD refs/heads/foo"
>> > >...
>> > >
>> > I am still not sure if I like the change of what "checkout -b" is this
>> > late in the game, though.
>>
>> ...
>> That said, you're much more on the frontline of receiving negative
>> feedback about doing that than I am. :)  How would you like to
>> proceed?
>
> I didn't see an initial confirmation as to what the issue really
> was. You indicated the symptom ('a long checkout time'), but then we
> missed out on hard facts and example repos, so that the issue was
> replicable.

I took it as a given, trivial and obvious optimization opportunity, that it is wasteful having to traverse two trees to consolidate and reflect their differences into the working tree when we know upfront that these two trees are identical, no matter what the overhead for doing so is.

Show 7 quoted lines
> At the moment there is the simple workaround of an alias that executes
> that two step command dance to achieve what you needed, and Junio has
> outlined the issues he needed to be covered from his maintainer
> perspective (e.g. the detection of sparse checkouts). Confirming the
> root causes would help in setting a baseline.
>
> I hope that is of help - I'd seen that the discussion had gone quiet.
Some of the problems I have are:
 (1) "git checkout -b NEW", "git checkout", "git checkout HEAD^0"
     and "git checkout HEAD" (no other parameters to any of them)
     ought to give identical index and working tree.  It is too
     confusing to leave subtly different results that will lead to
     hard to diagnose bugs for only one of them.
 (2) The proposed log message talks only about "performance
     optimization", while the purpose of the change is more about
     changing the definition of what "git checkout -b NEW" is from
     "git branch NEW && git checkout NEW" to "git branch NEW && git
     symbolic-ref HEAD refs/heads/NEW".  The explanation in a Ben's
     later message <007401d21278$445eba80$cd1c2f80$@gmail.com> does
     a much better job contrasting the two.
 (3) I identified only one difference as an example sufficient to
     point out why the patch provided is not a pure optimization but
     behaviour change.  Fixing that example alone to avoid change in
     the behaviour is trivial (see if the "info/sparse-checkout"
     file is present and refrain from skipping the proper checkout),
     but a much larger problem is that I do not know (and Ben does
     not, I suspect) know what other behaviour changes the patch is
     introducing, and worse, the checks are sufficiently dense too
     detailed and intimate to the implementation of unpack_trees()
     that it is impossible for anybody to make sure the exceptions
     defined in this patch and updates to other parts of the system
     will be kept in sync.

So my inclination at this point, unless we see somebody invents a clever way to solve (3), is that any change that violates (1), i.e. as long as the patch does "Are we doing '-b NEW'? Then we do something subtly different", is not acceptable, and solving (3) in a maintainable way smells like quite a hard thing to do. But it would be ideal if (3) is solved cleanly, as we will then not have to worry about changing behaviour at all and can apply the optimization for all of the four cases equally. As a side effect, that approach would solve problem (2) above.

If we were to punt on keeping the sanity (1) and introduce a subtly different "create a new branch and point the HEAD at it", an easier way out may be be one of

 1. a totally new command, e.g. "git branch-switch NEW" that takes
    only a single argument and no other "checkout" options, or
 2. a new option to "git checkout" that takes _ONLY_ a single
    argument and incompatible with any other option or command line
    argument, or
 3. an alias that does "git branch" followed by "git symbolic-ref".
Neither of the first two sounds palatable, though.
        
Previous: Philip OakleyNext: Philip Oakley
Message 10 of 11 in “checkout: eliminate unnecessary merge for trivial checkout”
  1. checkout: eliminate unnecessary merge for trivial checkoutBen Peart, Sep 13, 2016
  2. Junio C HamanoSep 13, 2016
  3. Oleg TaranenkoSep 14, 2016
  4. Junio C HamanoSep 14, 2016
  5. Ben PeartSep 19, 2016
  6. Junio C HamanoSep 19, 2016
  7. Junio C HamanoSep 19, 2016
  8. Ben PeartSep 21, 2016
  9. Philip OakleySep 24, 2016
  10. Junio C HamanoSep 24, 2016
  11. Philip OakleySep 24, 2016

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.