threads / discuss / 57364

branch.autoSetupMerge option for "if name matches only"?

Subject: branch.autoSetupMerge option for "if name matches only"?

## tl;dr

3 messages between Feb 3, 2022 and Feb 24, 2022.

replies: 2people: 2as markdown or json

Tao Klerks· Feb 3, 2022, 18:58 UTC · lore
Hi folks,

In trying to recommend sane simple understandable git flows for large numbers of (often not git-proficient) users, I've found upstream tracking branches to be a sticky area.

The main problem is that when users intentionally create a new branch "test1" from origin/master, for example, they automatically get upstream tracking... but after they've pushed their new branch to the remote, they (unless they do something "wrong") typically have tracking switched to "origin/test1" (after a weird error about not pushing to a differently-named upstream - because they have push.default set to "simple", the safe default - unless they're using a GUI that sweeps this under the rug). So the behavior of "pull" changes dramatically, from the user's perspective, after the first time they push. Until that point, the system is behaving "weird".

On the other hand, when another user wants to work on "test1" directly, they branch from "origin/test1", they get upstream tracking, and everything is normal/predictable.

I *think* the simplest / most understandable behavior for most users would be a variation on the current branch.autoSetupMerge=true behavior, except *only set up tracking if the local branch name matches*.

This new branch.autoSetupMerge behavior (dare we call it "simple", to match push.default?) would mean that when branching from origin/master to test1, you would not get an upstream. Pull would say something like "hey, you haven't pushed yet", and everything would be understandable.

Is this a scheme that makes sense to people here?

Alternatively, another workable option for my not-so-sophisticated users would be something like branch.autoSetupMerge=current, which would simply always assume the same-name branch on the same remote. If this were a new branch, initial pulls would say "but there's no such branch on the remote!", and the first push would be even simpler, succeeding without the current surprising "The current branch has no upstream branch -0 run this slightly-more-complex command" message.

Are my users the only ones who get caught out by the default tracking behavior when branching from a different upstream branch (but *expect* tracking when creating a local instance of a remote branch)?

Thanks, Tao

Xavier Morel· Feb 9, 2022, 13:46 UTC · re: Tao Klerks · lore

Re: branch.autoSetupMerge option for "if name matches only"?

I found this message when trying to see if someone had already suggested something along those lines.

In fact I would be even more restrictive: what I wanted to propose was to only automatically setup the merge on implicit remote tracking branches, that is:

     git switch foo

if there is no such branch locally will look for the corresponding branch in the remotes, and will create a matching local one. In that case it makes a lot of sense to create a remote-tracking branch: when implicitly checking out a remote branch, it's likely the goal is to track it.

The issue is that
     git switch -c bar foo

will do the same, despite explicitely creating a differently named branch, which is probably some sort of feature which needs to be remote-ed somewhere else. If this issue is not caught immediately it is possible to push directly upstream by mistake.

Upon reading the documentation of `git switch` I actually believed this would behave correctly given `autoSetupMerge=false`:

     --guess, --no-guess
         If <branch> is not found but there does exist a tracking branch 
in exactly one remote (call it <remote>) with
         a matching name, treat as equivalent to
             $ git switch -c <branch> --track <remote>/<branch>

Because `--guess` is the default for the `git switch <name>` form, this description made me believe the tracking would be forced.

Sadly it is not so, setting `autoSetupMerge=false` will also disable automatic remote-tracking on guessed branch.

As far as I'm concerned, `git switch` actually behaving as documented would resolve the entire issue (especially if it were possible to disable `git checkout` somehow, such that I would have to force muscle memory).

This is made more annoying because
     git switch -t foo

*does not work*, frustratingly (if as documented, this time) `-t` implies `-c`. So it's not even possible to remember to type `git switch -t remotebranch` and then live happily with `autoSetupMerge=false`. This makes `autoSetupMerge=false` a lot more frustrating that necessary.

Tao Klerks· Feb 24, 2022, 16:47 UTC · re: Xavier Morel · lore

