<p>Handling multiple merges onto branches in Subversion or CVS is just one of those things that has to be experienced. It is inordinately easier to keep track of branches and merges in Mercurial (and probably any other distributed system) but I don't know why. Does anyone else know?</p>

<p>My question stems from the fact that with Mercurial you can adopt a working practice similar to that of Subversions/CVSs central repository and everything will work just fine. You can do multiple merges on the same branch and you won't need endless scraps of paper with commit numbers and tag names.</p>

<p>I know the latest version of Subversion has the ability to track merges to branches so you don't get quite the same degree of hassle but it was a huge and major development on their side and it still doesn't do everything the development team would like it to do.</p>

<p>There must be a fundamental difference in the way it all works.</p>

[{'answer_id': 44030, 'author': 'RedWolves', 'author_id': 648, 'author_profile': 'https://Stackoverflow.com/users/648', 'pm_score': 1, 'selected': False, 'text': '<p>I only have experience with Subversion but I can tell you that the merge screen in TortoiseSVN is horribly complicated.  Luckily they include a dry run button so that you can see if you are doing it right.  The complication is in the configuration of what you want to merge to where.  Once you get that set up for the merge the merge generally goes fine.  Then you need to resolve any and all conflicts and then commit your merged in working copy to the repository.</p>\n\n<p>If Mercurial can make the configuration of the merge easier then I can say that would make merging 100% easier then Subversion.</p>\n'}, {'answer_id': 44057, 'author': 'Evil Andy', 'author_id': 4431, 'author_profile': 'https://Stackoverflow.com/users/4431', 'pm_score': 2, 'selected': False, 'text': "<p>I suppose this might partially be because Subversion has the idea of a central server along with an absolute time line of revisions. Mercurial is truly distributed and has no such reference to an absolute time line. This does allow Mercurial projects to form more complicated hierarchies of branches for adding features and testing cycles by sub project however teams now need to much more actively keep on top of merges to stay current as they can't just hit update and be done with it.</p>\n"}, {'answer_id': 44060, 'author': 'Stephen Darlington', 'author_id': 2998, 'author_profile': 'https://Stackoverflow.com/users/2998', 'pm_score': 2, 'selected': False, 'text': "<p>In Subversion (and CVS), the repository is first and foremost. In git and mercurial there is not really the concept of a repository in the same way; here <em>changes</em> are the central theme.</p>\n\n<p>I've not thought much about how you'd implement either but my impression (based on bitter experience and lots of reading) is that this difference is what makes merging and branching so much easier in non-repository based systems.</p>\n"}, {'answer_id': 44071, 'author': 'htanata', 'author_id': 4353, 'author_profile': 'https://Stackoverflow.com/users/4353', 'pm_score': 4, 'selected': False, 'text': "<p>Because Subversion (at least version 1.4 and below) doesn't keep track of what have been merged. For Subversion, merging is basically the same as any commit while on other version control like Git, what have been merged are remembered.</p>\n"}, {'answer_id': 44708, 'author': 'Damien Diederen', 'author_id': 3844, 'author_profile': 'https://Stackoverflow.com/users/3844', 'pm_score': 8, 'selected': True, 'text': '<blockquote>\n  <p>In Subversion (and CVS), the repository is first and foremost. In git\n  and mercurial there is not really the concept of a repository in the\n  same way; here changes are the central theme.</p>\n</blockquote>\n\n<p>+1</p>\n\n<p>The hassle in CVS/SVN comes from the fact that these systems do <strong>not</strong>\nremember the parenthood of changes.  In Git and Mercurial,\nnot only can a commit have multiple children, it can also have multiple\nparents!</p>\n\n<p>That can easily observed using one of the graphical tools, <code>gitk</code> or <code>hg\nview</code>.  In the following example, branch #2 was forked from #1 at\ncommit A, and has since been merged once (at M, merged with commit B):</p>\n\n<pre><code>o---A---o---B---o---C         (branch #1)\n     \\       \\\n      o---o---M---X---?       (branch #2)\n</code></pre>\n\n<p>Note how A and B have two children, whereas M has two <strong>parents</strong>.  These\nrelationships are <em>recorded</em> in the repository.  Let\'s say the maintainer of\nbranch #2 now wants to merge the latest changes from branch #1, they can\nissue a command such as:</p>\n\n<pre><code>$ git merge branch-1\n</code></pre>\n\n<p>and the tool will automatically know that the <em>base</em> is B--because it\nwas recorded in commit M, an ancestor of the tip of #2--and\nthat it has to merge whatever happened\nbetween B and C.  CVS does not record this information, nor did SVN prior to\nversion 1.5.  In these systems, the graph\nwould look like:</p>\n\n<pre><code>o---A---o---B---o---C         (branch #1)\n     \\    \n      o---o---M---X---?       (branch #2)\n</code></pre>\n\n<p>where M is just a gigantic "squashed" commit of everything that happened between A and B,\napplied on top of M.  Note that after the deed is done, there is <em>no trace\nleft</em> (except potentially in human-readable comments) of where M did\noriginate from, nor of <em>how many</em> commits were collapsed together--making\nhistory much more impenetrable.</p>\n\n<p>Worse still, performing a second merge becomes a nightmare: one has to figure out\nwhat the merge base was at the time of the first merge (and one <em>has</em> to <em>know</em>\nthat there has been a merge in the first place!), then\npresent that information to the tool so that it does not try to replay A..B on\ntop of M.  All of this is difficult enough when working in close collaboration, but is\nsimply impossible in a distributed environment.</p>\n\n<p>A (related) problem is that there is no way to answer the question: "does X\ncontain B?" where B is a\npotentially important bug fix.  So, why not just record that information in the commit, since\nit is <em>known</em> at merge time!</p>\n\n<p>P.-S. -- I have no experience with SVN 1.5+ merge recording abilities, but the workflow seems to be much more\ncontrived than in the distributed systems.  If that is indeed the case, it\'s probably because--as mentioned\nin the above comment--the focus is put on repository organization rather than on the changes themselves.</p>\n'}, {'answer_id': 3179838, 'author': 'Tomislav Nakic-Alfirevic', 'author_id': 279623, 'author_profile': 'https://Stackoverflow.com/users/279623', 'pm_score': 3, 'selected': False, 'text': '<p>Untouched by any of the already provided answers, Hg offered superior merge capabilities because it uses more information when merging changes (<a href="http://hginit.com/00.html" rel="noreferrer">hginit.com</a>):</p>\n\n<blockquote>\n  <p>For example, if I change a function a\n  little bit, and then move it somewhere\n  else, Subversion doesn’t really\n  remember those steps, so when it comes\n  time to merge, it might think that a\n  new function just showed up out of the\n  blue. Whereas Mercurial will remember\n  those things separately: function\n  changed, function moved, which means\n  that if you also changed that function\n  a little bit, it is much more likely\n  that Mercurial will successfully merge\n  our changes.</p>\n</blockquote>\n\n<p>Of course, remembering what was last merged (the point addressed by most of the answers provided here) is also a huge win.</p>\n\n<p>Both improvements, however, are questionable since subversion 1.5+ stores additional merge information in the form of subversion properties: that information available, there\'s no obvious reason why subversion merge couldn\'t implement merge as successfully as Hg or Git. I don\'t know if it does, though, but it certainly sounds like subversion developers are on their way to get around this issue.</p>\n'}]
['https://Stackoverflow.com/questions/43995', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4003/']