Git Workflow – Part 4: Remote Branches
The final piece of Git I’ll be covering is using shared remote branches. This can be helpful if you have a team working on a development and a release branch, among other scenarios.
I’ll start by setting up a central repository and two working repositories based off it. I’ll be supplying an extra argument to the clone command to make things less confusing, this gives the name of the directory in which to check out the branch. For example, “git checkout first.git” (no argument) checks out into a directory called “first”. Using “git checkout first.git second” will check out into a directory called “second”.
Kleinschs-Macbook:tmp nick$ mkdir first.git && cd first.git Kleinschs-Macbook:first.git nick$ git --bare init --shared Initialized empty shared Git repository in /Users/nick/tmp/first.git/ Kleinschs-Macbook:first.git nick$ cd .. Kleinschs-Macbook:tmp nick$ git clone first.git second Initialized empty Git repository in /Users/nick/tmp/second/.git/ warning: You appear to have cloned an empty repository. Kleinschs-Macbook:tmp nick$ cd second Kleinschs-Macbook:second nick$ echo 'First file contents' > file1 Kleinschs-Macbook:second nick$ git add file1 Kleinschs-Macbook:second nick$ git commit -am'added first file' [master (root-commit) 19b39e3] added first file 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file1 Kleinschs-Macbook:second nick$ git push origin master Counting objects: 3, done. Writing objects: 100% (3/3), 243 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To /Users/nick/tmp/first.git * [new branch] master -> master Kleinschs-Macbook:second nick$ cd .. Kleinschs-Macbook:tmp nick$ git clone first.git third Initialized empty Git repository in /Users/nick/tmp/third/.git/ |
Now that I have two working repositories, I’ll go create a release branch on the second repository.
Kleinschs-Macbook:tmp nick$ cd second Kleinschs-Macbook:second nick$ git checkout -b release Switched to a new branch 'release' Kleinschs-Macbook:second nick$ echo 'Second file contents' > file2 Kleinschs-Macbook:second nick$ git add file2 Kleinschs-Macbook:second nick$ git commit -am'added file2' [release 48a00ee] added file2 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file2 |
Since I have this release branch, I’d like to expose it to the rest of the team so that everyone is looking at the same version. Adding a branch is as simple as doing a push with the name of the new branch. In this example, I’m telling Git to push to a remote branch that doesn’t exist, so it creates it.
Kleinschs-Macbook:second nick$ git push origin release:release Counting objects: 4, done. Delta compression using up to 2 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 292 bytes, done. Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. To /Users/nick/tmp/first.git * [new branch] release -> release |
Listing the branches will show that the branch was created on the remote repository as well.
Kleinschs-Macbook:second nick$ git branch -a master * release remotes/origin/master remotes/origin/release |
Now let’s go over to the third repository and make sure we can access the release branch. First we do a pull to make sure we have the latest data from the remote server.
Kleinschs-Macbook:second nick$ cd ../third/ Kleinschs-Macbook:third nick$ git pull remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From /Users/nick/tmp/first * [new branch] release -> origin/release Already up-to-date. Kleinschs-Macbook:third nick$ ls file1 |
We’re still not seeing the second file that was checked in on the release branch. This is because we’re still on the master branch at this point. In order to access the remote release branch, we need to create a local tracking branch for our changes. A tracking branch is a local branch that’s set up with a remote branch so that pushes and pulls go to the corresponding remote branch. In order to set up a tracking branch, just supply the “–track” flag to the branch command.
Kleinschs-Macbook:third nick$ git branch --track release origin/release Branch release set up to track remote branch release from origin. Kleinschs-Macbook:third nick$ git checkout release Switched to branch 'release' Kleinschs-Macbook:third nick$ ls file1 file2 |
As you can see, we received the second file that was checked in on the release branch, so we should be ready to go. There’s one more thing I’d like to clear up. What if you have an existing branch that you’d like to have track a remote branch? The easiest way to do this is to edit your Git config file. Outputting the config from the the third repository will make this a little more clear.
Kleinschs-Macbook:third nick$ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = /Users/nick/tmp/first.git [branch "master"] remote = origin merge = refs/heads/master [branch "release"] remote = origin merge = refs/heads/release |
The section for branch “release” has the relevant information. If you wanted to set up the second repository so its release branch was tracking the remote release branch, you just need to add these three lines to second/.git/config.
This concludes my series on Git. There’s a lot more to it than these four articles describe, but this should be a good jumping off point.
