{"thread":{"id":"27732","subject":"linux-next: manual merge of the security-testing tree with the tree","startedAt":"2011-06-30T04:29:10Z","lastAt":"2011-06-30T19:13:39Z","messageCount":11,"participants":["Stephen Rothwell","James Morris","Uwe Kleine-König","Linus Torvalds","Junio C Hamano","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"170691","messageId":"20110630142910.2fea4257.sfr@canb.auug.org.au","threadId":"27732","inReplyTo":null,"subject":"linux-next: manual merge of the security-testing tree with the tree","fromName":"Stephen Rothwell","fromEmail":"sfr@canb.auug.org.au","sentAt":"2011-06-30T04:29:10Z","receivedAt":"2011-06-30T04:29:10Z","isPatch":false,"sender":{"key":"sfr@canb.auug.org.au","avatar":null},"body":"Hi James,\n\nToday's linux-next merge of the security-testing tree produced a large\nnumber of conflicts in files not modified by the security-testing tree.\nI assume that this is a bug in \"git merge\" but I cannot complete the\nmerge as such.\n\nI have used the security-testing tree from next-20110628 for today.\n\nMore information for the git experts:\n\nThe security-testing tree is at\ngit://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git\nand I am trying to merge branch \"next\" into linux-next at commit\n9fd8fab5e299a (\"Merge remote-tracking branch 'voltage/for-next'\").\n\nI can merge commit 0e4ae0e0dec6 (\"TOMOYO: Make several options\nconfigurable\") from the security testing tree without conflict and also\ncommit 25e75dff519b (\"AppArmor: Fix masking of capabilities in complain\nmode\").\n\nI cannot merge commit bcd05ca10420 (\"Merge branch 'for-security' of\ngit://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev into next\")\nwhich is the child of the above two commits.\n\nThe tree to commit 25e75dff519b only containes two simple commits\n(modifying 2 files) and is based on v3.0-rc5.  The tree to commit\nbcd05ca10420 containes several commits and is based on commit\n06e86849cf40 (\"Merge branch 'pm-fixes' of\ngit://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6\") from\nLinus' tree (between v3.0-rc2 and v3.0-rc2).\n\nAfter attempting the merge I get this:\n\n$ git status\n# On branch master\n# Changes to be committed:\n#\n#\tdeleted:    Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870\n#\tmodified:   Documentation/accounting/cgroupstats.txt\n#\tmodified:   Documentation/cgroups/blkio-controller.txt\n#\tmodified:   Documentation/cgroups/cgroups.txt\n#\tmodified:   Documentation/cgroups/cpuacct.txt\n#\tmodified:   Documentation/cgroups/cpusets.txt\n\t.\n\t.\t[lots elided]\n\t.\n#\tmodified:   tools/perf/util/PERF-VERSION-GEN\n#\tmodified:   tools/perf/util/trace-event-parse.c\n#\n# Unmerged paths:\n#   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n#\n#\tboth modified:      arch/arm/mach-shmobile/board-ag5evm.c\n#\tboth modified:      arch/arm/mm/context.c\n#\tboth modified:      arch/arm/mm/proc-v7.S\n#\tboth modified:      arch/arm/plat-mxc/devices/platform-imx-dma.c\n#\tboth modified:      arch/arm/plat-s5p/include/plat/map-s5p.h\n#\tboth modified:      arch/m68k/Kconfig.nommu\n#\tboth modified:      block/blk-throttle.c\n#\tboth modified:      drivers/gpu/drm/nouveau/nouveau_fence.c\n#\tdeleted by them:    drivers/net/usb/kalmia.c\n#\tboth modified:      drivers/net/wireless/iwlegacy/iwl-dev.h\n#\tboth modified:      drivers/net/wireless/iwlegacy/iwl4965-base.c\n#\tboth modified:      drivers/net/wireless/iwlwifi/iwl-agn-rxon.c\n#\tboth modified:      drivers/net/wireless/iwlwifi/iwl-agn.c\n#\tboth modified:      drivers/net/wireless/rtlwifi/pci.c\n#\tdeleted by them:    drivers/video/backlight/adp8870_bl.c\n#\tboth modified:      fs/namei.c\n#\tboth modified:      fs/nfs/nfs4proc.c\n#\tboth modified:      fs/nfs/pnfs.c\n#\tboth modified:      fs/proc/base.c\n#\tboth modified:      net/bluetooth/rfcomm/sock.c\n#\tboth modified:      net/ipv4/ip_output.c\n#\tboth modified:      net/netfilter/ipvs/ip_vs_core.c\n#\tboth modified:      sound/pci/hda/patch_via.c\n#\tboth modified:      sound/soc/codecs/ad1836.h\n#\tboth modified:      sound/soc/soc-cache.c\n#\n\nNone of the \"Unmerged paths\" are modified in the tree I am merging in.\n\nThe linux-next tree will be published later today and James' tree is\navailable already (I can publis my copy of it if James modifies his).\n\n-- \nCheers,\nStephen Rothwell                    sfr@canb.auug.org.au\nhttp://www.canb.auug.org.au/~sfr/\n"},{"id":"170692","messageId":"20110630143334.90c9d1bc.sfr@canb.auug.org.au","threadId":"27732","inReplyTo":"20110630142910.2fea4257.sfr@canb.auug.org.au","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Stephen Rothwell","fromEmail":"sfr@canb.auug.org.au","sentAt":"2011-06-30T04:33:34Z","receivedAt":"2011-06-30T04:33:34Z","isPatch":false,"sender":{"key":"sfr@canb.auug.org.au","avatar":null},"body":"On Thu, 30 Jun 2011 14:29:10 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:\n>\n> More information for the git experts:\n> \n\n$ git version\ngit version 1.7.5.4\n\nI am running Debian unstable.\n-- \nCheers,\nStephen Rothwell                    sfr@canb.auug.org.au\nhttp://www.canb.auug.org.au/~sfr/\n"},{"id":"170694","messageId":"20110630143915.0b0fdf0f.sfr@canb.auug.org.au","threadId":"27732","inReplyTo":"20110630143334.90c9d1bc.sfr@canb.auug.org.au","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Stephen Rothwell","fromEmail":"sfr@canb.auug.org.au","sentAt":"2011-06-30T04:39:15Z","receivedAt":"2011-06-30T04:39:15Z","isPatch":false,"sender":{"key":"sfr@canb.auug.org.au","avatar":null},"body":"On Thu, 30 Jun 2011 14:33:34 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:\n>\n> On Thu, 30 Jun 2011 14:29:10 +1000 Stephen Rothwell <sfr@canb.auug.org.au> wrote:\n> >\n> > More information for the git experts:\n> > \n> \n> $ git version\n> git version 1.7.5.4\n> \n> I am running Debian unstable.\n\nToday's linux-next is based on v3.0-rc5-76-gc017d0d (Linus' tree commit\nc017d0d135 (\"Merge branch 'kvm-updates/3.0' of\ngit://git.kernel.org/pub/scm/virt/kvm/kvm\").\n\nThe point at which I tried to merge the security-testing tree is\nv3.0-rc5-3666-g9fd8fab.\n\n-- \nCheers,\nStephen Rothwell                    sfr@canb.auug.org.au\nhttp://www.canb.auug.org.au/~sfr/\n"},{"id":"170697","messageId":"alpine.LRH.2.00.1106301518430.13767@tundra.namei.org","threadId":"27732","inReplyTo":"20110630142910.2fea4257.sfr@canb.auug.org.au","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"James Morris","fromEmail":"jmorris@namei.org","sentAt":"2011-06-30T05:22:33Z","receivedAt":"2011-06-30T05:22:33Z","isPatch":false,"sender":{"key":"jmorris@namei.org","avatar":null},"body":"On Thu, 30 Jun 2011, Stephen Rothwell wrote:\n\n> I cannot merge commit bcd05ca10420 (\"Merge branch 'for-security' of\n> git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev into next\")\n> which is the child of the above two commits.\n\nActually, I may have accidentally pulled upstream commits in via the \nabove.  I'll rebase my tree to the TOMOYO merge.\n\n\n- James\n-- \nJames Morris\n<jmorris@namei.org>\n"},{"id":"170698","messageId":"20110630155354.bdd620b5.sfr@canb.auug.org.au","threadId":"27732","inReplyTo":"alpine.LRH.2.00.1106301518430.13767@tundra.namei.org","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Stephen Rothwell","fromEmail":"sfr@canb.auug.org.au","sentAt":"2011-06-30T05:53:54Z","receivedAt":"2011-06-30T05:53:54Z","isPatch":false,"sender":{"key":"sfr@canb.auug.org.au","avatar":null},"body":"Hi James,\n\nOn Thu, 30 Jun 2011 15:22:33 +1000 (EST) James Morris <jmorris@namei.org> wrote:\n>\n> On Thu, 30 Jun 2011, Stephen Rothwell wrote:\n> \n> > I cannot merge commit bcd05ca10420 (\"Merge branch 'for-security' of\n> > git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev into next\")\n> > which is the child of the above two commits.\n> \n> Actually, I may have accidentally pulled upstream commits in via the \n> above.  I'll rebase my tree to the TOMOYO merge.\n\nIt does pull in v3.0-rc5, but that is already in my tree today, so I\nstill don't understand why the merge I did gets so messaed up.\n\n-- \nCheers,\nStephen Rothwell                    sfr@canb.auug.org.au\nhttp://www.canb.auug.org.au/~sfr/\n"},{"id":"170700","messageId":"20110630072559.GA4048@pengutronix.de","threadId":"27732","inReplyTo":"20110630142910.2fea4257.sfr@canb.auug.org.au","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Uwe Kleine-König","fromEmail":"u.kleine-koenig@pengutronix.de","sentAt":"2011-06-30T07:25:59Z","receivedAt":"2011-06-30T07:25:59Z","isPatch":false,"sender":{"key":"u.kleine-koenig@pengutronix.de","avatar":"https://gravatar.com/avatar/354b5e3ceb2806a2f1e1e382ac29ddbdad18288654da62b61eb13583a857eee7?d=mp&s=160"},"body":"On Thu, Jun 30, 2011 at 02:29:10PM +1000, Stephen Rothwell wrote:\n> Hi James,\n> \n> Today's linux-next merge of the security-testing tree produced a large\n> number of conflicts in files not modified by the security-testing tree.\n> I assume that this is a bug in \"git merge\" but I cannot complete the\n> merge as such.\n> \n> I have used the security-testing tree from next-20110628 for today.\n> \n> More information for the git experts:\n> \n> The security-testing tree is at\n> git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git\n> and I am trying to merge branch \"next\" into linux-next at commit\n> 9fd8fab5e299a (\"Merge remote-tracking branch 'voltage/for-next'\").\n> \n> I can merge commit 0e4ae0e0dec6 (\"TOMOYO: Make several options\n> configurable\") from the security testing tree without conflict and also\n> commit 25e75dff519b (\"AppArmor: Fix masking of capabilities in complain\n> mode\").\n> \n> I cannot merge commit bcd05ca10420 (\"Merge branch 'for-security' of\n> git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev into next\")\n> which is the child of the above two commits.\n> \n> The tree to commit 25e75dff519b only containes two simple commits\n> (modifying 2 files) and is based on v3.0-rc5.  The tree to commit\n> bcd05ca10420 containes several commits and is based on commit\n> 06e86849cf40 (\"Merge branch 'pm-fixes' of\n> git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6\") from\n> Linus' tree (between v3.0-rc2 and v3.0-rc2).\n> \n> After attempting the merge I get this:\n> \n> $ git status\n> # On branch master\n> # Changes to be committed:\n> #\n> #\tdeleted:    Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870\n> #\tmodified:   Documentation/accounting/cgroupstats.txt\n> #\tmodified:   Documentation/cgroups/blkio-controller.txt\n> #\tmodified:   Documentation/cgroups/cgroups.txt\n> #\tmodified:   Documentation/cgroups/cpuacct.txt\n> #\tmodified:   Documentation/cgroups/cpusets.txt\n> \t.\n> \t.\t[lots elided]\n> \t.\n> #\tmodified:   tools/perf/util/PERF-VERSION-GEN\n> #\tmodified:   tools/perf/util/trace-event-parse.c\n> #\n> # Unmerged paths:\n> #   (use \"git add/rm <file>...\" as appropriate to mark resolution)\n> #\n> #\tboth modified:      arch/arm/mach-shmobile/board-ag5evm.c\n> #\tboth modified:      arch/arm/mm/context.c\n> #\tboth modified:      arch/arm/mm/proc-v7.S\n> #\tboth modified:      arch/arm/plat-mxc/devices/platform-imx-dma.c\n> #\tboth modified:      arch/arm/plat-s5p/include/plat/map-s5p.h\n> #\tboth modified:      arch/m68k/Kconfig.nommu\n> #\tboth modified:      block/blk-throttle.c\n> #\tboth modified:      drivers/gpu/drm/nouveau/nouveau_fence.c\n> #\tdeleted by them:    drivers/net/usb/kalmia.c\n> #\tboth modified:      drivers/net/wireless/iwlegacy/iwl-dev.h\n> #\tboth modified:      drivers/net/wireless/iwlegacy/iwl4965-base.c\n> #\tboth modified:      drivers/net/wireless/iwlwifi/iwl-agn-rxon.c\n> #\tboth modified:      drivers/net/wireless/iwlwifi/iwl-agn.c\n> #\tboth modified:      drivers/net/wireless/rtlwifi/pci.c\n> #\tdeleted by them:    drivers/video/backlight/adp8870_bl.c\n> #\tboth modified:      fs/namei.c\n> #\tboth modified:      fs/nfs/nfs4proc.c\n> #\tboth modified:      fs/nfs/pnfs.c\n> #\tboth modified:      fs/proc/base.c\n> #\tboth modified:      net/bluetooth/rfcomm/sock.c\n> #\tboth modified:      net/ipv4/ip_output.c\n> #\tboth modified:      net/netfilter/ipvs/ip_vs_core.c\n> #\tboth modified:      sound/pci/hda/patch_via.c\n> #\tboth modified:      sound/soc/codecs/ad1836.h\n> #\tboth modified:      sound/soc/soc-cache.c\n> #\n> \n> None of the \"Unmerged paths\" are modified in the tree I am merging in.\nHmm, looking at bcd05ca10420 and the difference to its first parent:\n\n\t$ git diff --stat bcd05ca10420^ bcd05ca10420\n\t<void>\n\n\t$ git describe bcd05ca10420\n\tv3.0-rc5-28-gbcd05ca\n\n\t$ git describe bcd05ca10420^\n\tv3.0-rc2-221-g0e4ae0e\n\nSo commit bcd05ca10420 reverted many commits between v3.0-rc2 and v3.0-rc5.\n\nIf I redo what should have been done in bcd05ca10420 and compare with\nbcd05ca10420:\n\n\tgit checkout bcd05ca10420^\n\tgit merge bcd05ca10420^2\n\tgit diff --stat bcd05ca10420\n\nI get the same list of touched files as you above.\n\nLong history short: James probably used -s ours or similar and it's fine\nnot to merge that commit into next :-)\n\nBest regards\nUwe\n\n-- \nPengutronix e.K.                           | Uwe Kleine-König            |\nIndustrial Linux Solutions                 | http://www.pengutronix.de/  |\n"},{"id":"170703","messageId":"20110630193023.6056d48e.sfr@canb.auug.org.au","threadId":"27732","inReplyTo":"20110630072559.GA4048@pengutronix.de","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Stephen Rothwell","fromEmail":"sfr@canb.auug.org.au","sentAt":"2011-06-30T09:30:23Z","receivedAt":"2011-06-30T09:30:23Z","isPatch":false,"sender":{"key":"sfr@canb.auug.org.au","avatar":null},"body":"Hi Uwe,\n\nOn Thu, 30 Jun 2011 09:25:59 +0200 Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:\n>\n> Long history short: James probably used -s ours or similar and it's fine\n> not to merge that commit into next :-)\n\nAh ha!  Thanks for the explanation.  My mind was clearly not up to it\ntoday. :-)\n\n-- \nCheers,\nStephen Rothwell                    sfr@canb.auug.org.au\nhttp://www.canb.auug.org.au/~sfr/\n"},{"id":"170708","messageId":"20110630121710.GJ11559@pengutronix.de","threadId":"27732","inReplyTo":"20110630193023.6056d48e.sfr@canb.auug.org.au","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Uwe Kleine-König","fromEmail":"u.kleine-koenig@pengutronix.de","sentAt":"2011-06-30T12:17:10Z","receivedAt":"2011-06-30T12:17:10Z","isPatch":false,"sender":{"key":"u.kleine-koenig@pengutronix.de","avatar":"https://gravatar.com/avatar/354b5e3ceb2806a2f1e1e382ac29ddbdad18288654da62b61eb13583a857eee7?d=mp&s=160"},"body":"On Thu, Jun 30, 2011 at 07:30:23PM +1000, Stephen Rothwell wrote:\n> Hi Uwe,\n> \n> On Thu, 30 Jun 2011 09:25:59 +0200 Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote:\n> >\n> > Long history short: James probably used -s ours or similar and it's fine\n> > not to merge that commit into next :-)\n> \n> Ah ha!  Thanks for the explanation.  My mind was clearly not up to it\n> today. :-)\nThe uncomfortable issue here is that \n\n\tgit show bcd05ca10420\n\n(or gitk or gitweb or <enteryourfavoritetoolhere>) doesn't indicate that\nit's \"strange\". The patch shown is simply empty, as it would be if the\ntree matched the other parent or if it were a clean merge.\n\nA flag would be nice that does what I did: redo the merge and compare\nbcd05ca10420^{tree} with the result?\n\nBest regards\nUwe\n\n-- \nPengutronix e.K.                           | Uwe Kleine-König            |\nIndustrial Linux Solutions                 | http://www.pengutronix.de/  |\n"},{"id":"170712","messageId":"BANLkTi=usrsF60Popfu55v3_dXe7Yo0GrA@mail.gmail.com","threadId":"27732","inReplyTo":"20110630121710.GJ11559@pengutronix.de","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2011-06-30T16:20:35Z","receivedAt":"2011-06-30T16:20:35Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"2011/6/30 Uwe Kleine-König <u.kleine-koenig@pengutronix.de>:\n>\n> A flag would be nice that does what I did: redo the merge and compare\n> bcd05ca10420^{tree} with the result?\n\nThe problem with that is that it's *way* too expensive an operation to\ndo for the normal \"git log\" kind of operations.\n\nAlso, truly re-doing the merge actually requires workspace access\nand/or require new objects to be created, so it would be inappropriate\nanyway: git log/show absolutely has to be a read-only operation,\nanything else would be totally insane.\n\nSo there's no way - both for performance and 'fundamental' reasons -\nto make the normal logging code truly re-do the merge and then compare\nthe end result of the merge with the end result that is in the tree.\n\nThat said, what the current \"git show/log\" does is to just compare the\nend points with the merge result, which means that if the end result\nmatches either of the end-points, nothing will be shown. That works\nfor the common cases, but it absolutely doesn't work if somebody does\nsomething crazy, and just picks one end-point over another without\ndoing a proper merge (ie \"-s ours\" or just a mis-merge). But the\nreason it's done that way is that it's possible to do without re-doing\nthe merge.\n\nIt would be lovely if \"git show\" (and log operations) had some option\nto do a \"expensive merge check\" and did actually figure out the common\nancestor and at least took that into account.\n\nIt would be doable to do it at least better than we do now - the\ncommon ancestor is not cheap to compute, but it's much cheaper than a\nfull merge, and would at least allow us to flag dangerous merges. Of\ncourse, it gets fun when there are multiple common ancestors and\nrenames. It's entirely possible that it's never going to be practical\nto do anything but \"re-do the merge and compare result\".\n\n                      Linus\n"},{"id":"170722","messageId":"7v4o37qhi6.fsf@alter.siamese.dyndns.org","threadId":"27732","inReplyTo":"BANLkTi=usrsF60Popfu55v3_dXe7Yo0GrA@mail.gmail.com","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-06-30T18:52:17Z","receivedAt":"2011-06-30T18:52:17Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> It would be lovely if \"git show\" (and log operations) had some option\n> to do a \"expensive merge check\" and did actually figure out the common\n> ancestor and at least took that into account.\n>\n> It would be doable to do it at least better than we do now - the\n> common ancestor is not cheap to compute, but it's much cheaper than a\n> full merge, and would at least allow us to flag dangerous merges. Of\n> course, it gets fun when there are multiple common ancestors and\n> renames. It's entirely possible that it's never going to be practical\n> to do anything but \"re-do the merge and compare result\".\n\nI would have to say that it would boil down to \"re-do the merge\" whichever\nway we implement it, and it is not necessarily a bad thing.  \n\nThere are ideas to implement a mode of \"git merge\" that works entirely\nin-core without touching the working tree (it may have to write temporary\nblobs and possibly trees to the object store, though). It would let sites\nlike github to let its users accept a trivial pull request that can merge\ncleanly on site in the browser without necessarily having to have a local\ncheckout used for conflict resolution.\n\nIf such an \"in-core merge\" feature is implemented cleanly in a reusable\nway, it would be just the matter of comparing the output from it with the\nactual committed result.\n\nOf course, if the committed result was deliberately made by \"-s ours\",\ncomparison between an auto-merge result and the committed result would\nproduce a lot of noise, but that is really the point of \"expensie merge\ncheck\", so the noise in that scenario is a feature, not a bug.\n"},{"id":"170725","messageId":"20110630191339.GA9176@sigill.intra.peff.net","threadId":"27732","inReplyTo":"7v4o37qhi6.fsf@alter.siamese.dyndns.org","subject":"Re: linux-next: manual merge of the security-testing tree with the tree","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2011-06-30T19:13:39Z","receivedAt":"2011-06-30T19:13:39Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 30, 2011 at 11:52:17AM -0700, Junio C Hamano wrote:\n\n> I would have to say that it would boil down to \"re-do the merge\" whichever\n> way we implement it, and it is not necessarily a bad thing.  \n> \n> There are ideas to implement a mode of \"git merge\" that works entirely\n> in-core without touching the working tree (it may have to write temporary\n> blobs and possibly trees to the object store, though). It would let sites\n> like github to let its users accept a trivial pull request that can merge\n> cleanly on site in the browser without necessarily having to have a local\n> checkout used for conflict resolution.\n> \n> If such an \"in-core merge\" feature is implemented cleanly in a reusable\n> way, it would be just the matter of comparing the output from it with the\n> actual committed result.\n\nBelow is my unpolished, probably-buggy-as-hell patch to do the in-core\ncontent merge.  But there are still two sticking points:\n\n  1. This is a dirt-simple 3-way content merge. The actual merge would\n     likely have used some more complex strategy. So you're going to see\n     discrepancies between a real merge, even a correct one, and what\n     this produces (e.g., in the face of renames detected by\n     merge-recursive).\n\n  2. This just makes read-tree do the content merge where it doesn't\n     conflict, and leaves the conflicted cases unmerged in the index.\n     Which is of course the only sane thing to put in the index.\n\n     But what do you want to do about comparing entries with conflicts,\n     which are the really interesting bits?  Compare the result to the\n     version of the file with conflict markers? If so, where do you want\n     to store the file with conflict markers?  I guess we could generate\n     an in-core index with the conflict markers that we are just going\n     to throw away. That seems pretty hack-ish.\n\n-Peff\n\n-- >8 --\nSubject: [PATCH] teach read-tree to do content-level merges\n\nRead-tree will resolve simple 3-way merges, such as a path\ntouched on one branch but not on the other. With\n--aggressive, it will also do some more complex merges, like\nboth sides adding the same content. But it always stops\nshort of actually merging content, leaving the unmerged\npaths in the index.\n\nOne can always use \"git merge-index git-merge-one-file -a\"\nto do a content-level merge of these paths. However, that\nhas two disadvantages:\n\n  1. It's slower, as we actually invoke merge-one-file for\n     each unmerged path, which in turns writes temporary\n     files to the filesystem.\n\n  2. It requires a working directory to store the merged\n     result. When working in a bare repository, this can be\n     inconvenient.\n\nInstead, let's have read-tree perform the content-level\nmerge in core. If it results in conflicts, read-tree can\nsimply punt and leave the unmerged entries in the index.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n builtin/read-tree.c |    2 +\n unpack-trees.c      |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++\n unpack-trees.h      |    1 +\n 3 files changed, 72 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin/read-tree.c b/builtin/read-tree.c\nindex df6c4c8..392c378 100644\n--- a/builtin/read-tree.c\n+++ b/builtin/read-tree.c\n@@ -117,6 +117,8 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \t\t\t    \"3-way merge if no file level merging required\", 1),\n \t\tOPT_SET_INT(0, \"aggressive\", &opts.aggressive,\n \t\t\t    \"3-way merge in presence of adds and removes\", 1),\n+\t\tOPT_SET_INT(0, \"merge-content\", &opts.file_level_merge,\n+\t\t\t    \"3-way merge of non-conflicting file content\", 1),\n \t\tOPT_SET_INT(0, \"reset\", &opts.reset,\n \t\t\t    \"same as -m, but discard unmerged entries\", 1),\n \t\t{ OPTION_STRING, 0, \"prefix\", &opts.prefix, \"<subdirectory>/\",\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex 3a61d82..0443fcf 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -8,6 +8,8 @@\n #include \"progress.h\"\n #include \"refs.h\"\n #include \"attr.h\"\n+#include \"xdiff-interface.h\"\n+#include \"blob.h\"\n \n /*\n  * Error messages expected by scripts out of plumbing commands such as\n@@ -1515,6 +1517,45 @@ static void show_stage_entry(FILE *o,\n }\n #endif\n \n+static int file_level_merge(unsigned char sha1[20],\n+\t\t\t    struct cache_entry *old,\n+\t\t\t    struct cache_entry *head,\n+\t\t\t    struct cache_entry *remote)\n+{\n+\tmmfile_t old_data = {0}, head_data = {0}, remote_data = {0};\n+\tmmbuffer_t resolved = {0};\n+\txmparam_t xmp = {{0}};\n+\tint ret = -1;\n+\n+\tif (remote->ce_mode != head->ce_mode &&\n+\t    remote->ce_mode != old->ce_mode)\n+\t\tgoto out;\n+\n+\tread_mmblob(&old_data, old->sha1);\n+\tif (buffer_is_binary(old_data.ptr, old_data.size))\n+\t\tgoto out;\n+\tread_mmblob(&head_data, head->sha1);\n+\tif (buffer_is_binary(head_data.ptr, head_data.size))\n+\t\tgoto out;\n+\tread_mmblob(&remote_data, remote->sha1);\n+\tif (buffer_is_binary(remote_data.ptr, remote_data.size))\n+\t\tgoto out;\n+\n+\txmp.level = XDL_MERGE_ZEALOUS_ALNUM;\n+\tif (xdl_merge(&old_data, &head_data, &remote_data, &xmp, &resolved))\n+\t\tgoto out;\n+\tif (write_sha1_file(resolved.ptr, resolved.size, blob_type, sha1) < 0)\n+\t\tdie(\"unable to write resolved blob object\");\n+\tret = 0;\n+\n+out:\n+\tfree(old_data.ptr);\n+\tfree(head_data.ptr);\n+\tfree(remote_data.ptr);\n+\tfree(resolved.ptr);\n+\treturn ret;\n+}\n+\n int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o)\n {\n \tstruct cache_entry *index;\n@@ -1653,6 +1694,34 @@ int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o)\n \t\t\treturn -1;\n \t}\n \n+\tif (o->file_level_merge &&\n+\t    !no_anc_exists && head && remote && !head_match && !remote_match) {\n+\t\tint i;\n+\t\tstruct cache_entry *old = NULL;\n+\t\tunsigned char sha1[20];\n+\n+\t\tfor (i = 1; i < o->head_idx; i++) {\n+\t\t\tif (stages[i] && stages[i] != o->df_conflict_entry) {\n+\t\t\t\told = stages[i];\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t\tif (!old)\n+\t\t\tdie(\"BUG: file-level merge couldn't find ancestor\");\n+\n+\t\tif (file_level_merge(sha1, old, head, remote) == 0) {\n+\t\t\t/* ugh */\n+\t\t\tunsigned char tmp[20];\n+\t\t\tint r;\n+\n+\t\t\thashcpy(tmp, head->sha1);\n+\t\t\thashcpy(head->sha1, sha1);\n+\t\t\tr = merged_entry(head, index, o);\n+\t\t\thashcpy(head->sha1, tmp);\n+\t\t\treturn r;\n+\t\t}\n+\t}\n+\n \to->nontrivial_merge = 1;\n \n \t/* #2, #3, #4, #6, #7, #9, #10, #11. */\ndiff --git a/unpack-trees.h b/unpack-trees.h\nindex 7998948..516c2f1 100644\n--- a/unpack-trees.h\n+++ b/unpack-trees.h\n@@ -40,6 +40,7 @@ struct unpack_trees_options {\n \t\t     trivial_merges_only,\n \t\t     verbose_update,\n \t\t     aggressive,\n+\t\t     file_level_merge,\n \t\t     skip_unmerged,\n \t\t     initial_checkout,\n \t\t     diff_index_cached,\n-- \n1.7.6.15.ga6419\n"}]}