Author: James Blackwell Revision: 1 Date: Sept 5 2005
This story covers the individual hacker named Barry. Barry likes to work independently on free software projects. He's got a small pile of small free software projects. Barry hasn't been using revision control on his projects because he felt that doing so wouldn't be worth the effort.
Unfortunately for poor Barry, one of his ten users has complained about a bug that has been in his code for the last couple features. This bug wasn't complicated, but was spread throughout the code in lots of little pieces that made it difficult for Barry to track down. Barry, realizing that he doesn't want to repeat this type of effort again, decides to move to using a revision control system.
Barry wanted to get his code controlled as easily as possible. He wanted all of the bells and whistles of a RCS system, but didn't want to pay the cost of setting up RCS servers. Thusly, he chose Bazaar. Barry decided to start controlling a project that he forked years ago, something called Tuxpuck.
The first thing that Barry did was to get a copy of his own sources, which he put into a directory named tuxpuck (if you are following along with bzr yourself, feel free to import something you've got, perhaps by running cp -a /etc/init.d ~/tuxpuck). He then performed the following actions:
~$ cd tuxpuck ~/tuxpuck$ bzr init ~/tuxpuck$ echo "I have become truely omnimematic" > my_brag ~/tuxpuck$ bzr add my_brag added my_brag ~/tuxpuck$ bzr commit -m"Started up"
Barry was pretty happy with this. He decided to give bzr a few more commits so that he could get a feel for how commits went:
~/tuxpuck$ echo "Don't brag. I guess I'm not omnimematic" > my_brag ~/tuxpuck$ bzr commit -m"Bragging is bad" modified my_brag
Barry, like much of us, leads a hectic life. He wanders off for a few days and comes back, unable to remember what he did. To get around this, he runs "bzr log:"
~/tuxpuck$ bzr log ------------------------------------------------------------ revno: 2 committer: James Blackwell <firstname.lastname@example.org> timestamp: Wed 2005-09-07 01:09:14 -0400 message: Bragging is bad ------------------------------------------------------------ revno: 1 committer: James Blackwell <email@example.com> timestamp: Wed 2005-09-07 01:08:42 -0400 message: Started up
This pleases Barry quite a bit, mostly because Barry hasn't worked with a revision control system a bit (Note: This is my imaginary friend and I can make him easy to please if I want!)
However, this doesn't please Barry for too long; he wants more than just to be able to to save changes. What he'd really like to do is to work on two things at the same time, so that he get a feel for branching:
~/tuxpuck$ cd ~$ bzr branch tuxpuck newpuck
What he's just done now is tell bazaar to make a copy of his old tuxpuck branch and make a new one in the newpuck directory. These two branches are absolutely identical, except for location. In a moment of inspiration, Barry realizes this means that he could have made a copy of his branch in other ways... He could have run "cp -a tuxpuck newpuck", he could have rsynced the branch to another machine, or even done a copy by transcribing by hand, if he had been so inclined.
This is cool and all, but what's the point of having a two branches that are exactly the same? Thusly, Barry makes some changes to newpuck:
~$ cd newpuck ~/newpuck$ echo "Don't brag. I guess I don't remember all" > my_brag ~/newpuck$ bzr commit -m"Variation in humility" modified my_brag
Barry, like many people, gets distracted for a few days and walks off. When he comes back he can't remember how tuxpuck and newpuck are different. To figure out how the two trees are different, he runs:
~/tuxpuck$ bzr diff -r branch:../newpuck [a lot of output from diff]
Note: The branch: revision specifier is available on 0.7 and later versions. If Barry were using 0.6 or earlier, he'd need to do something like:
~/tuxpuck$ cd ~$ diff -ruN -x .bzr tuxpuck newpuck [a lot of output from diff]
Barry decides that he likes the changes that he did to the newpuck branch the other day and decides to merge it into his main tuxpuck branch. Thusly, he ran the following:
~$ cd tuxpuck ~/tuxpuck$ bzr merge ../newpuck/ 0 conflicts encountered. ~/tuxpuck$ cat my_brag Don't brag. I guess I don't remember all
Sure enough, bzr merged the changes that he made in the newpuck branch into the tuxpuck branch. He wonders, though, what happens with slightly more complicated files. Barry decides to try a slightly more complicated test:
~/tuxpuck$ cat << EOF > my_brag > This stuff seems to > be working pretty good so farr. > > I wonder if it will kepe working > EOF ~/tuxpuck$ bzr commit -m"Making a longer example" modified my_brag ~/tuxpuck$ cd ../newpuck ~/newpuck$ bzr merge ../tuxpuck 0 conflicts encountered. ~/newpuck$ bzr commit -m"Catching newpuck up with tuxpuck" modified my_brag
Now he's ready to try something a little different: He's going to try and make a different change to the same file in two different branches:
~/newpuck$ sed -i s/kepe/keep/ my_brag ~/newpuck$ bzr commit -m "I fixed the mispelled keep" modified my_brag ~/newpuck$ cd ../tuxpuck ~/tuxpuck$ sed -i s/farr/far/ my_brag ~/tuxpuck$ bzr commit -m "I fixed the mispelled farr"
Barry is now comfortable knowing that my_brag is different in two different places. But can bzr merge them?
~/tuxpuck$ bzr merge ../newpuck/ 0 conflicts encountered. ~/tuxpuck$ cat my_brag This stuff seems to be working pretty good so far. I wonder if it will keep working ~/tuxpuck$
So far so good! So Barry commits and tries it the other way:
~/tuxpuck$ bzr commit -m"Merged in from newpuck" modified my_brag ~/tuxpuck$ cd ../newpuck ~/newpuck$ bzr merge ../tuxpuck/ 0 conflicts encountered.
"This seems pretty cool!" Barry says to himself. He takes a quick look at the my_brag in newpuck, and sure enough, both typos have been fixed.
~/newpuck$ bzr commit -m"Saving the merge from tuxpuck" modified my_brag
But what would happen if Barry had tried to merge two branches that had changes in the same place? This results in something called a conflict. A conflicted file is a bit of a headache to deal with that is a bit difficult to explain at this point. We'll get to that later.
This wraps up the first chapter of the Bzr chronicles. In this chapter you learned, by actually performing, the following things:
- How to import a new project into bazaar
- How to branch in bazaar
- How to check the differences between two branches in bazaar
- How to merge between two branches in bazaar