<div class="gmail_quote">On 21 March 2011 04:32, Thomas Wouters <span dir="ltr"><<a href="mailto:thomas@python.org">thomas@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im"><br></div><div>Merging and merge changesets are a fact of DVCSes, and while I (as a grumpy luddite misanthrope) greatly prefer the automatic (and mostly silent) merge as BitKeeper does it, in the long run the actual merging and the merge changesets are unavoidable and something to get used to, not dodged around (at least not at this cost.)</div>
</blockquote><div><br></div><div>Agreed 100%. I really don't understand the antipathy to branching and merging. I understand the desire to distribute a collapsed changeset - it's changing history, but as long as you're absolutely sure that it's never been shared to another repository, *even another local one* then you're OK.</div>
<div><br></div><div>As far as I can see, people here are fighting against the tools, and as a result making life much much harder for themselves. Patch, Export/Import, Mercurial Queues - they're all recipes for ending up with an inconsistent history across repos in the hands of inexperienced users (and as much as I consider myself a decent user of Mercurial, I'm very much a neophyte when it comes to MQ).</div>
<div><br></div><div>The way I set up Mercurial for my team was to have a single master repository, which was then cloned as many times as desired by developers. Clones were also made to do automated builds/tests in. Nothing was *ever* done in the master's workspace (it was always empty).</div>
<div><br></div><div>All work was done in a named branch per task named for the task number. You could collapse changesets so long as they had not been shared (though we preferred to keep the entire history - made code reviews and pairing much easier).</div>
<div><br></div><div>The advantages I saw of this:</div><div><br></div><div>1. It's a much simpler workflow. You pull and push between repositories, update to the named branch you're working on, and commit. You only need to merge *from* your task branch in most cases, except when merging a change between feature branches (e.g. named branch -> 3.1 -> 3.2 -> 3.3).</div>
<div><br></div><div>The only complication is if you start your work in e.g. 3.2 but it needs to be backported to 3.1. In that case, you can either do an export/import/dummy merge forwards to get the change onto 3.1, or if the change has never been shared you could *transplant* the named branch onto the 3.1 feature branch (but that is a history change, using the transplant extension, so should only be done if the named branch has never been shared outside that repo). For this reason, you should always branch from the earliest possible location - you can always merge forwards, but backwards is hard because of the extra associated history). If the task is for a bugfix, always try to branch from the point where the bug originated.</div>
<div><br></div><div>2. Work sits in named branches, and can be reviewed there. All you have to say in the issue tracker is "branch X in repo URL". Work doesn't need to be merged to the feature branches until it's been reviewed.</div>
<div><br></div><div>This does mean that a branch can be based on an outdated version of the feature branch. A merge from the feature branch will fix that, but does make reviewing harder. This is the main reason I've seen to want to rebase - but in general I still think it's more trouble than it's worth. Live with the merges - if you really want to, you can always create *another* named branch to do the merge in e.g. for the first merge from feature branch to task 1234</div>
<div><br></div><div>hg update 1234</div><div>hg branch 1234_merged_with_3.2</div><div>hg merge 3.2</div><div>hg commit -m "Initial merge 1234_merged_with_3.2"</div><div><br></div><div>For the second and later merges:</div>
<div><br></div><div><div>hg update 1234_merged_with_3.2</div><div>hg merge 3.2</div><div><div>hg commit -m "Merged 3.2 to 1234_merged_with_3.2"</div></div><div>hg merge 1234</div><div><div><div>hg commit -m "Merged 1234 to 1234_merged_with_3.2"</div>
</div></div></div><div><br></div><div>Then you have a "clean" branch to review, and a branch that will merge cleanly with the feature branch. This combined branch is the one that you will then merge to the feature branch.</div>
<div><br></div><div>3. When a branch is finished, it can just be closed, then merged to the feature branch(es). Note that you do want to merge the close changeset as well - this prevents leaving extra heads around.</div><div>
<br></div><div>4. When a branch is abandoned, it can just be closed. It stays in the history, so if someone wants to take it up again they've got the previous work sitting there and can either resume, or use it to work out what went wrong. Note that closing a branch does nothing except hide it from hg heads and hg branches.</div>
<div><br></div><div>5. It's very easy to just pull or push a single branch (although I'm personally in favour of all branches eventually ending up in the master repository). Pulling a single branch from another developer's repo is a good way to work on a branch together.</div>
<div><br></div><div>6. Working on someone else's code is much much easier. Say I have an environment set up, with various ignored configuration files, etc. A good example would be an Eclipse workspace. You really don't want to have to set up a separate workspace for each task or feature you're working on (which you would need to do if you're using separate clones for each task). If you have each task on a named branch, you can just hg update 1234 and your existing workspace is now ready to work on another task (you might want to hg purge as well to get rid of generated artifacts such as .pyc files).</div>
<div><br></div><div>I've worked extensively with this workflow, and it was *really easy*. The entire team was working happily in about a week, and we really found no reason to change how we used Mercurial once we started doing this. Yes - you end up with a much branchier workflow, but I found that to be an advantage, rather than a disadvantage, because I could easily isolate the changes that composed any particular task.</div>
<div><br></div><div>Tim Delaney</div></div>