Managing HelenOS source with Bazaar
This should help you to start using our new VCS, Bazaar. Please read this little guide carefully. Inappropriate use of Bazaar WILL make a mess in our repository. This page only documents how to use Bazaar with HelenOS. If you are confused and want to know what happens behind the scenes, read the Bazaar Theory.
First of all, you need to tell Bazaar a little bit about yourself. This is accomplished by following:
$ bzr whoami "Ferda Mravenec <ferda.mravenec@mraveniste>"
From now, Bazaar will attribute all your commits to that identity. Note that the string inside the angle quotes is just a means of identification, it does not have to be your real e-mail address. You should consider not using your real e-mail address. The commit logs are publicly visible on many places on the web and you could receive lots of spam for years to come. The part after the @ sign does not have to be a real fully qualified domain name and the part before the @ sign does not have to be a real user name. If you use identity which is not an e-mail address, it's best idea to not make it look like one (i.e. one that does not end in something which looks like FQDN or TLD.
If you are doing a simple change (or several simple, unrelated changes) you might try to go for linear history. But remember that you will actually not be taking advantage of the distributed VCS, instead using it as a centralized tool.
Remember that this will only work if nobody else pushed any changes to the main repository while you were doing your changes. Start by creating your private branch:
$ bzr branch bzr://bzr.helenos.org/mainline my_branch
This will create a branch (and working copy) under the directory my_branch. Now make some changes and commit them to your private branch:
$ cd my_branch my_branch$ ...modify some files... my_branch$ bzr commit -m "Fix crash when writing zero bytes to FAT."
Now we can try and push back our changes to the main repository:
my_branch$ bzr push --remember bzr+http://email@example.com/mainline
In the command above please replace jermar with your username. Next time you can just use
my_branch$ bzr push
If nobody pushed any changes since the point you branched off, this will work. Otherwise it will fail. If it fails like this:
bzr: ERROR: These branches have diverged. Use the missing command to see how. Use the merge command to reconcile them.
you have two options. Either rebase your changes to the mainline head or switch to structured history workflow.
See official Bazaar documentation on rebasing. You will need the rebase plugin.
Stuctured history is good and merging is the most natural operation in a distributed VCS. If you are working on some feature and produce several related commits, it is better to group them to a separate branch. Even better, you can have one (or more) private branches that you keep all the time. Do not be afraid of structured history.
Merging Into the Mainline
Let us say your branch diverged from the mainline (i.e. somebody pushed to the main repository since you branched off). This is perfectly normal. You can work on your branch independently of the mainline. However, from time to time you might want to actually propagate your great new changes to the mainline. We do it by merging.
With merging, the order of arguments is significant. In this case we want to merge your branch into the mainline, not the other way around! How can you do this? With bazaar you can only merge to a local repository (you need to chdir into it), you cannot merge to a remote repository.
Therefore we have to resort to a little trick. Suppose you have a branch my_branch. We create a new branch mainline-clone which will be a clone of the mainline:
$ bzr branch bzr://bzr.helenos.org/mainline mainline-clone
Now go to the clone repository and merge your branch into it:
$ cd mainline-clone mainline-clone$ bzr merge ../my_branch mainline-clone$ bzr commit -m "Merge FAT server improvements."
The comment for the merge changeset should summarize the changes done on that branch (or, it could just name that branch, if it was a well-known one). Now we can push from the clone to the main repository:
mainline-clone$ bzr push bzr+http://firstname.lastname@example.org/mainline
Remember that it is not necessary to merge every commit you make into the mainline right away. It can be better to merge more changes at a time.
Keeping Your Branch Up to Date
From time to time you might want to add the latest changes from mainline into your private branch. You do this simply by merging from the mainline:
my_branch$ bzr merge bzr://bzr.helenos.org/mainline my_branch$ bzr commit -m "Merge mainline changes."
Note that it is not necessary to merge all new mainline changes at once, you can do it less often, preventing unnecessary merges. Especially note that it makes no sense merging the mainline if the only new changeset is the changeset that merges the latest changes from your branch.
Keeping a Clone Around
It is advisable to keep a clone (such as the mainline-clone repository mentioned above) around. You can keep it up to date by pulling from the main repository:
mainline-clone$ bzr pull
The clone is good for two things:
- compiling and testing the latest and greatest changes in the mainline (without having to merge them)
- merging changes from your feature branch into the mainline
What if I pull from mainline to my feature branch?
The effect is that the mainline head will become the head of your repository. Consequently, your repository will not continue your feature branch, but it will branch off a new branch from the mainline. If you do bzr log it will show the mainline's history beyond the new branching point, not the history of your feature branch.
Working this way will result in creating lots of short feature branches which start and finish. If you merge from the mainline instead, you will get one long branch.
What would happen if I pushed from my feature branch to the mainline?
The main repository would inherit the head of your feature branch as its head. Your feature branch would become the mainline and the repository's history will become confused. If you did this, well, shame on you! However, it can still be fixed to some extent by creating a new merge changeset which would merge the offending head into the mainline. (I.e., the right way around.) You should rather ask someone competent to do this. In any case it will produce some confusing changesets in the history.
How do I know it is safe to push to the main repository?
In case you are wondering, there is one foolproof way to check that you can push from a repository A to the mainline. (It could be even automated on the client side.) First look at the log of the main repository and find the last changeset (the mainline head, H). Now look at the log of repository A from which you would like to push. If it contains the mainline head H at some point, it is safe to push. Use bzr log --show-ids and compare revision-id. Usually, the first changeset at the top should be a merge changeset, and the second one should be the mainline head H. If you do not see the mainline head, stop!
Normally you will know what repositories are safe to push because they are not diverged (the clone of the main repository) and which are not (your feature branches).
A Bazaar plugin which automatically checks your pushes has been deployed on the mainline repository server. This should make merging foolproof, however, there is always a slight possibility that something might go wrong despite the checks or that some of the checks might be too strict. If you encounter any problems, ask for help or report a bug.