branch: let inherit track a remote-tracking start point
PATCH 1/1 branch: let inherit track a remote-tracking start point
From: Harald Nordgren <[email protected]>
With branch.autoSetupMerge=inherit, "git switch topic" creates a local topic branch from origin/topic with no upstream, and warns that no remote is set. "git switch -c topic origin/topic" and an explicit "--track=inherit" do the same.
A remote-tracking branch has no upstream of its own to copy. Make inherit use it as the upstream directly, as the default "true" does, so that inherit sets up tracking in every case the default does.
---
branch: let inherit track a remote-tracking start point
With branch.autoSetupMerge=inherit, make git switch -c new_branch upstream/master work without a warning, and sets the remote branch upstream/master as the upstream.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2450%2FHaraldNordgren%2Fhn%2Fbranch-inherit-remote-tracking-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2450/HaraldNordgren/hn/branch-inherit-remote-tracking-v1
Pull-Request: https://github.com/git/git/pull/2450
Documentation/config/branch.adoc | 2 +- Documentation/git-branch.adoc | 4 +++- branch.c | 3 +++ t/t2060-switch.sh | 17 +++++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-)
Documentation/config/branch.adoc +1 -1
@@ -10,7 +10,7 @@ `always`;; automatic setup is done when the starting point is either a local branch or remote-tracking branch `inherit`;; if the starting point has a tracking configuration, it is copied to the new - branch + branch. A remote-tracking starting point is tracked directly, as with `true`. `simple`;; automatic setup is done only when the starting point is a remote-tracking branch and the new branch has the same name as the remote branch.
Documentation/git-branch.adoc +3 -1
@@ -280,7 +280,9 @@ remove it anyway. The exact upstream branch is chosen depending on the optional argument: `-t`, `--track`, or `--track=direct` means to use the start-point branch itself as the upstream; `--track=inherit` means to copy the upstream -configuration of the start-point branch. +configuration of the start-point branch. A remote-tracking start-point +has no upstream of its own, so `--track=inherit` uses it as the upstream +directly. + The `branch.autoSetupMerge` configuration variable specifies how `git switch`, `git checkout` and `git branch` should behave when neither `--track` nor
branch.c +3 -0
@@ -263,6 +263,9 @@ static void setup_tracking(const char *new_ref, const char *orig_ref,if (!track)BUG ("asked to set up tracking, but tracking is disallowed" ); +if (track ==BRANCH_TRACK_INHERIT && !starts_with (orig_ref,"refs/heads/" )) + track =BRANCH_TRACK_REMOTE ; +memset (&tracking,0 ,sizeof (tracking)); tracking.spec.dst = (char *)orig_ref; tracking.srcs = &tracking_srcs;
t/t2060-switch.sh +17 -0
@@ -146,6 +146,23 @@ test_expect_success 'tracking info copied with autoSetupMerge=inherit' ' test_cmp_config "" --default "" branch.main2.merge ' +test_expect_success 'autoSetupMerge=inherit tracks a remote-tracking start point' ' + git clone . downstream && + ( + cd downstream && + git config branch.autoSetupMerge inherit && + git switch -c new_branch origin/main && + git status >../actual && + cat >expect <<-EOF && + On branch new_branch + Your branch is up to date with ${SQ}origin/main${SQ}. + + nothing to commit, working tree clean + EOF + test_cmp expect ../actual + ) +' + test_expect_success 'switch back when temporarily detached and checked out elsewhere ' ' test_when_finished " git worktree remove wt1 ||:
base-commit: f57c9a73884400380bddd172acc88b569834f909
Signature · 1 line
gitgitgadget
Documentation/config/branch.adoc line 13
Quoted 3 lines · Harald Nordgren via GitGitGadget
inherit;; if the starting point has a tracking configuration, it is copied to the newDocumentation/config/branch.adoc +1
-1- branch + branch. A remote-tracking starting point is tracked directly, as with `true`.
That is "A remote-tracking branch given as a starting point", not "A remote-tracking starting point". Don't abbreviate and drop "branch".
If a starting point is not a remote-tracking branch, shouldn't the same thing happen, by the way? IOW, shouldn't the updated text and behaviour be more like
inherit;; if the starting point has a tracking configuration, it is copied to the new branch. Otherwise, the new branch is set to track the starting point itself.
I am not sure if it is the users of inherit want that forking a new branch from something that they know is *not* tracking anything suddenly starts to track the starting point (whether it is a remote-tracking branch or something else).
Looking at the originating commit d3115660b4 (branch: add flags and config to inherit tracking, 2021-12-20), it only talks about what they want to do when the starting point does track something, and forgets to say what they want when it does not track anything (the author CC'ed in case he retains the memory of the motivation from 5 years ago), but if you ask me _now_, not doing anything, i.e., the behaviour the old commit happened to have implemented without explanation does sound like the right thing to do.
What we should do if this change of behaviour turns out to be undesirable?
Perhaps inherit should gain a synonym inherit-or-ignore for those who prefer the current behaviour, and we want two extra behaviours, inherit-or-fail that complains and dies if the specified starting point does not have anything for the new branch to inherit, and inherit-or-direct that uses the fallback definition, or something?
Quoted 9 lines · Junio C Hamano
Documentation/config/branch.adoc line 13
Quoted 3 lines · Harald Nordgren via GitGitGadget
inherit;; if the starting point has a tracking configuration, it is copied to the newDocumentation/config/branch.adoc +1
-1- branch + branch. A remote-tracking starting point is tracked directly, as with `true`.That is "A remote-tracking branch given as a starting point", not "A remote-tracking starting point". Don't abbreviate and drop "branch".
Thanks!
Quoted 4 lines
I am not sure if it is the users of
inheritwant that forking a new branch from something that they know is *not* tracking anything suddenly starts to track the starting point (whether it is a remote-tracking branch or something else).
For me it's simple, only tracking when the starting point is a remote branch.
Quoted 12 lines
Looking at the originating commit
d3115660b4(branch: add flags and config to inherit tracking, 2021-12-20), it only talks about what they want to do when the starting point does track something, and forgets to say what they want when it does not track anything (the author CC'ed in case he retains the memory of the motivation from 5 years ago), but if you ask me _now_, not doing anything, i.e., the behaviour the old commit happened to have implemented without explanation does sound like the right thing to do.What we should do if this change of behaviour turns out to be undesirable?
Quoted 6 lines
Perhaps
inheritshould gain a synonyminherit-or-ignorefor those who prefer the current behaviour, and we want two extra behaviours,inherit-or-failthat complains and dies if the specified starting point does not have anything for the new branch to inherit, andinherit-or-directthat uses the fallback definition, or something?
Seems quite overkill for the relatively small problem this is solving. But it would be interesting to hear the original author's POV.
Harald
Quoted 21 lines · Harald Nordgren
Quoted 8 lines · Junio C Hamano
Looking at the originating commit
d3115660b4(branch: add flags and config to inherit tracking, 2021-12-20), it only talks about what they want to do when the starting point does track something, and forgets to say what they want when it does not track anything (the author CC'ed in case he retains the memory of the motivation from 5 years ago), but if you ask me _now_, not doing anything, i.e., the behaviour the old commit happened to have implemented without explanation does sound like the right thing to do.Quoted 8 lines
What we should do if this change of behaviour turns out to be undesirable?
Perhapsinheritshould gain a synonyminherit-or-ignorefor those who prefer the current behaviour, and we want two extra behaviours,inherit-or-failthat complains and dies if the specified starting point does not have anything for the new branch to inherit, andinherit-or-directthat uses the fallback definition, or something?
Quoted 2 lines
Seems quite overkill for the relatively small problem this is solving. But it would be interesting to hear the original author's POV.
Overkill, possibly, but easier to expand in a compatible way over time (other than piling new modifier --options on top, which makes the CLI confusing IMO).
Quoted 2 lines · Ben Knoble
Overkill, possibly, but easier to expand in a compatible way over time (other than piling new modifier --options on top, which makes the CLI confusing IMO).
Yes, exactly. A myopic initial design can easily paint us into a UI corner from which we cannot easily escape without awkward options. That is why I care.
Thanks.
Quoted 13 lines · Junio C Hamano
Documentation/config/branch.adoc line 13
Quoted 3 lines · Harald Nordgren via GitGitGadget
inherit;; if the starting point has a tracking configuration, it is copied to the newDocumentation/config/branch.adoc +1
-1- branch + branch. A remote-tracking starting point is tracked directly, as with `true`.That is "A remote-tracking branch given as a starting point", not "A remote-tracking starting point". Don't abbreviate and drop "branch".
If a starting point is not a remote-tracking branch, shouldn't the same thing happen, by the way? IOW, shouldn't the updated text and behaviour be more like
Quoted 8 lines
inherit;; if the starting point has a tracking configuration, it is copied to the new branch. Otherwise, the new branch is set to track the starting point itself.I am not sure if it is the users of
inheritwant that forking a new branch from something that they know is *not* tracking anything suddenly starts to track the starting point (whether it is a remote-tracking branch or something else).
For me it depends on what I'm forking from. If I create a branch on my desktop, push it to my server and then create a local branch from that on my laptop, I normally want the new branch to track something like origin/master rather than the starting point. However, if I create a new branch from origin/master then I do want to track the starting point. So it is not clear to me that the behavior proposed here is better than the current behavior, but equally I don't think it is any worse. Having some way of saying "set up tracking when the starting point matches one of these patterns" might be useful, but I find the tracking options to "git switch -c" so confusing I normally just run "git branch --set-upstream-to" afterwards to set the upstream I want.
Thanks
Phillip
Quoted 18 lines
Looking at the originating commit
d3115660b4(branch: add flags and config to inherit tracking, 2021-12-20), it only talks about what they want to do when the starting point does track something, and forgets to say what they want when it does not track anything (the author CC'ed in case he retains the memory of the motivation from 5 years ago), but if you ask me _now_, not doing anything, i.e., the behaviour the old commit happened to have implemented without explanation does sound like the right thing to do.What we should do if this change of behaviour turns out to be undesirable?
Perhaps
inheritshould gain a synonyminherit-or-ignorefor those who prefer the current behaviour, and we want two extra behaviours,inherit-or-failthat complains and dies if the specified starting point does not have anything for the new branch to inherit, andinherit-or-directthat uses the fallback definition, or something?
Quoted 11 lines
For me it depends on what I'm forking from. If I create a branch on my desktop, push it to my server and then create a local branch from that on my laptop, I normally want the new branch to track something like origin/master rather than the starting point. However, if I create a new branch from origin/master then I do want to track the starting point. So it is not clear to me that the behavior proposed here is better than the current behavior, but equally I don't think it is any worse. Having some way of saying "set up tracking when the starting point matches one of these patterns" might be useful, but I find the tracking options to "git switch -c" so confusing I normally just run "git branch --set-upstream-to" afterwards to set the upstream I want.
I don't actually use 'git switch -c', I just used that in the example because it's the *modern* way to do things. In reality I always run 'git checkout -b'. I agree about set-upstream-to, there is probably no single terminal command that I run more than
git branch --set-upstream-to=origin
Your example got me thinking. Maybe we should go the other way? If we can inherit from the branch we are coming from, should we do that as first prio? Because of the --set-upstream-to=origin usage, we will likely already be tracking the right one. So
git checkout -b first_branch
git branch --set-upstream-to=origin/master git checkout -b new_branch origin/another_branch
could give us a 'new_branch' that tracks what 'first_branch' tracked, i.e. 'origin/master'. Maybe as a fallback, we could have the new behavior from my v1, so if 'first_branch' has no tracking branch, then
git checkout -b first_branch
git checkout -b new_branch origin/another_branch
falls back to 'new_branch ' tracking 'origin/another_branch' instead? Or not, maybe this fallback is just bad?
Harald
Quoted 17 lines · Harald Nordgren
Quoted 12 lines
For me it depends on what I'm forking from. If I create a branch on my desktop, push it to my server and then create a local branch from that on my laptop, I normally want the new branch to track something like origin/master rather than the starting point. However, if I create a new branch from origin/master then I do want to track the starting point. So it is not clear to me that the behavior proposed here is better than the current behavior, but equally I don't think it is any worse. Having some way of saying "set up tracking when the starting point matches one of these patterns" might be useful, but I find the tracking options to "git switch -c" so confusing I normally just run "git branch --set-upstream-to" afterwards to set the upstream I want.
Quoted 6 lines
I don't actually use 'git switch -c', I just used that in the example because it's the *modern* way to do things. In reality I always run 'git checkout -b'. I agree about
set-upstream-to, there is probably no single terminal command that I run more thangit branch --set-upstream-to=origin
Curious. I typically do
git switch -c topic origin
and am happy. (When creating a branch that *doesn’t* start at origin but still should track it, I use « branch -u » as shown, too.)