Being one of git's core features, being able to handle branches is an incredibly important skill to have. If done properly, it can greatly enhance a group's efficiency when working on a new project.
Although not explicitly necessary to understand in order to use branching, it is still fairly important to discuss exactly how git handles branching.
When you make a commit on a branch, you are actually not commiting directly on the branch —
your commit goes first into a large pool
where it swims around with all of the other commits that were ever made to the repository (including commits on other branches).
Then, git takes the commit and updates the HEAD
pointer on the branch to point at that particular commit by adding the commit to the branch's history.
So, effectively, a branch is really just a list defining its history. If a branch is deleted, the commits that were a part of its history will remain in the repository — even if that branch was the only branch that they belonged to (they may only be accessed by their commit hash after this point, however).
When branches are merged together, on top of splicing the source code together, git splices the history lists together, so that the commits that were made on the source branch will appear on the destination branch as if they had been made alongside the rest of the development, and not in a large block at the top of the branch's history.
Creating a new branch is quite easy, and there are a number of ways to do it. However, there are a few important things to understand about branching first.
When you create a new branch, you are deliberately causing the repository's history to diverge. This is great if you want to work on a new feature for your code, you are working on some sort of side project, or you don't want to interfere with the main stream of development. However, if you are just working on a simple fix, creating a whole new branch can be a little too much. If you let the main stream of development diverge too much from your branch, you will end up with merge conflicts when you ultimately do decide to merge your branch back.
When you make a new branch, keep the name short and simple. Make sure that it accurately describes the purpose of the branch, so that it really isn't necessary to inspect the code on the branch to figure out what you're doing.
Of the two options that you have, this one is the simplest of the two.
When you create a new branch locally, by default,
the HEAD
pointer of the new branch will point to the HEAD
commit of the branch you were on when you gave git the branch command.
If you want to branch from a specific commit, then you have to tell git the commit you wish to branch from.
If you have a GUI, this function is probably embedded in its branch switching feature.
Open the Switch branch
or Checkout
dialog and look for a New branch
option.
At some point, it will ask you what you want the branch to be named, and it will likely ask you where you want to push it on the remote repository.
In the latter event, you will want to tell git to set up a new branch on the remote of the same name, so there is no confusion later.
At any rate, when you finish with the dialog, your tool will usually switch to the new branch for you, and you can start working on the new branch.
If you want to create the new branch from another commit or branch, you will have to tell git the source in the dialog
(the option will probably be labeled Source
or Branch from
).
If that option only lists branches, you can try typing in a commit hash, if there is a field there for you to type in.
With the commandline, you have a few options to create a new branch.
The first is simply to create the new branch. This will create the new branch, but you will remain on the branch that you were on before you entered the branch command.
This can be done with git branch
:
git branch myBranch
Furthermore, the branch
command can be used to branch from a specific branch or commit:
# Branch from commit
git branch myBranch 845da8b
# Branch from existing branch 'myBranch' to 'myOtherBranch' while on a different branch
git branch myOtherBranch myBranch
The second option is to create a branch and then immediately switch to the new branch.
This is done with the -b
switch of the git checkout
command.
With the -b
switch, git checkout
's syntax is practically identical to that of git branch
:
# Branch from the current HEAD and switch to the new branch
git checkout -b myBranch
# Branch from commit 845da8b and switch to the new branch
git checkout -b myBranch 845da8b
# Branch from branch 'myBranch' to 'myOtherBranch' and switch to it
git checkout -b myOtherBranch myBranch
With any of these commands, git will create the new branch and then immediately switch to it.
When you create a new branch locally, you still need to push it to the remote repository. However, this is an incredibly simple operation to perform.
If you have a GUI, just push like you normally would (no commit necessary). There may be some configuration steps involved, but the defaults should be fine. That's it.
If you are using the commandline, you also just push like you normally would, just adding the -u
switch to have git set up the tracking information:
git push -u origin myBranch
It is also possible to use the GitHub web interface to create a new branch. However, it does involve some extra steps to get the branch on your local copy.
Creating a branch on GitHub is quite similar to the process for a local GUI. Just open the branch selector, and type the name of the branch you want to create. and hit enter.
If you want to branch from a specific branch or commit, you need to be browsing the repository under that branch or commit.
To browse the repository at a specific commit, click on the Commits
link in the info box, find the commit you want to branch from and click on it,
and then click Browse files
in the upper right-hand corner of the commit digest. This will bring you back to the root of the repository. The branch selector should now
read Tree: xxxxxxxxx
, where xxxxxxxxx
is the first 9 characters of the commit hash.
Once you have created the new branch, you need to pull it down.
If you are OK with pulling (i.e. there is nothing on the server that you don't want yet — this stands for any branch), then you can just do a pull. For commandline users, you need to do a generic pull by leaving off the remote and ref name:
git pull
However, if only want to grab the new branch, then the process is a little different.
First, perform a fetch. This will update git's remote-tracking branches (and thus fetch the new branch).
Secondly, you need to create a new branch from the proper remote-tracking branch.
In the GUI, you will want to select the proper branch under the Source
or Branch from
option.
In the commandline, just use the process described above, and just use your source as the right remote-tracking branch.
# Set up new branch without checking it out
git branch myBranch origin/myBranch
# Set up new branch and check it out
git checkout -b myBranch origin/myBranch
It is useful to know what branch you are on, so you know that you are developing in the right place.
Most GUIs will show this information to you quite readily, however, this depends on the implementation.
Most IDE git plugins (such as EGit or the Qt Creator git plugin) will display the branch right next to the project root in the project explorer.
TortoiseGit displays this information alongside the Commit option (it says Git Commit → 'branch'
).
If you remember back to the git status
message from lesson 2-1, the very first line shows you the current branch:
On branch myBranch
Although you will be working on one feature on one branch for a while, you may decide to start working on another feature, or a bug has come up that needs attention. In either of these scenarios (among others), you will want to switch your branch to work on something else so you don't mix your work together prematurely.
This is a very simple operation. In the GUI, you will have an option called Switch branch
or Checkout
,
or the function may simply be presented to you as the name of the current branch on top of a drop-down menu.
Regardless of how it is presented, selecting this option will present you with at least all of the local branches.
There will usually be some way to access the remote-tracking branches as well.
On the command line, this function is available through, you guessed it, the git checkout
command.
This function is probably the checkout
command's most simple use case; you just pass it the name of the branch you want to switch to.
git checkout myBranch
When you switch branches, it is important to remember that you cannot have uncommitted changes in your working directory.
Once you're done working on your branch, you need to merge it back into the main stream of development.
However, it is important to note that this will not always be the master
branch.
Which branch you merge into depends on your project, and if you don't know, you should ask one of your teammates as to which branch to merge into.
The important thing to remember when you merge that a merge always happens onto the current branch from another branch. So, when you want to merge, make sure you are on the target branch, not the branch you want to merge from.
Before you merge, make sure that both branches are completely up-to-date — especially the target branch. Merging onto outdated code will just cause more problems during the merge process.
Secondly, it is usually good advice to merge from the branch you want to ultimately merge onto into your branch first, so that you work out any conflicts and problems without disrupting the main stream of development. Once you have worked those out, then you would merge into the target branch, which should simply give you a fast-forward.
Once you are on the new branch, then you want to start the merge operation. In the GUI, selecting the Merge
option will basically always bring a list of branches up (either as a list view or a combobox).
Here, you select the branch you wish to merge from. If the GUI shows you the summary of the latest commit, ensure that it matches the last commit on the branch you are trying to merge from.
Once you have selected your branch, select Merge
. Git will attempt to merge automatically, but if lines conflict,
then it will error out and ask you to resolve the conflict manually (which you will learn more about in the next lesson).
If there are no conflicts but the result was an automatic merge (i.e. it was not a fast-forward)), the tool may commit the result for you, but it is usually a good idea to try and commit the result anyway in case it does not.
On the commandline, you would do basically the same thing as you would if you were merging fetched changes, except you would leave the remote tracking prefix off (unless the remote tracking branch has the code you wish to merge) and use the name of the branch you wish to merge from instead:
git merge myBranch
Although most everything about the branch should be pretty much done when you set it up, there may be times when you need to modify the branch itself (not just the code on it).
It is important to note that GUIs do not usually have a unified way of presenting these functions, so only the command line will be shown here.
You might find that your branch's name is not quite fitting to its purpose. Or maybe you're just having one of those bad days when you can't type (don't worry, it happens to us all).
The best way to rename a branch is to use the command line and use the -m
switch of the git branch
command:
git branch -m old_name new_name
This will rename the branch old_name
to new_name
. You can also use a shorthand if you want to rename the current branch:
git branch -m new_name
If this branch has already been pushed to the remote repository, then you will have to delete the remote branch and push the renamed branch as a new branch instead. However, you should be very cautious when doing this, because this can cause git to error out on your teammates' computers because it doesn't know what happened to the branch you deleted. Be sure that everyone knows that you are going to change the branch name before you go and do it.
When you merge, the branch you are merging from is not deleted. It remains in the repository.
Under almost all circumstances, this is fine. You are usually not actually done with development on that branch when you do a merge (merging usually happens when the branch reaches a particular milestone), so it is a good idea to keep them around in case you need them.
However, there may be some cases where you want to delete the branch. This is usually if you created a branch and ended up not needing it in the first place.
And, a word of advice — don't delete master
.
You may also have cause to delete a branch locally if you personally have no need to keep the branch, and would rather just keep it on the server.
Deleting a branch is done using the -d
switch of the git branch
command.
git branch -d myBranch
Note that git will NOT allow you to delete the branch you currently have checked out.
Make sure that you have another branch (such as master
) checked out first.
Please talk to your codevelopers before deleting a branch from the remote repository!
If you delete a branch locally, you can no longer push that branch, so attempting to perform a push the way you would normally would not delete the remote branch.
However, the way this is done is still using the git push
command. As a matter of fact, the syntax is almost exactly the same, except you add a colon (:
) before the branch name, like so:
git push origin :myBranch
← 2-2 Revising History | 2-3 Branching | 2-4 Resolving Merge Conflicts → |