= 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 [wiki:BazaarTheory Bazaar Theory]. == Linear History == 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/head 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://jermar@bzr.helenos.org/head }}} 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. == Rebasing == == Structured History == 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 {{{head-clone}}} which will be a clone of the mainline: {{{ $ bzr branch bzr://bzr.helenos.org/head head-clone }}} Now go to the clone repository and merge your branch into it: {{{ $ cd head-clone head-clone$ bzr merge ../my_branch head-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: {{{ head-clone$ bzr push bzr+http://jermar@bzr.helenos.org/head }}} 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/head my_branch my_branch$ bzr commit -m "Merge latest 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 {{{head-clone}}} repository mentioned above) around. You can keep it up to date by pulling from the main repository: {{{ head-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'' (use {{{bzr log --show-ids}}} and compare {{{revision-id}}}) (usually as the second changeset from the top), it is safe to push. 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). == Conclusion == We are still trying to determine whether it is possible to check for bad merges automatically on the server side. So please be careful what you push into the main repository. If you are unsure, ask for help.