Re: branch.autoSetupMerge option for "if name matches only"?

Hi Xavier,
Thanks for the follow-up.
>I found this message when trying to see if someone had already suggested
> something along those lines.

Did you find any other related threads that could add context? I did not find anything when I looked.

> what I wanted to propose was to only automatically setup the merge on
> implicit remote tracking branches

While I understand this as a personal expectation/preference, that doesn't seem to align with the expectations of the "beginner users" that I interact with;

generally, they expect a branch that is "the local version of a remote branch" to behave one way, and a branch that "was 'branched' from the then-HEAD of a remote branch" to behave another way - regardless of whether a given user knows the "pretend I already have the branch locally / create it on-the-fly" syntax, or is explicit about saying "I want to work on (for example) master which I know is origin/master on the remote".

> As far as I'm concerned, `git switch` actually behaving as documented
> would resolve the entire issue

I'm not sure I understand this. I just tested and got exactly what I expected from the doc:

$ git -c merge.autosetupmerge=false switch -t origin/mybranch Branch 'mybranch' set up to track remote branch 'mybranch' from 'origin'. Switched to a new branch 'mybranch'

I agree being able to say "git switch mybranch", without the other side effects of merge.autosetupmerge=true, would be convenient... but then I'm arguing for a broader change and (in my opinion) better value of "merge.autosetupmerge" altogether :)

Fwiw, I submitted a patch introducing this "merge.autosetupmerge=simple" option earlier today, but no reactions yet. I don't know whether that's because project members disagree that there is inherent unnecessary complexity facing "beginners" in the current behavior, or disagree that this is a reasonable direction to reduce that complexity, or are frustrated with my spotty participation record in this mailing list, or the terrible quality of my C- and project-novice code, or simply haven't looked at this topic yet!

The patch series is titled "adding new branch.autosetupmerge option "simple"".

Thanks again, Tao

On Wed, Feb 9, 2022 at 2:46 PM Xavier Morel <xmo@odoo.com> wrote:
Show 54 quoted lines
>
> I found this message when trying to see if someone had already suggested
> something along those lines.
>
> In fact I would be even more restrictive: what I wanted to propose was
> to only automatically setup the merge on implicit remote tracking
> branches, that is:
>
>      git switch foo
>
> if there is no such branch locally will look for the corresponding
> branch in the remotes, and will create a matching local one. In that
> case it makes a lot of sense to create a remote-tracking branch: when
> implicitly checking out a remote branch, it's likely the goal is to
> track it.
>
> The issue is that
>
>      git switch -c bar foo
>
> will do the same, despite explicitely creating a differently named
> branch, which is probably some sort of feature which needs to be
> remote-ed somewhere else. If this issue is not caught immediately it is
> possible to push directly upstream by mistake.
>
> Upon reading the documentation of `git switch` I actually believed this
> would behave correctly given `autoSetupMerge=false`:
>
>      --guess, --no-guess
>          If <branch> is not found but there does exist a tracking branch
> in exactly one remote (call it <remote>) with
>          a matching name, treat as equivalent to
>
>              $ git switch -c <branch> --track <remote>/<branch>
>
> Because `--guess` is the default for the `git switch <name>` form, this
> description made me believe the tracking would be forced.
>
> Sadly it is not so, setting `autoSetupMerge=false` will also disable
> automatic remote-tracking on guessed branch.
>
> As far as I'm concerned, `git switch` actually behaving as documented
> would resolve the entire issue (especially if it were possible to
> disable `git checkout` somehow, such that I would have to force muscle
> memory).
>
> This is made more annoying because
>
>      git switch -t foo
>
> *does not work*, frustratingly (if as documented, this time) `-t`
> implies `-c`. So it's not even possible to remember to type `git switch
> -t remotebranch` and then live happily with `autoSetupMerge=false`. This
> makes `autoSetupMerge=false` a lot more frustrating that necessary.

← back to recent threads