Search code examples
gitgit-remotesmartgit

How to setup multiple tracking levels of branchs with git


I have a git local branch that tracked the remote svn trunk.

I created a new development branch and set the local branch to track it.

I want that the development branch will also track the svn/trunk something like:

from:
local branch > development branch

to:
local branch > development branch > svn/trunk

Is it possible to do it with git?

I'm using git version 2.14.3

git GUI - smartgit v18.1


Solution

  • No, this is not possible in Git. But it's also not that important (really!), because tracking a branch in Git just means that the one branch has the other set as its upstream:

    git branch --set-upstream-to=desired-upstream my-branch
    

    Each of your branches can have at most one upstream at any time. When your branch does have an upstream, the following occur:

    • git fetch with no arguments knows which other Git repository may contain commits to be fetched. Hence you can run git fetch instead of git fetch remote.

      But if you only have one remote named origin, as is pretty common, this doesn't really buy you anything since git fetch with no arguments will fetch from origin if it has nothing better from an upstream. In other words, git fetch already fetches from the (single) correct remote anyway. So having an upstream here did not buy you anything.

    • git merge and git rebase run with no additional arguments automatically know which remote-tracking name to use. This does buy you something, but if you'd like to have two upstreams, you would still have had to tell git merge or git rebase which upstream to use, so having to type git merge fred/xyzzy and git merge giselle/xyzzy isn't really much worse. In fact it's probably better: git merge upstream1 and git merge upstream2 are shorter to type, but is fred/xyzzy upstream #1, or is it upstream #2? Why not use the more memorable name?

    • Like the other two above, git pull—which just runs the other two, fetch first and then one of the other two commands—also knows what to use by default. I recommend that most Git users avoid git pull as it's meant to be a convenience command, but tends to be inconvenient at the worst times. If you avoid git pull, having it know things buys you nothing at all.

    • The default git push behavior, using the standard push.default setting of simple, is better. This does buy you something, but you probably should only be pushing to one other Git repository anyway, so you can pick that particular other Git repository as the (single) upstream for the branch.

    • Last, the git status command (which some other Git commands run, or run part of) becomes more informative, telling you how many commits you are ahead of and behind the chosen upstream. This includes git branch -v as well. I find this has significant value.

    Fortunately, there's a simple way to get the same information from the command line, and you can make an alias or script to do this for you. When git status says that you're "ahead 1" and/or "behind 3", it's running the equivalent of:

    git rev-list --count --left-right <local-name>...<upstream-name>
    

    For instance, with branch stash-exp having origin/master as its upstream, I can run:

    git rev-list --count --left-right stash-exp...origin/master
    

    and get the same two numbers (as raw numbers): the first is the "ahead" count and the second is the "behind" count. Note the three periods . here; this form of this command and options requires all three, while most commands mostly use the two-dot syntax instead.

    In summary, then, setting an upstream, so that some local branch name tracks either some remote-tracking name, or some other local branch name, has a very low cost (one command) and some noticeable benefits, so you should do it when it makes sense. But the benefits are not so huge as to need to have more than one upstream.