Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Branching with Mercurial SCM

So right now I'm learning Ruby on Rails, and I'm working through the book "Agile Web Development with Rails". I've also decided that I want to give Mercurial a go, because I've read up on distributed SCM's, and it seems like an ideal situation. I still, however, prefer to push my code remotely to my Linux VPS just incase my hard drive decides to take a dive.

So, my question is specific to branching in Mercurial. Right now I've got a remote repository set up and I can push changes over SSH easily (hell I even set up an Nginx FastCGI site that lets me push, too). What I'd like to do, however, is create branches for each chapter as I work on them, so I can keep a nice organized history of my progress through the book. So this is what I'm doing:

$ hg branch chapter-10
(do chapter 10 stuff)
$ hg commit -m "Chapter 10 complete"
$ hg update default
$ hg merge chapter-10
$ hg commit -m "Merging chapter 10 into default"
$ hg push

Once I execute the push statement, I get this message from Mercurial:

pushing to ssh://myserver/hg/depot
searching for changes
abort: push creates new remote branch 'chapter-10'!
(did you forget to merge? use push -f to force)

So at this point I try to do an hg merge again, and it tells me there's nothing to merge, which is obviously true because I just merged it. When I force the push with -f, everything seems fine, and even the web interface shows the appropriate branches.

To sum up, my question is simple: Am I doing this the right way? Is there a more appropriate way to do this with Mercurial (i.e. the "Mercurial way")? Honestly I just want the repository to serve as a backup. I'm a fan of the distributed SCM model, but to me it feels sorta "dirty" to force pushes. Any insight is greatly appreciated! Thanks in advance.

like image 938
Scott Anderson Avatar asked Jan 20 '10 06:01

Scott Anderson


People also ask

What is a branch in Mercurial?

Branches occur if lines of development diverge. The term "branch" may thus refer to a "diverged line of development". For Mercurial, a "line of development" is a linear sequence of consecutive changesets. Combining a line of development into an existing one is called merging. Creating a branch.

How do I merge Mercurials?

To merge two branches, you pull their heads into the same repository, update to one of them and merge the other, and then commit the result once you're happy with the merge.

How do I delete a branch in Mercurial?

You cannot. You can close the branch to hide it from the list of active branches, but you cannot completely delete it. This happens because in mercurial and in git the "branch" term means different things.


3 Answers

The push -f is the right option for your case, and there was a discussion last month to add that command when this "push creates new remote branch" warning pops up: see issue 1513.

However, issue 1974 (this month) mentions some undesirable effects (not in your case though).
See this translated article to know more about creating a second head on a remote repo.


On the more general point, you can use branch if you are writing your chapter in parallel, and you want to merge them only at certain (stable) point in time

But if your writing process is more linear, you could use only one branch, and put some tags along the way.
However, should you go back to chapter 10 and add some lines, even though you already put tags 11 and 12, that would make the history harder to read. So branches are still a good idea in this case.

like image 79
VonC Avatar answered Sep 23 '22 19:09

VonC


I don't know about your specific problem, but from your comments it seems that you use branches where you probably wanted to use tags.

Branches are generally used when multiple people cooperate on the same project and you want to create a work separation so one person can work on a stable piece of code, while the other does something experimental that temporarily breaks functionality. Alternatively branches are used to stabilize for release, while development is going on in trunk.

Tags (or labels) are used to primarily create a marker signifying some importance to the version of code. Like for example if you want to mark a completion of chapter 10, you just tag all current versions with a 'chapter-10' tag. There is no need to branch. You can branch from a tagged version at any point in future if it would be necessary for some reason.

like image 22
Jiri Klouda Avatar answered Sep 25 '22 19:09

Jiri Klouda


In this case I feel that it's totally ok to use -f for the push. It just creates new branches, not heads. Creating remote heads is another matter entirely.

like image 20
Ringding Avatar answered Sep 22 '22 19:09

Ringding