{"thread":{"id":"1728","subject":"Multi-ancestor read-tree notes","startedAt":"2005-09-05T05:41:36Z","lastAt":"2005-09-11T16:45:10Z","messageCount":18,"participants":["Daniel Barkalow","Junio C Hamano","Darrin Thompson","Fredrik Kuivinen","Matthias Urlichs"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"8078","messageId":"Pine.LNX.4.63.0509050049030.23242@iabervon.org","threadId":"1728","inReplyTo":null,"subject":"Multi-ancestor read-tree notes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-09-05T05:41:36Z","receivedAt":"2005-09-05T05:41:36Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"I've got a version of read-tree which accepts multiple ancestors and does \na merge using information from all of them.\n\nThe basic features are that it looks for an ancestor which would permit a \ntrivial merge, and uses that. However, if it finds ancestors which permit \ndifferent trivial merges, it does not merge (which I call case #16).\n\nIn case #16, I'm not sure what I should produce. I think the best thing \nmight be to not leave anything in stage 1. The desired end effect is that \nthe user is given a file with a section like:\n\n  {\n    *t = NULL;\n    *m = 0;\n<<<<<<<<\n    return Z_DATA_ERROR;\n========\n    return Z_OK;\n>>>>>>>>\n  }\n\nIn other news, the merge that was giving Len Brown problems a while ago \nturns out to have the above conflict, and he happened to end up doing the \nright thing and not reverting Linus's revert of an unnecessary (but \nharmless) change. I only noticed this just now, when I was testing that \nmerge, and got it to generate only two conflicts regardless of order of \nancestors (didn't try to resolve the other one, drivers/acpi/osl.c, with \n\"merge\" either way).\n\nSo this test is encouraging: I get fewer non-trivial cases than either of \nthe ancestors alone gives, and I catch a case that both single ancestors \ngets wrong.\n\nNote that there are still some memory leaks for me to fix, but that's the \nonly flaw I know of with this.\n\nPatches against mainline to follow shortly.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"8116","messageId":"7virxeycod.fsf@assigned-by-dhcp.cox.net","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509050049030.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-09-06T05:42:42Z","receivedAt":"2005-09-06T05:42:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> I've got a version of read-tree which accepts multiple ancestors and does \n> a merge using information from all of them.\n\nAfter disabling the debugging printf(), I used this read-tree to\ntry resolving the parents of four commits Fredrik Kuivinen gave\nus in <20050827014009.GB18880@c165.ib.student.liu.se> using\ntheir two merge bases, and compared the resulting tree with the\ntree recorded in the commit.  The results are really promising.\n\nFor the following two commits, multi-base merge resolved their\nparents trivially and produced the same result as the tree in\nthe commit.  The current \"best-base merge\" in the master branch\nperformed far worse and left many conflicts.\n\n - 467ca22d3371f132ee225a5591a1ed0cd518cb3d \n - da28c12089dfcfb8695b6b555cdb8e03dda2b690\n\nAnother one, 0e396ee43e445cb7c215a98da4e76d0ce354d9d7,\nmulti-base merge left only one conflicting path to be hand\nresolved.  The best-base merge again performed far worse.\n\nThe other one, 3190186362466658f01b2e354e639378ce07e1a9, is\nresolved trivially with both algorithms.\n\n> In case #16, I'm not sure what I should produce. I think the best thing \n> might be to not leave anything in stage 1.\n\nBecause?  I know it would affect the readers of index files if\nyou did so, but it would seem the most natural in git\narchitecture to have merge-cache look at the resulting cache\nwith such multiple stage 1 entries (and other stages) and let\nthe script make a decision.\n\n> The desired end effect is that the user is given a file with a\n> section like:\n>\n>   {\n>     *t = NULL;\n>     *m = 0;\n> <<<<<<<<\n>     return Z_DATA_ERROR;\n> ========\n>     return Z_OK;\n>>>>>>>>>\n>   }\n\nSounds fine.\n\nAnyway, I really am happy to see this multi-base merge perform\nwell on real-world data, and you are certainly the git hero of\nthe week ;-).\n"},{"id":"8130","messageId":"Pine.LNX.4.63.0509061228090.23242@iabervon.org","threadId":"1728","inReplyTo":"7virxeycod.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-ancestor read-tree notes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-09-06T17:43:08Z","receivedAt":"2005-09-06T17:43:08Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Mon, 5 Sep 2005, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > I've got a version of read-tree which accepts multiple ancestors and does \n> > a merge using information from all of them.\n> \n> After disabling the debugging printf(), I used this read-tree to\n> try resolving the parents of four commits Fredrik Kuivinen gave\n> us in <20050827014009.GB18880@c165.ib.student.liu.se> using\n> their two merge bases, and compared the resulting tree with the\n> tree recorded in the commit.  The results are really promising.\n> \n> For the following two commits, multi-base merge resolved their\n> parents trivially and produced the same result as the tree in\n> the commit.  The current \"best-base merge\" in the master branch\n> performed far worse and left many conflicts.\n> \n>  - 467ca22d3371f132ee225a5591a1ed0cd518cb3d \n>  - da28c12089dfcfb8695b6b555cdb8e03dda2b690\n> \n> Another one, 0e396ee43e445cb7c215a98da4e76d0ce354d9d7,\n> multi-base merge left only one conflicting path to be hand\n> resolved.  The best-base merge again performed far worse.\n> \n> The other one, 3190186362466658f01b2e354e639378ce07e1a9, is\n> resolved trivially with both algorithms.\n\nDo you know if there's anything like case #16 in there? I'd be interested \nto know if there's anything that gets handled automatically in different \nways depending on which single base is used, and doesn't require manual \nintervention with multiple bases, because that's probably wrong.\n\n> > In case #16, I'm not sure what I should produce. I think the best thing \n> > might be to not leave anything in stage 1.\n> \n> Because?  I know it would affect the readers of index files if\n> you did so, but it would seem the most natural in git\n> architecture to have merge-cache look at the resulting cache\n> with such multiple stage 1 entries (and other stages) and let\n> the script make a decision.\n\nI didn't want to break the assumption of only one entry per stage in the \ninitial version. I'm also not sure that listing the ancestors is \nparticularly useful in this case. They have to be exactly the contents of \nstages 2 and 3, plus possibly more stuff that's not been kept by either \nside. What you actually want is a two-way merge (i.e., a diff between the \ntwo sides, presented in \"merge\" format), so you don't really need any \nancestors, unless it would fit some more general case that way.\n\n> > The desired end effect is that the user is given a file with a\n> > section like:\n> >\n> >   {\n> >     *t = NULL;\n> >     *m = 0;\n> > <<<<<<<<\n> >     return Z_DATA_ERROR;\n> > ========\n> >     return Z_OK;\n> >>>>>>>>>\n> >   }\n> \n> Sounds fine.\n> \n> Anyway, I really am happy to see this multi-base merge perform\n> well on real-world data, and you are certainly the git hero of\n> the week ;-).\n\nGreat. Want me to send the patches with better organization, or are you \nset with what I've sent?\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"8137","messageId":"7vbr36j75b.fsf@assigned-by-dhcp.cox.net","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509061228090.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-09-06T20:03:28Z","receivedAt":"2005-09-06T20:03:28Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> Do you know if there's anything like case #16 in there? I'd be interested \n> to know if there's anything that gets handled automatically in different \n> ways depending on which single base is used, and doesn't require manual \n> intervention with multiple bases, because that's probably wrong.\n\nRe-running the tests with the attached patch shows there weren't any.\n\n> I didn't want to break the assumption of only one entry per stage in the \n> initial version. I'm also not sure that listing the ancestors is \n> particularly useful in this case. They have to be exactly the contents of \n> stages 2 and 3, plus possibly more stuff that's not been kept by either \n> side.\n\nAh, I see, that's true.\n\n> Great. Want me to send the patches with better organization, or are you \n> set with what I've sent?\n\nThat's up to you.  If you are content with what I have in the pu\nbranch, there is no need to bother resending.  OTOH if you have\nfurther clean-ups in mind, i.e. \"better organization\" above, I\ndo not mind dropping the current ones from \"pu\" and replace them\nwith another set from you.\n\n------------\n[PATCH] Add debugging help for case #16 to read-tree.c\n\nThis will help us detect if real-world example merges have multiple\nmerge-base candidates and one of them matches one head while another\nmatches the other head.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n read-tree.c                 |   36 ++++++++++++++++++++++++++++--------\n t/t1000-read-tree-m-3way.sh |   16 ++++++++++++++++\n 2 files changed, 44 insertions(+), 8 deletions(-)\n\n6405d0aa729f4b060123e1235b3ddc074fdd01b7\ndiff --git a/read-tree.c b/read-tree.c\n--- a/read-tree.c\n+++ b/read-tree.c\n@@ -3,6 +3,8 @@\n  *\n  * Copyright (C) Linus Torvalds, 2005\n  */\n+#define DBRT_DEBUG 1\n+\n #include \"cache.h\"\n \n #include \"object.h\"\n@@ -47,8 +49,6 @@ static int entcmp(char *name1, int dir1,\n \treturn ret;\n }\n \n-#define DBRT_DEBUG 0\n-\n static int unpack_trees_rec(struct tree_entry_list **posns, int len,\n \t\t\t    const char *base, merge_fn_t fn, int *indpos)\n {\n@@ -101,14 +101,14 @@ static int unpack_trees_rec(struct tree_\n \t\t\t}\n \t\t}\n \n-#if DBRT_DEBUG\n+#if DBRT_DEBUG > 1\n \t\tif (first)\n \t\t\tprintf(\"index %s\\n\", first);\n #endif\n \t\tfor (i = 0; i < len; i++) {\n \t\t\tif (!posns[i] || posns[i] == &df_conflict_list)\n \t\t\t\tcontinue;\n-#if DBRT_DEBUG\n+#if DBRT_DEBUG > 1\n \t\t\tprintf(\"%d %s\\n\", i + 1, posns[i]->name);\n #endif\n \t\t\tif (!first || entcmp(first, firstdir,\n@@ -188,7 +188,7 @@ static int unpack_trees_rec(struct tree_\n \t\t\tif (merge) {\n \t\t\t\tint ret;\n \n-#if DBRT_DEBUG\n+#if DBRT_DEBUG > 1\n \t\t\t\tprintf(\"%s:\\n\", first);\n \t\t\t\tfor (i = 0; i < src_size; i++) {\n \t\t\t\t\tprintf(\" %d \", i);\n@@ -200,7 +200,7 @@ static int unpack_trees_rec(struct tree_\n #endif\n \t\t\t\tret = fn(src);\n \t\t\t\t\n-#if DBRT_DEBUG\n+#if DBRT_DEBUG > 1\n \t\t\t\tprintf(\"Added %d entries\\n\", ret);\n #endif\n \t\t\t\t*indpos += ret;\n@@ -353,6 +353,19 @@ static int keep_entry(struct cache_entry\n \treturn 1;\n }\n \n+#if DBRT_DEBUG\n+static void show_stage_entry(FILE *o,\n+\t\t\t     const char *label, const struct cache_entry *ce)\n+{\n+\tfprintf(stderr, \"%s%06o %s %d\\t%s\\n\",\n+\t\tlabel,\n+\t\tntohl(ce->ce_mode),\n+\t\tsha1_to_hex(ce->sha1),\n+\t\tce_stage(ce),\n+\t\tce->name);\n+}\n+#endif\n+\n static int threeway_merge(struct cache_entry **stages)\n {\n \tstruct cache_entry *index;\n@@ -392,10 +405,10 @@ static int threeway_merge(struct cache_e\n \tif (!same(remote, head)) {\n \t\tfor (i = 1; i < head_idx; i++) {\n \t\t\tif (same(stages[i], head)) {\n-\t\t\t\thead_match = 1;\n+\t\t\t\thead_match = i;\n \t\t\t}\n \t\t\tif (same(stages[i], remote)) {\n-\t\t\t\tremote_match = 1;\n+\t\t\t\tremote_match = i;\n \t\t\t}\n \t\t}\n \t}\n@@ -450,6 +463,13 @@ static int threeway_merge(struct cache_e\n \t\t\t}\n \t\t}\n \t}\n+#if DBRT_DEBUG\n+\telse {\n+\t\tfprintf(stderr, \"read-tree: warning #16 detected\\n\");\n+\t\tshow_stage_entry(stderr, \"head   \", stages[head_match]);\n+\t\tshow_stage_entry(stderr, \"remote \", stages[remote_match]);\n+\t}\n+#endif\n \tif (head) { count += keep_entry(head); }\n \tif (remote) { count += keep_entry(remote); }\n \treturn count;\ndiff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh\n--- a/t/t1000-read-tree-m-3way.sh\n+++ b/t/t1000-read-tree-m-3way.sh\n@@ -218,6 +218,9 @@ currently implemented.\n                                            or (2) match B.\n  ------------------------------------------------------------------\n  15  exists  O==A    O==B      take B      must match A if exists.\n+ ------------------------------------------------------------------\n+ 16  exists  O==A    O==B      barf        must match A if exists.\n+     *multi* in one  in another\n -------------------------------------------------------------------\n \n Note: if we want to implement 2ALT and 3ALT we need to be careful.\n@@ -514,4 +517,17 @@ test_expect_failure \\\n      git-update-cache --add NN &&\n      git-read-tree -m $tree_O $tree_A $tree_B\"\n \n+# #16\n+test_expect_success \\\n+    '16 - A matches in one and B matches in another.' \\\n+    'rm -f .git/index F16 &&\n+    echo F16 >F16 &&\n+    git-update-cache --add F16 &&\n+    tree0=`git-write-tree` &&\n+    echo E16 >F16 &&\n+    git-update-cache F16 &&\n+    tree1=`git-write-tree` &&\n+    git-read-tree -m $tree0 $tree1 $tree1 $tree0 &&\n+    git-ls-files --stage'\n+\n test_done\n"},{"id":"8138","messageId":"Pine.LNX.4.63.0509061610080.23242@iabervon.org","threadId":"1728","inReplyTo":"7vbr36j75b.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-ancestor read-tree notes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-09-06T20:25:44Z","receivedAt":"2005-09-06T20:25:44Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 6 Sep 2005, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > Do you know if there's anything like case #16 in there? I'd be interested \n> > to know if there's anything that gets handled automatically in different \n> > ways depending on which single base is used, and doesn't require manual \n> > intervention with multiple bases, because that's probably wrong.\n> \n> Re-running the tests with the attached patch shows there weren't any.\n\nGood. (Although that patch doesn't seem to be directly on top of my \nversion; I can tell what it's doing anyway)\n\n> > Great. Want me to send the patches with better organization, or are you \n> > set with what I've sent?\n> \n> That's up to you.  If you are content with what I have in the pu\n> branch, there is no need to bother resending.  OTOH if you have\n> further clean-ups in mind, i.e. \"better organization\" above, I\n> do not mind dropping the current ones from \"pu\" and replace them\n> with another set from you.\n\nI'm happy with the content in \"pu\"; the issue is just whether you want the \nhistory cleaned up more. In the series I sent, I kept forgetting parts \nthat belonged in earlier patches.\n\nCould you look over the documentation in \nDocumentation/technical/trivial-merge.txt, and see if it's a suitable \nreplacement for the table in t1000-read-tree-m-3way.sh? It should be the \nsame, except for ALT or non-ALT versions that we're not using, combining a \nfew matching cases, describing the rules behind index requirements rather \nthan listing outcomes, and the addition of info on how multiple ancestors \nare handled.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"8146","messageId":"7vslwhg8xe.fsf@assigned-by-dhcp.cox.net","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509061610080.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-09-06T21:53:17Z","receivedAt":"2005-09-06T21:53:17Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> Good. (Although that patch doesn't seem to be directly on top of my \n> version; I can tell what it's doing anyway)\n\nThat one was against the proposed updates head.  I've updated it\nagain to include the patch.\n\n> I'm happy with the content in \"pu\"; the issue is just whether you want the \n> history cleaned up more. In the series I sent, I kept forgetting parts \n> that belonged in earlier patches.\n\nAgain, that is up to you.  I am not _that_ perfectionist but I\ndo not mind reapplying updated ones if you are ;-).\n\n> Could you look over the documentation in\n> Documentation/technical/trivial-merge.txt, and see if it's a\n> suitable replacement for the table in\n> t1000-read-tree-m-3way.sh?\n\nI do not understand what you meant by '*' and 'index+' in\none-way merge table.  I take the first row ('*') to mean \"If the\ntree is missing a path, that path is removed from the index.\"\n\nI like the second sentence in three-way merge description.  That\nis a very easy-to-understand description of what the index\nrequirements are.\n\nYou have 2 2ALTs.  Also 14 and 14ALT look like they are the same\nrule now.\n\nWhat's \"(empty)^\" in \"ancest\"?  All of them must be empty for\nthis rule to apply?\n\nI am not quite sure it is 'a suitable replacement' yet; the\nexisting table you can see it covers all the cases, but with\nthings like \"'ancestor+' means one of them matches\", I cannot\nreally tell the table covers all the cases or some cases fall of\nthe end of the chain.\n\nAlso when we have more than one ancestors or one remotes and we\nsay \"no merge\", it is still unspecified (and I have to admit I\ncannot readily say what the result should be for all of them,\nexcept that I agree #16 will be fine with an empty stage1) what\nare left in which stages.\n\nI personally think the exotic cases (i.e. no rule applies, or\n\"no merge\" result with more than one ancestors/remotes) needs to\nbe handled outside read-tree anyway, by the script that drives\nread-tree to attempt trivial merges.  That is the core of the\ngit-resolve-script would become:\n\n    bases=`git-merge-base -a $ours $theirs` || exit\n    git-read-tree -m -u $bases $ours $theirs\n    case \"$?\" in\n    0)\n        # trivially resolved; nothing to do.\n        ;;\n    1)\n        # no exotic cases -- just do it the old way.\n    \tgit-merge-cache -o git-merge-one-file-script -a ;;\n    2)\n        # exotic cases like #16 and any other.\n        # maybe try different heuristics, like best-base, from\n        # scratch.\n        git-read-tree --reset $ours\n        ... attempt different merge policies ...\n        ;;\n    esac\n\nSo in that sense it probably does not matter what we leave in\nstage1/2/3 in such cases as long as the command fails in such a\nway that allows us to tell what happened.\n"},{"id":"8148","messageId":"Pine.LNX.4.63.0509061819340.23242@iabervon.org","threadId":"1728","inReplyTo":"7vslwhg8xe.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-ancestor read-tree notes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-09-06T22:59:29Z","receivedAt":"2005-09-06T22:59:29Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 6 Sep 2005, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > Good. (Although that patch doesn't seem to be directly on top of my \n> > version; I can tell what it's doing anyway)\n> \n> That one was against the proposed updates head.  I've updated it\n> again to include the patch.\n> \n> > I'm happy with the content in \"pu\"; the issue is just whether you want the \n> > history cleaned up more. In the series I sent, I kept forgetting parts \n> > that belonged in earlier patches.\n> \n> Again, that is up to you.  I am not _that_ perfectionist but I\n> do not mind reapplying updated ones if you are ;-).\n\nWhat's there is fine with me.\n\n(I'll work on improving the documentation as a further patch)\n\n> > Could you look over the documentation in\n> > Documentation/technical/trivial-merge.txt, and see if it's a\n> > suitable replacement for the table in\n> > t1000-read-tree-m-3way.sh?\n> \n> I do not understand what you meant by '*' and 'index+' in\n> one-way merge table.  I take the first row ('*') to mean \"If the\n> tree is missing a path, that path is removed from the index.\"\n\n'*' means that that case applies regardless of what's there. 'index+' \nmeans that it's the index, with the stat information. I forgot to actually \nexplain the table before going on to the interesting section.\n\n> I like the second sentence in three-way merge description.  That\n> is a very easy-to-understand description of what the index\n> requirements are.\n> \n> You have 2 2ALTs.  Also 14 and 14ALT look like they are the same\n> rule now.\n\nAh, right. I had originally listed \"index\" in the table, with separate \ncases for having it match the head and having it match the result, but \nthen ditched that when I figured out how that actually works.\n\n> What's \"(empty)^\" in \"ancest\"?  All of them must be empty for\n> this rule to apply?\n\nThe '^' means that all must be like that. \n\nI have to check, but I think that 8ALT and 10ALT should be '+'.\n\n> I am not quite sure it is 'a suitable replacement' yet; the\n> existing table you can see it covers all the cases, but with\n> things like \"'ancestor+' means one of them matches\", I cannot\n> really tell the table covers all the cases or some cases fall of\n> the end of the chain.\n\nAll of the \"any ancestor\" spots are good for covering things. Case #11 \n(which actually needs to be at the bottom) is basically \"everything else\".\n\n> Also when we have more than one ancestors or one remotes and we\n> say \"no merge\", it is still unspecified (and I have to admit I\n> cannot readily say what the result should be for all of them,\n> except that I agree #16 will be fine with an empty stage1) what\n> are left in which stages.\n\nPresently, except for case #16, only the first ancestor is used in \"no \nmerge\" output. The right thing should be worked out and documented, of \ncourse.\n\nI'm not at all convinced at this point that we can do much with multiple \nremotes in a single application of the rules; you won't necessarily have \nthe same merge base for all pairs, and all sorts of things go wrong if you \nstart including ancestors that aren't related to something, or not \nincluding common ancestors of some pair.\n\nWhat might work is to have the error for an unmerged index only happen \nwhen you get to a \"no merge\" result, so that you can get as many conflicts \nas possible (in different files) resolved by the user at the same time.\n\n> I personally think the exotic cases (i.e. no rule applies, or\n> \"no merge\" result with more than one ancestors/remotes) needs to\n> be handled outside read-tree anyway, by the script that drives\n> read-tree to attempt trivial merges.\n\nI think case #16 would benefit from doing more stuff, but there aren't any \nholes in the rules, and I think that, for the multiple ancestors in \"no \nmerge\", we just want to use the one with the least conflict. (Or, if we \nwrite our own merge, do a #16/#13,#14/#11 decision per-hunk in our merge, \nwhich is the really right thing). I think the common case for multiple \nancestors will really be that you've got a side branch that split before \nthe split you're resolving, and was merged into both sides before now; in \nthis case, there's no big problem, and it's not the exotic cross-merge \ncase. Of course, we won't see this in projects like the kernel and git, \nwhich aren't that amorphous.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"8209","messageId":"1126199765.3984.1.camel@localhost.localdomain","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509050049030.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Darrin Thompson","fromEmail":"darrint@progeny.com","sentAt":"2005-09-08T17:16:05Z","receivedAt":"2005-09-08T17:16:05Z","isPatch":false,"sender":{"key":"darrint@progeny.com","avatar":null},"body":"On Mon, 2005-09-05 at 01:41 -0400, Daniel Barkalow wrote:\n> I've got a version of read-tree which accepts multiple ancestors and does \n> a merge using information from all of them.\n\nDo the multiple ancestors have to share a common parent? More to the\npoint, is this read-tree any more friendly to baseless merges?\n\n--\nDarrin\n"},{"id":"8210","messageId":"20050908203756.GB26088@c165.ib.student.liu.se","threadId":"1728","inReplyTo":"1126199765.3984.1.camel@localhost.localdomain","subject":"Re: Multi-ancestor read-tree notes","fromName":"Fredrik Kuivinen","fromEmail":"freku045@student.liu.se","sentAt":"2005-09-08T20:37:56Z","receivedAt":"2005-09-08T20:37:56Z","isPatch":false,"sender":{"key":"frekui@gmail.com","avatar":"https://avatars.githubusercontent.com/u/13770967?v=4"},"body":"On Thu, Sep 08, 2005 at 12:16:05PM -0500, Darrin Thompson wrote:\n> On Mon, 2005-09-05 at 01:41 -0400, Daniel Barkalow wrote:\n> > I've got a version of read-tree which accepts multiple ancestors and does \n> > a merge using information from all of them.\n> \n> Do the multiple ancestors have to share a common parent? More to the\n> point, is this read-tree any more friendly to baseless merges?\n> \n\nIs a baseless merge a merge with two branches that do not have a\ncommon ancestor? That is, if we want to merge the branches A and B and\ngit-merge-base --all A B do not return any commits, is that a baseless\nmerge?\n\nIf that is the case then my merge code handles baseless merges\nfine. Or, it is _supposed_ to handle them, I have done some basic\ntests but it hasn't been tested thoroughly yet.\n\nI don't know how the new read-tree code handles those cases.\n\n- Fredrik\n"},{"id":"8215","messageId":"Pine.LNX.4.63.0509081727560.23242@iabervon.org","threadId":"1728","inReplyTo":"1126199765.3984.1.camel@localhost.localdomain","subject":"Re: Multi-ancestor read-tree notes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-09-08T21:39:47Z","receivedAt":"2005-09-08T21:39:47Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 8 Sep 2005, Darrin Thompson wrote:\n\n> On Mon, 2005-09-05 at 01:41 -0400, Daniel Barkalow wrote:\n> > I've got a version of read-tree which accepts multiple ancestors and does \n> > a merge using information from all of them.\n> \n> Do the multiple ancestors have to share a common parent? More to the\n> point, is this read-tree any more friendly to baseless merges?\n\nread-tree doesn't care about the relationships between its inputs; it's \nonly interested in the trees. But using ancestors which aren't common is \nunlikely to give you desired results. I think, if you do read-tree a^ b^ a \nb, you will get everything into the index, but it'll all going to be \nconflicts.\n\nI assume that what you want is something to include everything from two \ncommits, which would give conflicts if a name is reused?\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"8216","messageId":"1126216495.3984.4.camel@localhost.localdomain","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509081727560.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Darrin Thompson","fromEmail":"darrint@progeny.com","sentAt":"2005-09-08T21:54:55Z","receivedAt":"2005-09-08T21:54:55Z","isPatch":false,"sender":{"key":"darrint@progeny.com","avatar":null},"body":"On Thu, 2005-09-08 at 17:39 -0400, Daniel Barkalow wrote:\n> I assume that what you want is something to include everything from two \n> commits, which would give conflicts if a name is reused?\n> \n\nYes.\n\n--\nDarrin\n"},{"id":"8217","messageId":"7vy867te3f.fsf@assigned-by-dhcp.cox.net","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509081727560.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-09-08T22:00:04Z","receivedAt":"2005-09-08T22:00:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> I assume that what you want is something to include everything from two \n> commits, which would give conflicts if a name is reused?\n\nMy understanding is that Darrin wants to do what Linus did when\nhe merged gitk into git.git.\n\nPersonally I think that is a specialized application and\nsomething like the git-merge-projects script I posted as a\nfollow-up would be more appropriate than adding it to the\ncurrent merge discussion.\n"},{"id":"8218","messageId":"Pine.LNX.4.63.0509081805280.23242@iabervon.org","threadId":"1728","inReplyTo":"7vy867te3f.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-ancestor read-tree notes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-09-08T22:10:53Z","receivedAt":"2005-09-08T22:10:53Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Thu, 8 Sep 2005, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > I assume that what you want is something to include everything from two \n> > commits, which would give conflicts if a name is reused?\n> \n> My understanding is that Darrin wants to do what Linus did when\n> he merged gitk into git.git.\n> \n> Personally I think that is a specialized application and\n> something like the git-merge-projects script I posted as a\n> follow-up would be more appropriate than adding it to the\n> current merge discussion.\n\nWell, it's an easy addition to read-tree; just need a merge function which \ntakes two entries and adds the non-NULL one in stage 0, or adds both if \nthey both exist. git-merge-script probably shouldn't be the entry point to \nit, of course, but that part isn't my area anyway.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"8242","messageId":"7vy866i1zc.fsf@assigned-by-dhcp.cox.net","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509050049030.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-09-09T17:29:27Z","receivedAt":"2005-09-09T17:29:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> In case #16, I'm not sure what I should produce. I think the best thing \n> might be to not leave anything in stage 1. The desired end effect is that \n> the user is given a file with a section like:\n>\n>   {\n>     *t = NULL;\n>     *m = 0;\n> <<<<<<<<\n>     return Z_DATA_ERROR;\n> ========\n>     return Z_OK;\n>>>>>>>>>\n>   }\n\nI was thinking a bit more about this.  Let's rephrase case #16.\nI'll call merge bases O1, O2,... and merge heads A and B, and we\nare interested in one path.\n\nIf O1 and O2, the path has quite different contents.  A has the\nsame contents as O1 and B has the same contents as O2.  We\nshould not just pick one or the other and do two-file merge\nbetween the version in A and B (we could prototype by massaging\n'diff A B' output to produce what is common between A and B and\nrun (RCS) merge of A and B pretending that the common contents\nis the original to produce something like the above).\n\nIf A has slight changes since O1 but B did not change since O2,\nideally I think we would want the same thing to happen.  Let's\ncall it case #16+.\n\nWhat does the current implementation do?  It is not case #16\nbecause A and O1 does not exactly match.  I suspect the result\nwill be skewed because B has an exact match with O2.  The\nsituation becomes more interesting if both A and B has slight\nchanges since O1 and O2 respectively.  They do not exactly match\nwith their bases, but I think ideally we would like something\nvery similar to case #16 resolution to happen.\n\nOne way to solve this would be to try doing things entirely in\nread-tree by doing not just exact matches but also checking the\namount of changes -- if each heads has similar but different\nbase call it case #16 and try two-file merge between the heads\ndisregarding the bases.\n\nBut I am a bit reluctant to suggest this.  My gut feeling tells\nme that these 'interesting' cases are easier if scripted outside\nread-tree machinery to later enhance and improve the heuristics.\n\nOf course, the current case #16 detected by the exact match rule\nshould be something we can automatically handle, but to make\nthings safer to use I think we should have a way to detect case\n#16+ situlation and avoid mistakenly favoring A over B (or vice\nversa) only because one has slight modification while the other\ndoes not.\n"},{"id":"8245","messageId":"Pine.LNX.4.63.0509091337460.23242@iabervon.org","threadId":"1728","inReplyTo":"7vy866i1zc.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-ancestor read-tree notes","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2005-09-09T20:44:34Z","receivedAt":"2005-09-09T20:44:34Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Fri, 9 Sep 2005, Junio C Hamano wrote:\n\n> Daniel Barkalow <barkalow@iabervon.org> writes:\n> \n> > In case #16, I'm not sure what I should produce. I think the best thing \n> > might be to not leave anything in stage 1. The desired end effect is that \n> > the user is given a file with a section like:\n> >\n> >   {\n> >     *t = NULL;\n> >     *m = 0;\n> > <<<<<<<<\n> >     return Z_DATA_ERROR;\n> > ========\n> >     return Z_OK;\n> >>>>>>>>>\n> >   }\n> \n> I was thinking a bit more about this.  Let's rephrase case #16.\n> I'll call merge bases O1, O2,... and merge heads A and B, and we\n> are interested in one path.\n> \n> If O1 and O2, the path has quite different contents.  A has the\n> same contents as O1 and B has the same contents as O2. \n\nThere's a bit more subtlety here: since these are common ancestors, A must \nhave somehow changed O2's version to O1's version, and B must have changed \nO1's version to O2's version. It's isn't just that each side left the file \nthe same, but from different ancestral versions; both of the other \nversions must have gotten rejected somehow. I think the real key is to \nidentify what was going on in between.\n\n> We should not just pick one or the other and do two-file merge\n> between the version in A and B (we could prototype by massaging\n> 'diff A B' output to produce what is common between A and B and\n> run (RCS) merge of A and B pretending that the common contents\n> is the original to produce something like the above).\n> \n> If A has slight changes since O1 but B did not change since O2,\n> ideally I think we would want the same thing to happen.  Let's\n> call it case #16+.\n> \n> What does the current implementation do?  It is not case #16\n> because A and O1 does not exactly match.  I suspect the result\n> will be skewed because B has an exact match with O2. \n\nYes, in this case we miss whatever caused A to reject O2, and we use the \nmodified O2, because we don't realize that A's rejection of O2 should also \napply to the version in B. Unfortunately, this looks just like the \nsituation where both sides took O1, and B did a further modification to \nthat.\n\n> The situation becomes more interesting if both A and B has slight\n> changes since O1 and O2 respectively.  They do not exactly match\n> with their bases, but I think ideally we would like something\n> very similar to case #16 resolution to happen.\n\nI think the right thing, ideally, is to have the content merge also take \nmultiple ancestors and have a #16 case itself when it's deciding which \nversion of a block to use. The #16+ case is actually trickier, because we \nhave fewer cues.\n\n> One way to solve this would be to try doing things entirely in\n> read-tree by doing not just exact matches but also checking the\n> amount of changes -- if each heads has similar but different\n> base call it case #16 and try two-file merge between the heads\n> disregarding the bases.\n> \n> But I am a bit reluctant to suggest this.  My gut feeling tells\n> me that these 'interesting' cases are easier if scripted outside\n> read-tree machinery to later enhance and improve the heuristics.\n> \n> Of course, the current case #16 detected by the exact match rule\n> should be something we can automatically handle, but to make\n> things safer to use I think we should have a way to detect case\n> #16+ situlation and avoid mistakenly favoring A over B (or vice\n> versa) only because one has slight modification while the other\n> does not.\n\nI think #16+ is extra uncommon, because it involves someone making an \nirrelevant modification to a patched version of a file while someone else \nreverts the patch. I'm actually interested in doing a big spiffy program \nto do merges with information drawn as needed from the history, stuff \nhappening on a per-hunk level, and support for block moves. It'll take a \nwhile before it gets anywhere, but I still think it's likely that people \nwon't hit #16+ and get unexpected behavior before it's ready.\n\nThe main thing I'm unsure of is whether Fredrick's algorithm is actually \nnot a better solution: it is possible to understand what happened leading \nup to a merge either by looking at the time after the common ancestors or \nby looking at the time before them. I think that the more recent history \nis a better guide, but the older history is easier to use; the case his \nversion isn't good for, I think, is when the common ancestors of the sides \nare even more complicated to merge.\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"8260","messageId":"7virx87d2b.fsf@assigned-by-dhcp.cox.net","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509061228090.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-09-10T22:50:04Z","receivedAt":"2005-09-10T22:50:04Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> Do you know if there's anything like case #16 in there? I'd be interested \n> to know if there's anything that gets handled automatically in different \n> ways depending on which single base is used, and doesn't require manual \n> intervention with multiple bases, because that's probably wrong.\n\nI was playing with a handful of non-Linus 2.6 kernel\nrepositories today, and found two case #16 merges.\n\n0c3e091838f02c537ccab3b6e8180091080f7df2\n\n\tcase #16; stupid resolves the same way as the actual\n\tcommit, but that might mean the actual commit is bad.\n\n84ffa747520edd4556b136bdfc9df9eb1673ce12\n\n\tcase #16; stupid also fails.\n\n0c168775709faa74c1b87f1e61046e0c51ade7f3\n0e396ee43e445cb7c215a98da4e76d0ce354d9d7\n\n\tThese two fails both in stupid and resolve.\n\na855f9a4d29f0ec338c337358844389171b0bae0\n\n\tThis one stupid fails but resolve succeeds.\n\n19925d7e0af7de645d808fd973ef99049fce52f0\n3190186362466658f01b2e354e639378ce07e1a9\n467ca22d3371f132ee225a5591a1ed0cd518cb3d\n539aeb871b52233b189ae976dfded20e14db645a\n6358924b06cd1aaa031b8ba0c33e5a15e795bef0\ncf70be167c085af820c0c2a606cab8c3ee819dc6\nda28c12089dfcfb8695b6b555cdb8e03dda2b690\n\n\tThese give good merges in both stupid and resolve.\n\nHere are the logs for the commits involved in the above\nexperiments; some of them might be contained in only one\nmaintainer tree but I do not keep track of whose tree they came\nfrom.  The repository I am testing in is `fetch but not merge\nmany random trees derived from Linus linux-2.6' repository.\n\n----------------------------------------------------------------\ncommit 0c168775709faa74c1b87f1e61046e0c51ade7f3\ntree c40fd8818c64c5d7d1d90afab0bd6ffd94505526\nparent 9bd481f85940726bf66aae5cd03c5b912ad0ae4c\nparent 9b4311eedb17fa88f02e4876cd6aa9a08e383cd6\nauthor Jeff Garzik <jgarzik@pobox.com> 1120106958 -0400\ncommitter Jeff Garzik <jgarzik@pobox.com> 1120106958 -0400\n\n    Merge upstream 2.6.13-rc1-git1 into 'ieee80211' branch of netdev-2.6.\n\ncommit 0c3e091838f02c537ccab3b6e8180091080f7df2\ntree 61a407356d1e897e0badea552ce69e657cab6108\nparent 7ffacc1a2527c219b834fe226a7a55dc67ca3637\nparent a4cce10492358b33d33bb43f98284c80482037e8\nauthor Tony Luck <tony.luck@intel.com> 1124808655 -0700\ncommitter Tony Luck <tony.luck@intel.com> 1124808655 -0700\n\n    Pull release into test branch\n\ncommit 0e396ee43e445cb7c215a98da4e76d0ce354d9d7\ntree a6fde6a33965abb6077420cda31e3f1fbe8d3891\nparent b8112df71cae7d6a86158caeb19d215f56c4f9ab\nparent 2089a0d38bc9c2cdd084207ebf7082b18cf4bf58\nauthor Linus Torvalds <torvalds@ppc970.osdl.org> 1119120155 -0700\ncommitter Linus Torvalds <torvalds@ppc970.osdl.org> 1119120155 -0700\n\n    Manual merge of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git\n    \n    This is a fixed-up version of the broken \"upstream-2.6.13\" branch, where\n    I re-did the manual merge of drivers/net/r8169.c by hand, and made sure\n    the history is all good.\n\ncommit 19925d7e0af7de645d808fd973ef99049fce52f0\ntree 01e7bf7717582bd70fbf1ba86132c33e61d044d5\nparent cce3217e147b46ec4b7d20d922dadd3016b5fd49\nparent 85f265d887d2389376f1caa191e9682085feb76e\nauthor Tony Luck <tony.luck@intel.com> 1124143503 -0700\ncommitter Tony Luck <tony.luck@intel.com> 1124143503 -0700\n\n    Pull CONFIG_PCI description fix\n\ncommit 3190186362466658f01b2e354e639378ce07e1a9\ntree 4ef50e96c385ed076465aac23f52902467e7d825\nparent 08848e446bcd2130c26945be966446389d25bcc2\nparent f60f700876cd51de9de69f3a3c865d95e287a24d\nauthor Tony Luck <tony.luck@intel.com> 1121628606 -0700\ncommitter Tony Luck <tony.luck@intel.com> 1121628606 -0700\n\n    Auto merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git\n\ncommit 467ca22d3371f132ee225a5591a1ed0cd518cb3d\ntree 0e3d6de84b4ffa379c2c7ddcebd3f55de52b9844\nparent 12725675e26d52c39e856d341035b94bf7802458\nparent 1e86d1c648508fd50e6c9960576b87906a7906ad\nauthor Steve French <sfrench@hera.kernel.org> 1117748543 -0700\ncommitter Steve French <sfrench@hera.kernel.org> 1117748543 -0700\n\n    Merge with rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git\n    \n\ncommit 539aeb871b52233b189ae976dfded20e14db645a\ntree ad028270f2b79d74886418014f971d52cb729e11\nparent 04141b215a2a0ba7c2052b53a912c9412f2ed8ea\nparent 30d5b64b63fa69af31b2cba32e6d71d68526eec9\nauthor Tony Luck <tony.luck@intel.com> 1124407778 -0700\ncommitter Tony Luck <tony.luck@intel.com> 1124407778 -0700\n\n    Auto-update from upstream\n\ncommit 6358924b06cd1aaa031b8ba0c33e5a15e795bef0\ntree 9cc45ad48ba1c1171ceb949294223839c89d1f8c\nparent 1da21e73bdc458f8131e6071072632b4c3b0430f\nparent 344a076110f4ecb16ea6d286b63be696604982ed\nauthor Tony Luck <tony.luck@intel.com> 1126214972 -0700\ncommitter Tony Luck <tony.luck@intel.com> 1126214972 -0700\n\n    Pull release into test branch\n\ncommit 84ffa747520edd4556b136bdfc9df9eb1673ce12\ntree 1cfe20bd31fce1b5b3024384fcb324c3338d1d32\nparent 702c7e7626deeabb057b6f529167b65ec2eefbdb\nparent 81065e2f415af6c028eac13f481fb9e60a0b487b\nauthor Len Brown <len.brown@intel.com> 1124849543 -0400\ncommitter Len Brown <len.brown@intel.com> 1124849543 -0400\n\n    Merge from-linus to-akpm\n\ncommit a855f9a4d29f0ec338c337358844389171b0bae0\ntree 211824376a8b170a8087956c8d5ec25269f2bc49\nparent 04c573e1d1625b48b3c90f988579d7835f4c55f3\nparent f505380ba7b98ec97bf25300c2a58aeae903530b\nauthor Tony Luck <tony.luck@intel.com> 1125729479 -0700\ncommitter Tony Luck <tony.luck@intel.com> 1125729479 -0700\n\n    Update from linus with manual merge for include/asm-ia64/sn/sn_sal.h\n\ncommit cf70be167c085af820c0c2a606cab8c3ee819dc6\ntree 0a587cec3a6bd4fdd53fcfb75f87bc45da5d1a7f\nparent 3844dcf8faae3a163ca2d263ba6468085ffaceb8\nparent ff67b59726a8cd3549b069dfa78de2f538d3b8e3\nauthor Tony Luck <tony.luck@intel.com> 1125439229 -0700\ncommitter Tony Luck <tony.luck@intel.com> 1125439229 -0700\n\n    Pull release into test branch\n\ncommit da28c12089dfcfb8695b6b555cdb8e03dda2b690\ntree b3ff509f21352ef053cb3d490cb13528090d32ac\nparent 6de7dc2c4c713d037c19aa1e310d240f16973414\nparent 577a4f8102d54b504cb22eb021b89e957e8df18f\nauthor Dave Kleikamp <shaggy@austin.ibm.com> 1122559416 -0500\ncommitter Dave Kleikamp <shaggy@austin.ibm.com> 1122559416 -0500\n\n    Merge with /home/shaggy/git/linus-clean/\n    /home/shaggy/git/linus-clean/\n    /home/shaggy/git/linus-clean/\n    \n    Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>\n"},{"id":"8261","messageId":"7vacik7crj.fsf@assigned-by-dhcp.cox.net","threadId":"1728","inReplyTo":"7virx87d2b.fsf@assigned-by-dhcp.cox.net","subject":"Re: Multi-ancestor read-tree notes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-09-10T22:56:32Z","receivedAt":"2005-09-10T22:56:32Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"While I was doing merge experiments, I found two commits whose\nparents are actually fast forwards.  This does not mean you made\nmistakes when you made these commits, but it suggests that the\ntool that made these commits may have screwed up.  Do you use\n'git commit' to make your commits, or do you use something else?\n\n\ncommit b129a8ccd53f74c43e4c83c8e0031a4990040830\nMerge: 6b39374a27eb4be7e9d82145ae270ba02ea90dc8 194d0710e1a7fe92dcf860ddd31fded8c3103b7a\nAuthor: Russell King <rmk@dyn-67.arm.linux.org.uk>\nDate:   Wed Aug 31 10:12:14 2005 +0100\n\n    [SERIAL] Clean up and fix tty transmission start/stoping\n    \n    The start_tx and stop_tx methods were passed a flag to indicate\n    whether the start/stop was from the tty start/stop callbacks, and\n    some drivers used this flag to decide whether to ask the UART to\n    immediately stop transmission (where the UART supports such a\n    feature.)\n    \n    There are other cases when we wish this to occur - when CTS is\n    lowered, or if we change from soft to hard flow control and CTS\n    is inactive.  In these cases, this flag was false, and we would\n    allow the transmitter to drain before stopping.\n    \n    There is really only one case where we want to let the transmitter\n    drain before disabling, and that's when we run out of characters\n    to send.\n    \n    Hence, re-jig the start_tx and stop_tx methods to eliminate this\n    flag, and introduce new functions for the special \"disable and\n    allow transmitter to drain\" case.\n    \n    Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>\n\ncommit 603fff54420a0ccc4c3b48bfef43896fb4e33161\nMerge: 99f95e5286df2f69edab8a04c7080d986ee4233b 8b22c249e7de453961e4d253b19fc2a0bdd65d53\nAuthor: Russell King <rmk@dyn-67.arm.linux.org.uk>\nDate:   Tue Jun 28 13:40:39 2005 +0100\n\n    [PATCH] ARM SMP: TLB implementations only affect local CPU\n    \n    The existing TLB flush implementations only have an effect on\n    the local CPU.  Prefix them with local_.\n    \n    Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>\n"},{"id":"8295","messageId":"pan.2005.09.11.16.45.08.244699@smurf.noris.de","threadId":"1728","inReplyTo":"Pine.LNX.4.63.0509091337460.23242@iabervon.org","subject":"Re: Multi-ancestor read-tree notes","fromName":"Matthias Urlichs","fromEmail":"smurf@smurf.noris.de","sentAt":"2005-09-11T16:45:10Z","receivedAt":"2005-09-11T16:45:10Z","isPatch":false,"sender":{"key":"matthias@urlichs.de","avatar":"https://gravatar.com/avatar/2708905af227313eba6f2b2ae0f7d0259b5ac5d71baef58fe5a13c699ce0bbf0?d=mp&s=160"},"body":"Hi, Daniel Barkalow wrote:\n\n>  I'm actually interested in doing a big spiffy program \n> to do merges with information drawn as needed from the history, stuff \n> happening on a per-hunk level, and support for block moves.\n\nYou should look at \"meld\", which is a nice Python program to do\ngraphical merges.\n\nIn addition to that, I've written a Python interface for direct\n(read-only) access to git objects, so you can do more interesting\nthings without forking off a lot of programs. Expect that work to appear\nhere shortly.\n\n-- \nMatthias Urlichs   |   {M:U} IT Design @ m-u-it.de   |  smurf@smurf.noris.de\nDisclaimer: The quote was selected randomly. Really. | http://smurf.noris.de\n - -\n\"The majority of the stupid is invincible and guaranteed for all time. The\nterror of their tyranny, however, is alleviated by their lack of consistency.\"\n-- Albert Einstein\n"}]}