Archive for September, 2011

Yet another GIT branching guide

If you always work on the master branch, git pull and git push commands are just what you need. If instead you need to work on a branch, something more need to be said. First, some explanations.

  • GIT uses branches just like SVN: a branch is a different path of developement
  • There is no implicit “primary” branch (SVN has instead the “trunk”); that said, the main branch is often called master (GIT will give this name to the main branch when creating an empty repository).
  • Branches can be either local or remote:
    • A local branch is a branch that exist on the local repository only; you can see a list of local branches using git branch.
    • A remote branch is instead a branch that exists on a remote repository, therefore visible to anyone that has access to it. Use git branch -r to see all the remote branches known to you. Remote branches have generally a name in the form origin/$branchname, because origin is the default alias that is given locally to the remote repository.

Now, before creating a branch, you may want to ask yourself some questions:

  • Do I want to propose some changes to the world, or instead do I just want to try out some things?
  • Do I need to follow another guy’s branch, or am I working alone on the subproject?

If you need to work in team, you need to create a branch on the remote repository (if someone else did not already) and then setup a local branch to “link” to it (GIT calls this tracking); otherwise, you just need a local branch.

Let’s start from the easy part: how to create a local branch.

Local branches

Suppose that I am following the master branch, but I want to try the foorazor approach to the problem. I create a “topic” branch just for that:

git branch foorazor
git checkout foorazor
# or, in a single command:
git checkout -b foorazor

Now I start working on it, making commits and whatever. If, some time later, I see that the foorazor approach is wrong, I just delete that branch:

git checkout master   # to switch to that branch
git branch -d foorazor    # delete the wrong branch
# If the branch content was not merged (and this is perfectly fine sometimes), GIT complains with:
# error: The branch 'foorazor' is not fully merged.
# If you are sure you want to delete it, run 'git branch -D foorazor'.
git branch -D foorazor   # so, just force its deletion

If, instead, the foorazor approach turns out to be useful, I merge it back in the master branch:

git checkout master
git merge foorazor   # you may need to manually merge some things here, if there are conflicts
# edit the files with conflicts, git-add them when ready and git-commit to resolve the merge
git branch -d foorazor   # delete the now unneeded branch, if no development is needed anymore on that topic

Note that no git push was ever made: we never informed the central repository of our local branch. If, of course, I have completed the work on foorazor and I have merged it, now the code exists also on the master branch, so the next git push will transfer those commits to the central repository.

Working with a remote branch

Let’s take branches to the next level. Someone asked me to work on his awesome branch to fix some bugs. I have already fetched the whole repository with git clone, so the remote branch is already known to me:

$ git branch -r
  origin/awesome
  origin/master

Since I know that there is nothing awesome in fixing bugs committed by other people, I decide to track the awesome remote branch with a descriptive local name: (there is no need to have different remote and local names, I do it to point out the namespace differences)

git checkout --track -b boring_work origin/awesome

Now I work on the local branch boring_work as always. I fetch my friend’s changes with git pull and do commits locally; when I want to give him back my changes, I type:

git push origin boring_work:awesome

This command pushes the changes from the local boring_work on the remote branch awesome on the repository origin: note that you can use just git push origin awesome if you used the same name locally (and probably you should do so if you are not an advanced user).

NOTE FOR ADVANCED USERS: by default, if no remote branch name is given on the command line (remember that the syntax is git push ${reponame} ${local}:${remote}), GIT pushes to a remote branch with the same name of the local one. So, even if boring_work tracks origin/awesome, git push origin boring_work will create another branch called boring_work on the remote repo. This happens because the configuration option push.default has a default value of matching (see man git-config). Solutions?

  • Either use a local name that is the same of the remote one (git checkout --track -b awesome origin/awesome);
  • or, if you want more freedom, configure the local repo with git config push.default upstream, that says GIT to push the current branch to its upstream branch, not the one with the same name.

— NORMAL USERS, RESUME READING HERE —

When I’m done helping my friend, I just type

git checkout master
git branch -d boring_work

and forget about the past.

How to create and delete a remote branch

What if I want to create a brand new branch on the remote repository?

This command creates a branch called new_branch, as a copy of the remote’s master (actually, as a copy of the remote’s HEAD, but, if nobody messes up the remote repo by actively running commands inside it, the result is the same):

git push origin origin:refs/heads/new_branch

Now you can fetch it locally as explained above.

If instead you want to duplicate a remote branch, use:

git push origin origin/old_branch:refs/heads/new_branch

Note that none of the previous command sets up a local branch.

To delete a remote branch, just use:

git push origin :remote_branch

that can be remembered easily as “using remote repo origin, push “empty” to remote_branch“. The deletion command does not need the “refs/heads” prefix because the branch name is already known remotely and therefore can be looked for in the standard places.

1 comment September 9th, 2011


Rate:  

Calendar

September 2011
M T W T F S S
« Jul   Dec »
 1234
567891011
12131415161718
19202122232425
2627282930  

Badges

Posts by Month

Posts by Category

What's played in the cave