Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was recently discussing dvcs with a coworker, because our office is beginning to consider switching from TFS (we're a MS shop). In the process, I got very confused because he said that although he uses Mercurial, he hadn't heard of a "branch" or "checkout" command, and these terms were unfamiliar to him. After wondering how it was possible that he didn't know about them and explaining how dvcs branches work "in place" on your local files, he was quite confused.

He explained that, similar to how TFS works, when he wants to create a "branch" he does it by cloning, so he has an entire copy of his repo. This seemed really strange to me, but the benefit, which I have to concede, is that you can look at or work on two branches simultaneously because the files are separate.

In searching this site to see if this has been asked before I saw a comment that many online resources promote this "clone to branch" methodology, to the poster's dismay. Is this actually common in the dvcs community? And what are some of the pros and cons of going this way? I would never do it since I have no need to see multiple branches at once, switching is fast, and I don't need all the clones filling up my disk.

share|improve this question
7  
this is a hold over from CVS and SVN workflows, remember "to a hammer everything looks like a nail" –  Jarrod Roberson Jun 7 '12 at 15:20
1  
@JarrodRoberson - Only if you constrain yourself to the way git works. With hg this is usually the first workflow taught and it is still a very useful one. –  Mark Booth Jun 7 '12 at 22:26

3 Answers 3

Apart from the general advantage/disadvantage of being able to see both branches, I think there's a Mercurial-specific advantage to doing that.

If you clone to create a branch, you can delete the clone later if you don't want to keep your changes. If you decide to merge them, then the fact that you decided to separate your changes out in this way isn't visible to anybody else.

By contrast, if you use hg branch to create a new named branch, the branch name is recorded in the history when you commit, is visible to everybody else, and has to be fairly unique in order to avoid potential confusion later. This might not be appropriate if your branch is for developing some experimental feature, or for a change that might turn out to be small.

If you use named branches to maintain released versions of your software and also use them for developing short-term features or bugfixes, it's easy to become confused because there is no way (besides naming conventions) to keep these two kinds of branches separate.

http://mercurial.selenic.com/wiki/StandardBranching explains this in more detail. It's also worth mentioning that since Mercurial 1.8, it's possible to create a bookmark (hg bookmark) - a disposable name for a short-lived branch. Bookmarks can be pushed, pulled, moved around and deleted.

share|improve this answer
2  
I haven't used Mercurial much but Git does not have this problem. I can branch all day long locally, merge into develop branch, push and no one has to look at my branch names. –  Andrew Finnell Jun 7 '12 at 20:01
3  
@AndrewFinnell: It didn't really fit into the question, but I wanted to say that it's not necessarily a problem - there are also some advantages to the way named branches in Mercurial work. For example, you can see which branch a commit was originally made on, which can be useful to know. –  benj Jun 7 '12 at 20:38
1  
@AndrewFinnell - Named branches are something I really miss in git, having got used to them in hg. Also, having to remember to explicitly git branch every time I want to create a branch is annoying, compared to hg's automatic creation of unnamed branches. –  Mark Booth Jun 7 '12 at 22:18
    
You can still use the bundled strip extension to delete your branch in hg. Mercurial supports history modification better this days through the use of "phases" –  dukeofgaming Jun 8 '12 at 15:45

Every time you make a commit in a DVCS you are technically making a branch in the history, every time you push it back to the blessed repository you integrate it back, here comes the interesting part:

  • If no one made a change during your commit, it won't look like a branch in the DAG (directed acyclic graph)
  • If someone else made a change during your commit, it will look like a branch in the DAG, only unnamed

Remember the "fork" button in Bitbucket/github?, forking can be regarded as a synonymous of branching, and what the "fork" button does is just a clone of that repository to your account.

The only advantage of "cloning to branch" is being able to work simultaneously at two points in the history, and ironically for your coworker, it is a common workflow for working on different branches at the same time (without having to go back and forth).

Tell your coworker to learn how to branch, it is very easy, here, have a tutorial:

D:\>mkdir lol

D:\>cd lol

D:\lol>hg init

D:\lol>hg branch
default

D:\lol>touch lol

D:\lol>hg add lol

D:\lol>hg commit -m "lol"

D:\lol>hg branch lol
marked working directory as branch lol
(branches are permanent and global, did you want a bookmark?)

D:\lol>hg branches
default                        0:35d562fafaf2

D:\lol>echo "lol" > lol

D:\lol>hg commit -m "New lol branch"

D:\lol>hg branches
lol                            1:9384f923e78d
default                        0:35d562fafaf2 (inactive)

D:\lol>hg branch
lol

D:\lol>hg update default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

D:\lol>hg branch
default

D:\lol>hg update lol
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

D:\lol>hg branch
lol

D:\lol>hg update default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

D:\lol>hg branch
default

D:\lol>hg merge lol
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

D:\lol>hg commit -m "lol merge"

D:\lol>hg branch
default

D:\lol>hg update lol
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

D:\lol>hg branch
lol

"Cloning to branch" makes sense when you are working in different branches at the same time, or, when you want to try out an experiment without creating a permanent branch in the history and still be able to integrate it back to an already existing branch.

I personally don't like this practice and prefer to do branches and close them if necessary. Here, this is how you do it:

D:\lol>hg branches
default                        2:46420aca1612
lol                            1:9384f923e78d (inactive)

D:\lol>hg branch
lol

D:\lol>hg commit --close-branch -m "Obai, glorious lol branch"

D:\lol>hg branches
default                        2:46420aca1612

D:\lol>hg branch
lol

D:\lol>hg update default
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

D:\lol>hg branches
default                        2:46420aca1612

D:\lol>hg branches --closed
default                        2:46420aca1612
lol                            3:4b79c577e029 (closed)

Hope this clears out your DVCS branching doubts, here branches are not scary anymore.

share|improve this answer

I wouldn't personally worry about code filling up my disk... first, it's just code, and second, you're not going to keep all of your clones around forever.

This methodology is promoted in a lot of online resources, especially for Hg. I've never seen it used in production, in CI environments it's much more common to have short lived feature branches than additional repository clones. I don't see the advantage of doing this, if anything it's going to make your history more confusing, not less, and it also doesn't gain you anything. If you want to look at your new code side by side with the old code you can use a diff/merge tool to look at the two commits next to each other, with the added advantage that you will see your changes highlighted.

share|improve this answer
    
I've used this extensively in production, with hg. Being able to push and pull between multiple hg repositories can be a really powerful collaborative tool. Only being able to pull from non-bare git repositories can substantially limit your options with this sort of workflow. –  Mark Booth Jun 7 '12 at 22:21

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.