Subject: Re: [PATCH v4] merge: new autosetupmerge option 'simple' for matching branches

From: Josh Steadmon <[email-masked]>
Date: Mon, 18 Apr 2022 11:15:28 -0700

On 2022.03.21 06:17, Tao Klerks via GitGitGadget wrote:
> From: Tao Klerks <[email-masked]>
> 
> With the default push.default option, "simple", beginners are
> protected from accidentally pushing to the "wrong" branch in
> centralized workflows: if the remote tracking branch they would push
> to does not have the same name as the local branch, and they try to do
> a "default push", they get an error and explanation with options.
> 
> There is a particular centralized workflow where this often happens:
> a user branches to a new local feature branch from an existing
> upstream branch, eg with "checkout -b feature1 origin/master". With
> the default branch.autosetupmerge configuration (value "true"), git
> will automatically add origin/master as the remote tracking branch.
> 
> When the user pushes with "git push", they get an error, and (amongst
> other things) a suggestion to run "git push origin HEAD". Eventually
> they figure out to add "-u" to change the tracking branch, or they set
> push.default to "current", or some tooling does one or the other of
> these things for them.
> 
> When one of their coworkers works on the same branch, they don't get
> any of that weirdness. They just "git checkout feature1" and
> everything works exactly as they expect, with the shared remote branch
> set up as remote tracking branch, and push and pull working out of the
> box.
> 
> The "stable state" for this way of working is that local branches have
> the same-name remote tracking branch (origin/feature1 in this
> example), and multiple people can work on that remote feature branch
> at the same time, trusting "git pull" to merge or rebase as required
> for them to be able to push their interim changes to that same feature
> branch on that same remote.
> 
> (merging from the upstream "master" branch, and merging back to it,
> are separate more involved processes in this flow).
> 
> There is a problem in this flow/way of working, however, which is that
> the first user, when they first branched from origin/master, ended up
> with the "wrong" remote tracking branch (different from the stable
> state). For a while, before they pushed (and maybe longer, if they
> don't use -u/--set-upstream), their "git pull" wasn't getting other
> users' changes to the feature branch - it was getting any changes from
> the remote "master" branch instead (a completely different class of
> changes!)
> 
> Any experienced git user will presumably say "well yeah, that's what
> it means to have the remote tracking branch set to origin/master!" -
> but that user didn't *ask* to have the remote master branch added as
> remote tracking branch - that just happened automatically when they
> branched their feature branch. They didn't necessarily even notice or
> understand the meaning of the "set up to track 'origin/master'"
> message when they created the branch - especially if they are using a
> GUI.
> 
> Looking at how to fix this, you might think "OK, so disable auto setup
> of remote tracking - set branch.autosetupmerge to false" - but that
> will inconvenience the *second* user in this story - the one who just
> wanted to start working on the feature branch. The first and second
> users swap roles at different points in time of course - they should
> both have a sane configuration that does the right thing in both
> situations.
> 
> Make these flows painless by introducing a new branch.autosetupmerge
> option called "simple", to match the same-name "push.default" option
> that makes similar assumptions.
> 
> This new option automatically sets up tracking in a *subset* of the
> current default situations: when the original ref is a remote tracking
> branch *and* has the same branch name on the remote (as the new local
> branch name).
> 
> With this new configuration, in the example situation above, the first
> user does *not* get origin/master set up as the tracking branch for
> the new local branch. If they "git pull" in their new local-only
> branch, they get an error explaining there is no upstream branch -
> which makes sense and is helpful. If they "git push", they get an
> error explaining how to push *and* suggesting they specify
> --set-upstream - which is exactly the right thing to do for them.
> 
> This new option is likely not appropriate for users intentionally
> implementing a "triangular workflow" with a shared upstream tracking
> branch, that they "git pull" in and a "private" feature branch that
> they push/force-push to just for remote safe-keeping until they are
> ready to push up to the shared branch explicitly/separately. Such
> users are likely to prefer keeping the current default
> merge.autosetupmerge=true behavior, and change their push.default to
> "current".

I think this is a good solution for relatively inexperienced users, and
I don't see any issues with the implementation or tests. However, I
wonder how users for whom this may be useful are going to discover this
option? I don't expect that such users are going to be watching Git's
release notes looking for new features such as this, or carefully
reading documentation changes.

In the discussion on v3 of this series, you mentioned you were thinking
about adding an advice setting to point users here; is there a reason
why that didn't make it into v4? It seems appropriate to me to add one,
perhaps at the point where a user with "autosetupmerge=true" would run
into a failure when trying to push?