Subject: Re: [PATCH v3 10/21] checkout: split part of it to new command 'switch'

From: Phillip Wood <[email-masked]>
Date: Tue, 12 Mar 2019 11:06:17 +0000

Hi Elijah

On 11/03/2019 17:54, Elijah Newren wrote:
> A few other comments that I thought of while responding elsewhere in
> the thread that didn't make sense to include elsewhere...
> 
> On Fri, Mar 8, 2019 at 2:00 AM Nguyễn Thái Ngọc Duy <[email-masked]> wrote:
>>
>> +-m::
>> +--merge::
>> +       If you have local modifications to one or more files that are
>> +       different between the current branch and the branch to which
>> +       you are switching, the command refuses to switch branches in
>> +       order to preserve your modifications in context.  However,
>> +       with this option, a three-way merge between the current
>> +       branch, your working tree contents, and the new branch is
>> +       done, and you will be on the new branch.
>> ++
>> +When a merge conflict happens, the index entries for conflicting
>> +paths are left unmerged, and you need to resolve the conflicts
>> +and mark the resolved paths with `git add` (or `git rm` if the merge
>> +should result in deletion of the path).
> 
> Now that Phillip highlighted issues with -m and -f, it's hard not to
> wonder about other corner cases.  For example, what if the user made
> some changes, staged them, then made more changes, then tried to 'git
> checkout -m <other branch>'?  That's no longer a three-way merge, but
> four way.  How does that work?  Does it just rely on merge-recursive's
> (poorly defined) choice of when to bail out and when to permit such
> craziness?

If the two-way merge fails then it does 'git add -u' before calling 
merge_recursive(), then any merged paths are reset to the new HEAD 
(which throws away newly added files, it should keep anything that is 
not in HEAD or HEAD@{1}). So any staged changes are lost.

>> +--orphan <new-branch>::
>> +       Create a new 'orphan' branch, named `<new-branch>`, started from
>> +       `<start-point>` and switch to it. See explanation of the same
>> +       option in linkgit:git-checkout[1] for details.
> 
> Sigh...does this mean --orphan will remain broken?  It has always
> driven me crazy that it leaves you with a fully populated rather than
> an empty index.

I've always thought that was weird.

> It seemed broken to me before I figured out the
> special usecase,

I haven't figured it out yet - what is it?

Best Wishes

Phillip

> though it still seemed like the wrong default (an
> empty index wouldn't surprise due to the "orphan" name, but a full one
> does to those without the special usecase in mind).  Oh well, that's a
> much smaller battle than the big picture of getting switch and restore
> in place, and I don't want to derail the bigger picture; anything
> using --orphan is a somewhat special case anyway.
> 
>> +You can give the `-m` flag to the command, which would try a three-way
>> +merge:
>> +
>> +------------
>> +$ git switch -m mytopic
>> +Auto-merging frotz
>> +------------
>> +
>> +After this three-way merge, the local modifications are _not_
>> +registered in your index file, so `git diff` would show you what
>> +changes you made since the tip of the new branch.
> 
> ...even if the local modifications were registered in the index file
> before?  Is this why Phillip's "x" was missing and how it avoided
> doing a four-way merge?  I guess it kinda makes sense, view from this
> angle, but I'm not so sure I like it.  Hmm....
>