After part 1, we know how to create, checkout, and modify a single copy of code. It’s almost no different from CVS from a normal user’s standpoint. Add, checkout, commit, status, diff, etc. all do pretty much what they do in CVS. When dealing with a team of developers this can be a good thing, as the time spent learning the basics of the new VCS is minimized. Anyway, on to the point of this post, branching.
As I said in part one I still like the idea of a central branch, a “HEAD” if you will. I think there is also a need for “official” branches. Things like maintenance branches for each release/patch should be managed. However, I think users should be free to create their own branches for features as needed. In this post I’m going to take a look at how bazaar handles branches.
Creating a branch is very simple, you just issue the bzr branch command
[andrew karma] /Users/andrew/Development/BZR
>>>>>> bzr branch myProject myProject.branch1
Branched 2 revision(s).[andrew karma] /Users/andrew/Development/BZR
>>>>>> ls
total 0
0 myProject/ 0 myProject.branch1/
As you can see, the branch operation created a new directory, myProject.branch1. Again, this would work with local files, remote files (via SFTP, or other protocol) as described in the documentation. Lets take a look at what myProject.branch1 is.
[andrew karma] /Users/andrew/Development/BZR
>>>>>> cd myProject.branch1[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> bzr info
Standalone tree (format: pack-0.92)
Location:
branch root: .Related branches:
parent branch: /Users/andrew/Development/BZR/myProject
We have a complete copy of myProject, and the info says that our parent branch is myProject. Seems good. Let’s play around with committing.
First, we’ll make a change in myProject.branch1, commit it, then check to see what happens in the branch and in the parent.
[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> echo “Change from myProject.branch1″ >> test1.txt[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> bzr commit -m “Committing from myProject.branch1″
Committing to: /Users/andrew/Development/BZR/myProject.branch1/
modified test1.txt
Committed revision 3.
We’ve changed test1.txt and checked it into myProject.branch1. The new text exists in the branch1 directory. Let’s see what happens when we look at baes myProject directory.
[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> bzr update
Tree is up to date at revision 2.[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> bzr status[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> bzr info
Standalone tree (format: pack-0.92)
Location:
branch root: .[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> cat test1.txt
Initial Content
Line added from a checkout
Looks like the base tree doesn’t know anything about what’s going on in the branch. This is what I pretty much expected. Now, lets make a change in base myProject.
[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> echo “This is a change from the base myProject” >> test1.txt[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> bzr commit -m “Change made in base myProject”
Committing to: /Users/andrew/Development/BZR/myProject/
modified test1.txt
Committed revision 3.
Now, lets take a look at myProject.branch1
[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> bzr update
Tree is up to date at revision 3.
Ok, changes made in myProject don’t make it to myProject.branch1 with just an update. Lets try merging myProject down to myProject.branch1. This is what users in a feature branch would do to get changes from their main branch to stay in sync. Supposedly a simple bzr merge will merge the parent branch down into the current branch. Here’s what happens.
[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> bzr merge
Merging from remembered parent location
/Users/andrew/Development/BZR/myProject/
M test1.txtText conflict in test1.txt
1 conflicts encountered.
Ooh, we have a conflict. test1.txt line3 is different between myProject.branch1 and myProject, bzr correctly, does not try to guess what I meant. So, we have to resolve the conflict.
[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> ls -al test1*
8 -rw-r–r– 156 Apr 5 18:01 test1.txt
8 -rw-r–r– 43 Apr 5 18:01 test1.txt.BASE
8 -rw-r–r– 84 Apr 5 18:01 test1.txt.OTHER
8 -rw-r–r– 73 Apr 5 18:01 test1.txt.THIS
You can find full details on how to deal with conflicts here. Bascially, test1.txt now looks like this:
[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> cat test1.txt
Initial Content
Line added from a checkout
<<<<<<< TREE
Change from myProject.branch1
=======
This is a change from the base myProject
>>>>>>> MERGE-SOURCE
.BASE contains the previous previous version, .THIS contains the current version in this branch, .OTHER contains the current version in the parent. We just need to edit test1.txt and mark the conflict as resolved. After test1.txt is edited, we have to tell bzr that the conflict has been resolved. According to the documentation bzr is smart enough to know which files you’ve resolved conflicts in and which ones you haven’t. So I’m going to go ahead and run bzr resolve
[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> bzr resolve
All conflicts resolved.[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> bzr status
modified:
test1.txt
pending merge tips: (use -v to see all merge revisions)
Andrew 2009-04-05 Change made in base myProject
bzr resolve has also removed all of the .BASE/.OTHER/.THIS files. bzr status tells us that we have a pending merge. I’m going to go ahead and commit.
Now, say we’ve made a bunch of changes on our branch that need to be put into our main repository myProject.
[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> echo “New file in branch1″ >> test5.txt[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> echo “Change from branch1″ >> test2.txt[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> echo “Another change from branch1″ >> test1.txt[andrew karma] /Users/andrew/Development/BZR/myProject.branch1
>>>>>> bzr add test5.txt
adding test5.txt
We’ve added test5.txt and made some changes in test1.txt and test2.txt. Lets get those changes up to myProject.
[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> bzr merge ../myProject.branch1
+N test5.txt
M test1.txt
M test2.txt
All changes applied successfully.[andrew karma] /Users/andrew/Development/BZR/myProject
>>>>>> bzr status
added:
test5.txt
modified:
test1.txt
test2.txt
pending merge tips: (use -v to see all merge revisions)
Andrew 2009-04-05 Changes from branch1 for merge to myProject
Since we don’t have a parent branch, we needed to tell merge where to merge from. bzr status tells us what’s changed. No conflicts this time, we’ll go ahead and commit. At this point, both myProject and myProject.branch1 are identical. Which is what we kind of wanted.
That’s it for branching. I don’t know what I’ll do for the next post yet. I’m thinking either showing how to handle remote stuff, delving into what repositories are, or looking at how to handle authentication and permissions. Anyway, if you like this let me know.



“…if you like this let me know.”
I like this!
I’d love a similar post on authentication and permissions, if that’s what you’ve got lined up next, actually.
I’m greatly thankful for this article. Very easy to understand and very helpful. Thanks again!
Glad you liked it. Hopefully I’ll get some time to do some more digging into bzr. Been too busy recently to keep the site as up to date as I’d like.