{"thread":{"id":"4844","subject":"Why doesn't git-rerere automatically commit a resolution?","startedAt":"2006-07-11T06:16:26Z","lastAt":"2006-07-11T13:29:50Z","messageCount":4,"participants":["Shawn Pearce","Junio C Hamano","Matthias Kestenholz"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"23617","messageId":"20060711061626.GB11822@spearce.org","threadId":"4844","inReplyTo":null,"subject":"Why doesn't git-rerere automatically commit a resolution?","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-07-11T06:16:26Z","receivedAt":"2006-07-11T06:16:26Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"I'm curious... I have a pair of topic branches which don't merge\ntogether cleanly by recursive (due to conflicting hunks in the\nsame line segments).  I enabled git-rerere, ran the merge, fixed\nup the hunks and committed it.  git-rerere built its cache, as\nthe next time I pulled the two topic branches together and got\nthe same conflicts it correctly regenerated the prior resolution\n(and printed a message saying as much).\n\nBut it git-rerere left the files unmerged in the index and it\ndoesn't generate a commit for the merge, even though there are no\nmerge conflicts remaining.  I expected it to update the index (to\nmerge the stages) and to generate a commit if possible; especially\nin this case as I was pulling the exact same two commits together\nagain with the exact same merge base commit.\n\nSo I'm wondering why doesn't it try to finish the merge?  Was there\na really deep rooted reason behind it or was it simply easier/safer\nto let the user sort out the working directory state every time?\n\n-- \nShawn.\n"},{"id":"23620","messageId":"7v8xn06310.fsf@assigned-by-dhcp.cox.net","threadId":"4844","inReplyTo":"20060711061626.GB11822@spearce.org","subject":"Re: Why doesn't git-rerere automatically commit a resolution?","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-07-11T06:58:51Z","receivedAt":"2006-07-11T06:58:51Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Shawn Pearce <spearce@spearce.org> writes:\n\n> I'm curious... I have a pair of topic branches which don't merge\n> together cleanly by recursive (due to conflicting hunks in the\n> same line segments).  I enabled git-rerere, ran the merge, fixed\n> up the hunks and committed it.  git-rerere built its cache, as\n> the next time I pulled the two topic branches together and got\n> the same conflicts it correctly regenerated the prior resolution\n> (and printed a message saying as much).\n\nAfter all your merge is conflicting, so it should be sanity\nchecked.  At least you would want to run a compile test and\npreferably a whole test cycle if your project has one, before\nmaking the result into a commit.\n\nYou _could_ make it to automatically make a commit, and run a\ntest then if the test does not succeed fix the mismerge with \"git\ncommit --amend\", but people are lazy.\n\n> So I'm wondering why doesn't it try to finish the merge?  Was there\n> a really deep rooted reason behind it or was it simply easier/safer\n> to let the user sort out the working directory state every time?\n\nThe philosophy is to optimize the tools to support disciplined\nworkflows better, and make sure that the users do not have to\nworry about automated tools makeing mismerges.\n\nNow, I am not against helping lazy workflows per se, but only on\none condition.  Doing so should never make more disciplined\nworkflows harder or more difficult.\n\nNot merging the index after rerere re-applies a previous\nresolution to the working tree file is a deliberate design\ndecision.  During conflict resolution, \"git diff\" against\nunmerged index file is the second most useful command to check\nyour hand-merge result, and running update-index on these path\nautomatically robs this useful tool from the user.  So, in order\nto help more disciplined workflow, a bit of convenience for\nlazier people is sacrficed here.\n"},{"id":"23621","messageId":"20060711070518.GB4201@spinlock.ch","threadId":"4844","inReplyTo":"20060711061626.GB11822@spearce.org","subject":"Re: Why doesn't git-rerere automatically commit a resolution?","fromName":"Matthias Kestenholz","fromEmail":"lists@spinlock.ch","sentAt":"2006-07-11T07:05:18Z","receivedAt":"2006-07-11T07:05:18Z","isPatch":false,"sender":{"key":"lists@spinlock.ch","avatar":null},"body":"* Shawn Pearce (spearce@spearce.org) wrote:\n> I'm curious... I have a pair of topic branches which don't merge\n> together cleanly by recursive (due to conflicting hunks in the\n> same line segments).  I enabled git-rerere, ran the merge, fixed\n> up the hunks and committed it.  git-rerere built its cache, as\n> the next time I pulled the two topic branches together and got\n> the same conflicts it correctly regenerated the prior resolution\n> (and printed a message saying as much).\n> \n> But it git-rerere left the files unmerged in the index and it\n> doesn't generate a commit for the merge, even though there are no\n> merge conflicts remaining.  I expected it to update the index (to\n> merge the stages) and to generate a commit if possible; especially\n> in this case as I was pulling the exact same two commits together\n> again with the exact same merge base commit.\n> \n> So I'm wondering why doesn't it try to finish the merge?  Was there\n> a really deep rooted reason behind it or was it simply easier/safer\n> to let the user sort out the working directory state every time?\n> \n\nI am maintaining different websites from one git repository. The\ncode is almost the same between all versions, but the HTML templates\nare not. Sometimes, modified templates in feature branches produce\nmismerges which I want to fix up in different ways for different\nwebsites. There, git-rerere doesn't help me at all. It does help \nvery much with the code and configuration files though.\n\nTo conclude, I have rerere enabled, but it does not always do the\nright thing, so I am happy that I get a chance to inspect the files\nbefore committing (I could also amend the commit later, but I still\nthink it's better that the user still needs to acknowledge the\nresult of the automatic merge.)\n\n\tMatthias\n"},{"id":"23637","messageId":"20060711132950.GA5856@spearce.org","threadId":"4844","inReplyTo":"7v8xn06310.fsf@assigned-by-dhcp.cox.net","subject":"Re: Why doesn't git-rerere automatically commit a resolution?","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-07-11T13:29:50Z","receivedAt":"2006-07-11T13:29:50Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Not merging the index after rerere re-applies a previous\n> resolution to the working tree file is a deliberate design\n> decision.  During conflict resolution, \"git diff\" against\n> unmerged index file is the second most useful command to check\n> your hand-merge result, and running update-index on these path\n> automatically robs this useful tool from the user.  So, in order\n> to help more disciplined workflow, a bit of convenience for\n> lazier people is sacrficed here.\n\nOK, I agree with all of the above.  Except in the following case:\n\n\tgit update-ref BACKUP HEAD\n\tgit pull . sp/topicA\n\tgit pull . sp/topicB\n\t..fix conflicts..\n\tgit commit -F .git/MERGE_MSG\n\tgit reset --hard BACKUP\n\n\tgit pull . sp/topicA\n\tgit pull . sp/topicB\n\t..ah, come on!..\n\nBy pulling the exact same two heads together in the exact same\norder I would expect the exact same merge result.  And since I\nhave git-rerere enabled I would expect it to autocommit the result\nof the merge as I have already checked it before and verified its\ncorrect when I first fixed the conflicts.\n\nAfter reading your message I agree with you however that pulling in\nthe reverse direction (e.g. topicB then topicA) shouldn't autocommit\nthe merge result as I haven't hand verified it to be correct - yet.\nHowever if I do and I merge it again later with the same two commits\nthen it should still be correct.\n\nFurther if I alter sp/topicA by changing a file path which wasn't\nconflicted in the merge with sp/topicB I would expect it to\ncarry out the merge assuming the conflicts were remembered as-is.\nBecause that's what a trivial in-index merge would do and that will\ncommit despite conflicts possibly existing between files.\n\n\nI guess what I'm saying is maybe git-rerere (or git-merge in general)\ncould benefit from a slightly higher level cache.  Store 4 sets\nof (mode, sha1) tuples: stage1 stage2 stage3 result in a cache\nsomewhere.  If you get a conflicted merge which has been previously\nfixed by hand wherein all 3 stages in the index are found in the\ncache then update the index and working directory with the result\n(mode, sha1) tuple.\n\nIf any of the 3 stages differs then fall back to git-rerere and\nattempt a file level merge, stopping before commit to allow the\nuser to verify (and possibly correct) the resulting merge.\n\nOne advantage of this higher level cache is it can be used for\nbinary files which `merge` can't normally process, as well as for\nstructual conflicts.\n\nThoughts?  I can prototype this higher level cache into git-rerere\nlater tonight after I get home from work.\n\n-- \nShawn.\n"}]}