Commands used in this section:
- git clone
- git fetch
- git merge
The “branch” Section Of The Config File
Let’s look at the config file for the git client that did the git clone git://repohost/project1.git in the Git Remotes Behind the Scenes: “Tracking Branches” and “Remote-Tracking Branches” section.
After the git clone git://repohost/project1.git command is done, the contents of the .git/config file is created, as shown below:
$ git clone git://repohost/project1.git Initialized empty Git repository in .../project1/.git/ $ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = git://repohost/project1.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master
The [remote “…”] section of the git config file was described in the previous section. We will be exploring the [branch “…”] section now.
What’s The Point Of A “branch” Section?”
It’s all about less typing and convenience: If you want to type git pull and have it automatically do a git fetch followed by git merge then you came to the right place. Or you can type git fetch without any arguments or remote repository or branch names.
You can do a git fetch and git merge without a [branch “…”] section in your .git/config file. But, if you try a git pull without a [branch “…”] section, git will give you more advice than you got from your mother after going out in the rain without shoes, socks or a jacket.
We’ll temporarily comment-out the [branch] section and see what advice git has for us today:
$ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = git://repohost/project1.git fetch = +refs/heads/*:refs/remotes/origin/* ####[branch "master"] #### remote = origin #### merge = refs/heads/master $ git pull You asked me to pull without telling me which branch you want to merge with, and 'branch.master.merge' in your configuration file does not tell me, either. Please specify which branch you want to use on the command line and try again (e.g. 'git pull '). See git-pull(1) for details. If you often merge with the same branch, you may want to use something like the following in your configuration file: [branch "master"] remote = merge = [remote ""] url = fetch = See git-config(1) for details.
Now that was a lot of advice. I stopped listening to the above advice starting around the “You asked me to”.
The Branch Section: Line by Line
We’ll add the [branch “…”] section back to the .git/config file and examine each line in the [branch “…”] section.
While reading through this section, remember:
- git pull does:
- git fetch
- git merge
- The [branch “…”] configuration lines determine how git pull calls git fetch and git merge. Specifically, the [branch “…”] section determines what arguments are used to call git fetch and git merge.
Let’s look at the branch lines from the .git/config file:
- [branch “master”]
- This begins the definition of the configuration for users when their current branch is the master branch.The rest of the lines in this [branch “master”] section are used only if the user’s current branch is master.
- remote = origin
- This line specifies the remote repository to fetch from when doing the git fetch part of the git pull (or a git fetch) typed at the command line.Since remote = origin, the remote repository named origin will be used in the git fetch that is called by git pull.The origin repository referred to here must be defined in a [remote “origin”] section elsewhere in the configuration file.
- merge = refs/heads/master
- This line is used to configure the git merge part of the git pull: This line specifies which branch from the remote repository (not the remote-tracking branch!) will be specified when git pull calls git merge.When the master branch is the current branch, git pull will call git merge with the commit referred to in the refs/heads/master branch on the origin remote repository.
This means when you are on the master branch and type:
$ git pull
The above [branch “master”] configuration causes the git pull to run the following commands:
$ git fetch origin $ git merge [the-commit-referred-to-on-the-remote-master-branch]
“git pull” Example
For the example, let’s start with:
- A remote repository with two commits, C1 and C2
- A local remote-tracking branch named
origin/master and a local working branch named master that are both one commit behind the remote repository.
A digram is shown below:
The [remote “origin”] and [branch “master”] sections of the .git/config file are shown here:
[remote "origin"] url = git://repohost/project1.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master
git pull: Step 1
Using the git pull command while on the master branch causes the git fetch command to be run. The git fetch command is run using arguments from the [remote “origin”] section:
- The url from the [remote “origin”] section: “git://repohost/project1.git“
- The fetch from the [remote “origin”] line: “+refs/heads/*:refs/remotes/origin/*“
So git pull first does:
git fetch git://repohost/project1.git +refs/heads/*:refs/remotes/origin/*
The diagram below shows how the git fetch part of the git pull command is done, when master is your current branch.
git pull: Step 2
The second step done by the git pull command is the git merge command: The merge line in the [branch “master”] section specifies the name of the branch on the remote repository
that we want to merge from.
Note: The [branch “…”] section’s merge line refers to the branch in the remote repository refs/heads/master rather than refs/remotes/origin/master. This is different than calling git merge on your own, where you list the branch name in the local repository.
Above, you can see the second step of git merge caused the master branch head to move from commit C1 to C2 as the new commit: Commit C2, was merged into the user’s current master branch.
Using “git branch –set-upstream” to track existing branches
Instead of modifying .git/config, you can use git branch to add [branch “…”] sections, as discussed briefly in Adding And Removing Remote Branches.
For example, to create a new working branch called v0, and then create the new branch on the remote repository using git push origin v0, you can type:
$ git checkout -b v0 Switch to a new branch 'v0' $ git push origin v0 Total 0 (delta 0), reused 0 (delta 0) To git:///repohost/project1.git * [new branch] v0 -> v0
At this point:
- The remote repository has the new v0 branch.
- The local repository has the new v0 working branch.
- The local repository has the new origin/v0 remote-tracking
branch (it was created during the git push origin v0)
However, your .git/config does not have a [branch “v0”] section. Consequently, when you are on the [branch “v0”] section, typing git pull will fail:
amy$ git pull You asked me to pull without telling me which branch you want to merge with, and 'branch.v0.merge' ...
To fix this, if you are running git 1.7.0 or later, you can type:
$ git branch --set-upstream v0 origin/v0 Branch v0 set up to track remote branch v0 from origin.
The above command adds 3 lines, shown below, to the .git/config file:
$ cat .git/config ... [branch "v0"] remote = origin merge = refs/heads/v0
The .git/config file has been configured as follows:
- If the user is on the v0 branch, then a git pull will git fetch using the url and refspec configuration from the origin remote configuration (which is not shown here).
- The git merge will be done with the v0 branch from the remote.
With git versions earlier than 1.7.0 that don’t have the –set-upstream flag, you can use the following instead of using the above git branch –set-upstream v0 origin/v0 command, which isn’t as convenient and takes even more typing than simply editing the .git/config file:
$ git config branch.v0.remote origin $ git config branch.v0.merge refs/heads/v0
Using “git branch –track” to create a local branch that tracks a remote-tracking branch
In some repositories, git branch -r may show there are other remote-tracking branches that you want to work on besides the master branch:
$ git branch -r origin/HEAD -> origin/master origin/test origin/future
To set up a “tracking” branch for the origin/test branch, you can type:
$ git branch --track test origin/test Branch test set up to track remote branch test from origin.
The above command creates a new section in your .git/config file:
$ cat .git/config [branch "test"] remote = origin merge = refs/heads/test
Then you can type git pull while on the test branch and the git fetch and git merge commands will be run with the correct arguments, saving you time and trouble.