Today, I’d like to talk about tracking upstream branch in Git.
Here’re 3 possibilities to track upstream:
# Set upstream when pushing to remote git push -u origin topic # Set upstream without pushing it # with option -u / --set-upstream-to git branch -u origin/topic git branch --set-upstream-to=origin/topic
More detail is available in the following sections.
You can make you local branch track the upstream the first time you push that
--set-upstream allows to add upstream (tracking)
reference for every branch that is up to date or successfully pushed. For
example, my local repository is checkout in
issue-1: if I want to push it
origin and add upstream reference as
origin/issue-1, I can do:
$ git push -u origin issue-1
If you don’t want to push anything, you can also do it using
git-branch command. A local branch can track a remote branch using
git-branch with long option
--set-upstream-to=<upstream> or short option
-u <upstream>. The command sets up
branchname’s tracking information. If no
branchname is specified, then it defaults to the current branch. For example,
$ git branch -u origin/issue-1 Branch issue-1 set up to track remote branch issue-1 from origin.
… or longer option:
$ git branch --set-upstream-to=origin/issue-1 Branch issue-1 set up to track remote branch issue-1 from origin.
<upstream> is the combination of remote and branch without spaces:
Once the branch is tracked, the relationship can be verified via git-branch command in verbose list mode (twice ‘v’):
$ git branch -vv * issue-1 3646f49 [origin/issue-1] Initial commit master 3646f49 [origin/master] Initial commit
If you try to set upstream branch to a nonexistent one, you will see the
following error in your console. For example,
topic branch does not exist on
demo (topic) $ git branch -u origin/topic error: the requested upstream branch 'origin/topic' does not exist hint: hint: If you are planning on basing your work on an upstream hint: branch that already exists at the remote, you may need to hint: run "git fetch" to retrieve it. hint: hint: If you are planning to push out a new local branch that hint: will track its remote counterpart, you may want to use hint: "git push -u" to set the upstream config as you push.
You need to do a
git fetch or
git push -u depending on your situation, as
indicated by the hint.
Push Without Branch Specified
Is it possible to do
git pushwithout a branch specified?
Yes, it is possible. You can control the default behavior by setting
push.default in you Git config. It defines the action Git
push should take if no refsepc is given on the command line. In order to push
without branch specified, you can do set the mode to
current, which pushes the
current branch to update a branch with the same name on the receiving end:
$ git config push.default current
More information can be reached in
git-config. Personally, I don’t recommend it, because
without setting upstream, you lose comparison between local branch and its
upstream (behind commits, ahead commits). The
git pull command won’t be
possible without branch name neither:
demo (issue-1) $ git pull There is no tracking information for the current branch. Please specify which branch you want to merge with. See git-pull(1) for details. git pull <remote> <branch> If you wish to set tracking information for this branch you can do so with: git branch --set-upstream-to=origin/<branch> issue-1
Once upstream is defined, how this information is stored in Git?
master as an example, the relationship between the local branch
master and it upstream
origin/master is stored in
[branch "master"] remote = origin merge = refs/heads/master
As you can see, branch “master” has 2 properties:
merge. They are
also called as pattern
branch.master.merge defines, together with
the upstream branch for the given branch. It tells git-fetch, git-pull,
git-rebase which branch to merge and can also affect git-push. When in branch
master, it tells git-fetch the default refspec to be marked for merging in
FETCH_HEAD. The value is handled like the remote part of a refspec, and must
match a ref which is fetched from the remote given by
The merge information is used by git-pull (which at first call git-fetch) to
lookup the default branch for merging. Without this option, git-pull defaults
to merge the first refspec fetched. For more information, see git-config
--unset-upstream to unset an upstream:
$ git branch --unset-upstream [<branchname>]
The section of branch “master” in Git configuration file becomes empty:
$ cat .git/config ... [branch "master"]
During daily work, you can also do git-fetch with option
remove any remote-tracking references that no longer exist on the remote before
$ git fetch -p
The equivalent commands in JGit:
git branch -u origin/topic: None. This API does not exist in JGit.
git push -u origin topic: None. This API does not exist in JGit.
If you want to do the tracking, you need to handle it directly in Git
configuration. Like in
StoredConfig config = git.getRepository().getConfig(); config.setString(CONFIG_BRANCH_SECTION, "topic", "remote", "origin"); config.setString(CONFIG_BRANCH_SECTION, "topic", "merge", "refs/heads/topic"); config.save();