{"thread":{"id":"3482","subject":"bug?: stgit creates (unneccessary?) conflicts when pulling","startedAt":"2006-02-27T20:42:52Z","lastAt":"2006-03-11T06:46:15Z","messageCount":22,"participants":["Karl Hasselström","Sam Vilain","Catalin Marinas","Shawn Pearce","Chuck Lever","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"16851","messageId":"20060227204252.GA31836@diana.vm.bytemark.co.uk","threadId":"3482","inReplyTo":null,"subject":"bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2006-02-27T20:42:52Z","receivedAt":"2006-02-27T20:42:52Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"If I make a patch series where more than one patch touches the same\nline, I get a lot of merge errors when upstream has accepted them and\nI try to merge them back.\n\nSuppose a line contained the string \"0\". Patch p1 changes that to \"1\",\npatch p2 further changes that to \"2\". Upstream accept the patches, and\nI later \"stg pull\" them. When reapplying p1 after the pull, stg\ngenerates a merge conflict since upstream changed the \"0\" to \"2\" and\np1 changes the \"0\" to \"1\".\n\nThis situation arises for every line that's modified in more than one\npatch, and for every such patch except the last one. And it's really\nannoying, since it's intuitively obvious that there aren't actually\nany conflicts, since upstream accepted my patches verbatim.\n\nI suppose one way to fix it manually would be to first fetch, glance\nat the new upstream commits and try to find any accepted patches, and\nthen \"stg pull\" the commit corresponding to the earliest patch in my\nseries; repeat for every patch in the series. The queston is, how can\nwe automate it?\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"16854","messageId":"440372FE.2000301@vilain.net","threadId":"3482","inReplyTo":"20060227204252.GA31836@diana.vm.bytemark.co.uk","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Sam Vilain","fromEmail":"sam@vilain.net","sentAt":"2006-02-27T21:45:34Z","receivedAt":"2006-02-27T21:45:34Z","isPatch":false,"sender":{"key":"sam@vilain.net","avatar":"https://gravatar.com/avatar/8fc840ca854dbf6f7065b4335e3b934951c1dca3b11db688e95e471901f8f4a8?d=mp&s=160"},"body":"Karl Hasselström wrote:\n> If I make a patch series where more than one patch touches the same\n> line, I get a lot of merge errors when upstream has accepted them and\n> I try to merge them back.\n> \n> Suppose a line contained the string \"0\". Patch p1 changes that to \"1\",\n> patch p2 further changes that to \"2\". Upstream accept the patches, and\n> I later \"stg pull\" them. When reapplying p1 after the pull, stg\n> generates a merge conflict since upstream changed the \"0\" to \"2\" and\n> p1 changes the \"0\" to \"1\".\n> \n> This situation arises for every line that's modified in more than one\n> patch, and for every such patch except the last one. And it's really\n> annoying, since it's intuitively obvious that there aren't actually\n> any conflicts, since upstream accepted my patches verbatim.\n> \n> I suppose one way to fix it manually would be to first fetch, glance\n> at the new upstream commits and try to find any accepted patches, and\n> then \"stg pull\" the commit corresponding to the earliest patch in my\n> series; repeat for every patch in the series. The queston is, how can\n> we automate it?\n\nI don't seem to suffer from this, using my \"diff3 || \nediff-merge-files-with-ancestor\" script as a merge tool.  The diff3, or \nediff, seem to DTRT so long as the change is cleanly applied.  Otherwise \nI just get a merge conflict difference and I just press A/B to pick \nwhich one I want.\n\nSam.\n"},{"id":"16856","messageId":"44037A5C.6080409@gmail.com","threadId":"3482","inReplyTo":"20060227204252.GA31836@diana.vm.bytemark.co.uk","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-02-27T22:17:00Z","receivedAt":"2006-02-27T22:17:00Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"Karl Hasselström wrote:\n> If I make a patch series where more than one patch touches the same\n> line, I get a lot of merge errors when upstream has accepted them and\n> I try to merge them back.\n\nWe discussed about this in the thread announcing pg\n(http://article.gmane.org/gmane.comp.version-control.git/16247). This is\nnot easy to fix because StGIT pushes patches one by one and it stops at\nthe first conflict. Pg was trying to merge two patches at once but this\nis not suitable for StGIT since the latter keeps the patches as single\ncommits.\n\nThere is another problem - the same line might have been modified by a\nthird-party patch merged into the kernel (and the conflict solved by the\nmaintainer).\n\n> This situation arises for every line that's modified in more than one\n> patch, and for every such patch except the last one. And it's really\n> annoying, since it's intuitively obvious that there aren't actually\n> any conflicts, since upstream accepted my patches verbatim.\n\nBecause I found the same situation a bit annoying, I added the --reset\noption to resolved. If you know your patch was merged without\nmodifications, just use \"stg resolved --all --reset local\".\n\nAn idea (untested, I don't even know whether it's feasible) would be to\ncheck which patches were merged by reverse-applying them starting with\nthe last. In this situation, all the merged patches should just revert\ntheir changes. You only need to do a git-diff between the bottom and the\ntop of the patch and git-apply the output (maybe without even modifying\nthe tree). If this operation succeeds, the patch was integrated and you\ndon't even need to push it. The tool could even fold two consecutive\npatches and reverse-apply them. The disadvantage might be the delay when\npushing patches but we could enable this test only if an option is\npassed to the pull command.\n\nIf you really want to make StGIT behave intelligently, have a look at\nthe patch commuting theory in Darcs. It tends to handle this kind of\nconflicts easily. StGIT also does some patch commuting but using the\ndiff3 algorithm and asks the user to fix different conflicts.\n\nCatalin\n"},{"id":"16860","messageId":"20060227222600.GA11797@spearce.org","threadId":"3482","inReplyTo":"20060227204252.GA31836@diana.vm.bytemark.co.uk","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-02-27T22:26:00Z","receivedAt":"2006-02-27T22:26:00Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Karl Hasselstr?m <kha@treskal.com> wrote:\n> If I make a patch series where more than one patch touches the same\n> line, I get a lot of merge errors when upstream has accepted them and\n> I try to merge them back.\n> \n> Suppose a line contained the string \"0\". Patch p1 changes that to \"1\",\n> patch p2 further changes that to \"2\". Upstream accept the patches, and\n> I later \"stg pull\" them. When reapplying p1 after the pull, stg\n> generates a merge conflict since upstream changed the \"0\" to \"2\" and\n> p1 changes the \"0\" to \"1\".\n\nYou should look at pg:\n\n  http://www.spearce.org/2006/02/pg-version-0111-released.html\n\nIt has some of the features of StGIT and it (at least partially)\nsolves this problem.\n\nAssume you had a patch stack of:\n\n\tPatchA : Change 0 to a 1\n\tPatchB : Change 1 to a 2\n\tPatchC : Change 2 to a 3\n\nwith each affecting the same line of the same file.\n\nWhen pg grabs its (possibly remote) parent (\"stg pull\" aka pg-rebase)\nwe try to push down PatchA.  If PatchA fails to push cleanly we'll\npop it off and try to push PatchA + PatchB.  If that pushes cleanly\nthen we fold the content of PatchA into PatchB, effectively making\nPatchA part of PatchB.  If PatchA + PatchB failed to push down\ncleanly then we pop both and retry pushing PatchA + PatchB + PatchC.\nIf that pushes down cleanly then we make PatchA and PatchB officially\npart of PatchC.\n\nThis required some ``hacks'' in pg-push.  Basically if we are\ndoing a non-fastforward push (as there are new commits we must\nmerge on top of) we run an external diff/patch to apply the change.\nIf that fails we reset the tree back to a clean state and try again.\nWhenever patch rejects a hunk we examine the hunk to see if it is\nalready applied to the target file; if it is already applied we\nskip the hunk.  If all hunks applied cleanly and/or are already\napplied we accept the patch (or combination of patches) as merging\ncleanly. Yea, its not very pretty.  But it works!\n\nWhere it falls down is if the upstream accepts all three of your\npatches but then changes the line from a 3 to a 4.  pg won't look\nat the GIT commit history to detect that the upstream accepted your\nfinal change (PatchC) but then overwrite it with a newer change\n(3->4).  I have thought about trying to implement this but the\ncurrent environment where I am using pg wouldn't benefit from it,\nso it has not been high on my priority list.\n\n-- \nShawn.\n"},{"id":"16907","messageId":"b0943d9e0602280700p132c6da2v@mail.gmail.com","threadId":"3482","inReplyTo":"44037A5C.6080409@gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-02-28T15:00:22Z","receivedAt":"2006-02-28T15:00:22Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:\n> An idea (untested, I don't even know whether it's feasible) would be to\n> check which patches were merged by reverse-applying them starting with\n> the last. In this situation, all the merged patches should just revert\n> their changes. You only need to do a git-diff between the bottom and the\n> top of the patch and git-apply the output (maybe without even modifying\n> the tree). If this operation succeeds, the patch was integrated and you\n> don't even need to push it.\n\nI tried some simple tests with the idea above. I attached a patch if\nyou'd like to try (I won't push it to the main StGIT repository yet.\nFor safety reasons, it only skips the merged patches when pushing\nthem. A future version could simply delete the merged patches.\n\n--\nCatalin\n\n\nAdd a merged upstream test for pull and push\n\nFrom: Catalin Marinas <catalin.marinas@gmail.com>\n\nThis patch adds the --merged option to both pull and push commands. With\nthis option, these commands will first try to check which patches were\nmerged upstream by reverse-applying them in reverse order. This should\nsolve the situation where several patches modify the same line in a file.\n\nSigned-off-by: Catalin Marinas <catalin.marinas@gmail.com>\n---\n\n stgit/commands/pull.py |   20 +++++++++++++++++++-\n stgit/commands/push.py |   17 ++++++++++++++++-\n stgit/git.py           |   12 +++++++++---\n stgit/stack.py         |   20 ++++++++++++++++++++\n 4 files changed, 64 insertions(+), 5 deletions(-)\n\ndiff --git a/stgit/commands/pull.py b/stgit/commands/pull.py\nindex 843b579..5d75530 100644\n--- a/stgit/commands/pull.py\n+++ b/stgit/commands/pull.py\n@@ -39,6 +39,9 @@ format.\"\"\"\n \n options = [make_option('-n', '--nopush',\n                        help = 'do not push the patches back after pulling',\n+                       action = 'store_true'),\n+           make_option('-m', '--merged',\n+                       help = 'check for patches merged upstream (slower)',\n                        action = 'store_true')]\n \n def func(parser, options, args):\n@@ -77,12 +80,27 @@ def func(parser, options, args):\n     # push the patches back\n     if options.nopush:\n         applied = []\n+\n+    # check for patches merged upstream\n+    if options.merged:\n+        merged = crt_series.merged_patches(patches)\n+    else:\n+        merged = []\n+\n     for p in applied:\n+        if p in merged:\n+            print 'Patch \"%s\" merged upstream' % p\n+            continue\n+\n         print 'Pushing patch \"%s\"...' % p,\n         sys.stdout.flush()\n-        crt_series.push_patch(p)\n+\n+        modified = crt_series.push_patch(p)\n+\n         if crt_series.empty_patch(p):\n             print 'done (empty patch)'\n+        elif modified:\n+            print 'done (modified)'\n         else:\n             print 'done'\n \ndiff --git a/stgit/commands/push.py b/stgit/commands/push.py\nindex 9924a78..72b2663 100644\n--- a/stgit/commands/push.py\n+++ b/stgit/commands/push.py\n@@ -49,6 +49,9 @@ options = [make_option('-a', '--all',\n            make_option('--reverse',\n                        help = 'push the patches in reverse order',\n                        action = 'store_true'),\n+           make_option('-m', '--merged',\n+                       help = 'check for patches merged upstream (slower)',\n+                       action = 'store_true'),\n            make_option('--undo',\n                        help = 'undo the last push operation',\n                        action = 'store_true')]\n@@ -134,9 +137,21 @@ def func(parser, options, args):\n     elif forwarded == 1:\n         print 'Fast-forwarded patch \"%s\"' % patches[0]\n \n-    for p in patches[forwarded:]:\n+    patches = patches[forwarded:]\n+\n+    # check for patches merged upstream\n+    if options.merged:\n+        merged = crt_series.merged_patches(patches)\n+    else:\n+        merged = []\n+\n+    for p in patches:\n         is_patch_appliable(p)\n \n+        if p in merged:\n+            print 'Patch \"%s\" merged upstream' % p\n+            continue\n+\n         print 'Pushing patch \"%s\"...' % p,\n         sys.stdout.flush()\n \ndiff --git a/stgit/git.py b/stgit/git.py\nindex 016bc3a..66b8612 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -462,14 +462,20 @@ def commit(message, files = None, parent\n \n     return commit_id\n \n-def apply_diff(rev1, rev2):\n+def apply_diff(rev1, rev2, check_index = True):\n     \"\"\"Apply the diff between rev1 and rev2 onto the current\n     index. This function doesn't need to raise an exception since it\n     is only used for fast-pushing a patch. If this operation fails,\n     the pushing would fall back to the three-way merge.\n     \"\"\"\n-    return os.system('git-diff-tree -p %s %s | git-apply --index 2> /dev/null'\n-                     % (rev1, rev2)) == 0\n+    if check_index:\n+        index_opt = '--index'\n+    else:\n+        index_opt = ''\n+    cmd = 'git-diff-tree -p %s %s | git-apply %s 2> /dev/null' \\\n+          % (rev1, rev2, index_opt)\n+\n+    return os.system(cmd) == 0\n \n def merge(base, head1, head2):\n     \"\"\"Perform a 3-way merge between base, head1 and head2 into the\ndiff --git a/stgit/stack.py b/stgit/stack.py\nindex e1c55f0..9d5f043 100644\n--- a/stgit/stack.py\n+++ b/stgit/stack.py\n@@ -780,6 +780,26 @@ class Series:\n \n         return forwarded\n \n+    def merged_patches(self, names):\n+        \"\"\"Test which patches were merged upstream by reverse-applying\n+        them in reverse order. The function returns the list of\n+        patches detected to have been applied. The state of the tree\n+        is restored to the original one\n+        \"\"\"\n+        patches = [Patch(name, self.__patch_dir, self.__refs_dir)\n+                   for name in names]\n+        patches.reverse()\n+\n+        merged = []\n+        for p in patches:\n+            if git.apply_diff(p.get_top(), p.get_bottom(), False):\n+                merged.append(p.get_name())\n+        merged.reverse()\n+\n+        git.reset()\n+\n+        return merged\n+\n     def push_patch(self, name):\n         \"\"\"Pushes a patch on the stack\n         \"\"\"\n"},{"id":"16914","messageId":"b0943d9e0602281053r675cee49i@mail.gmail.com","threadId":"3482","inReplyTo":"b0943d9e0602280700p132c6da2v@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-02-28T18:53:07Z","receivedAt":"2006-02-28T18:53:07Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 28/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:\n> On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:\n> > An idea (untested, I don't even know whether it's feasible) would be to\n> > check which patches were merged by reverse-applying them starting with\n> > the last. In this situation, all the merged patches should just revert\n> > their changes. You only need to do a git-diff between the bottom and the\n> > top of the patch and git-apply the output (maybe without even modifying\n> > the tree). If this operation succeeds, the patch was integrated and you\n> > don't even need to push it.\n>\n> I tried some simple tests with the idea above. I attached a patch if\n> you'd like to try (I won't push it to the main StGIT repository yet.\n> For safety reasons, it only skips the merged patches when pushing\n> them. A future version could simply delete the merged patches.\n\nDon't bother trying this patch. I just found a bug with git.reset()\nand the caching of the git.__head variable. I'll post another patch in\na few hours.\n\n--\nCatalin\n"},{"id":"16925","messageId":"b0943d9e0602281445w7160d915y@mail.gmail.com","threadId":"3482","inReplyTo":"44037A5C.6080409@gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-02-28T22:45:56Z","receivedAt":"2006-02-28T22:45:56Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:\n> An idea (untested, I don't even know whether it's feasible) would be to\n> check which patches were merged by reverse-applying them starting with\n> the last. In this situation, all the merged patches should just revert\n> their changes. You only need to do a git-diff between the bottom and the\n> top of the patch and git-apply the output (maybe without even modifying\n> the tree). If this operation succeeds, the patch was integrated and you\n> don't even need to push it.\n\nI attached another patch that should work properly. It also pushes\nempty patches on the stack if they were merged upstream (a 'stg clean'\nis required to remove them). This is useful for the push --undo\ncommand if you are not happy with the result.\n\nI'll try this patch for a bit more before pushing into the repository.\n\n--\nCatalin\n\n\nAdd a merged upstream test for pull and push\n\nFrom: Catalin Marinas <catalin.marinas@gmail.com>\n\nThis patch adds the --merged option to both pull and push commands. With\nthis option, these commands will first try to check which patches were\nmerged upstream by reverse-applying them in reverse order. This should\nsolve the situation where several patches modify the same line in a file.\n\nSigned-off-by: Catalin Marinas <catalin.marinas@gmail.com>\n---\n\n stgit/commands/common.py |   41 +++++++++++++++++++++++++++++++++++++++++\n stgit/commands/pull.py   |   15 +++++----------\n stgit/commands/push.py   |   28 ++++++----------------------\n stgit/git.py             |   12 +++++++++---\n stgit/stack.py           |   34 +++++++++++++++++++++++++++++++---\n 5 files changed, 92 insertions(+), 38 deletions(-)\n\ndiff --git a/stgit/commands/common.py b/stgit/commands/common.py\nindex 2e1ba7a..2985379 100644\n--- a/stgit/commands/common.py\n+++ b/stgit/commands/common.py\n@@ -132,6 +132,47 @@ def resolved_all(reset = None):\n             resolved(filename, reset)\n         os.remove(os.path.join(git.get_base_dir(), 'conflicts'))\n \n+def push_patches(patches, check_merged = False):\n+    \"\"\"Push multiple patches onto the stack. This function is shared\n+    between the push and pull commands\n+    \"\"\"\n+    forwarded = crt_series.forward_patches(patches)\n+    if forwarded > 1:\n+        print 'Fast-forwarded patches \"%s\" - \"%s\"' % (patches[0],\n+                                                      patches[forwarded - 1])\n+    elif forwarded == 1:\n+        print 'Fast-forwarded patch \"%s\"' % patches[0]\n+\n+    names = patches[forwarded:]\n+\n+    # check for patches merged upstream\n+    if check_merged:\n+        print 'Checking for patches merged upstream...',\n+        sys.stdout.flush()\n+\n+        merged = crt_series.merged_patches(names)\n+\n+        print 'done (%d found)' % len(merged)\n+    else:\n+        merged = []\n+\n+    for p in names:\n+        print 'Pushing patch \"%s\"...' % p,\n+        sys.stdout.flush()\n+\n+        if p in merged:\n+            crt_series.push_patch(p, empty = True)\n+            print 'done (merged upstream)'\n+        else:\n+            modified = crt_series.push_patch(p)\n+\n+            if crt_series.empty_patch(p):\n+                print 'done (empty patch)'\n+            elif modified:\n+                print 'done (modified)'\n+            else:\n+                print 'done'\n+\n def name_email(address):\n     \"\"\"Return a tuple consisting of the name and email parsed from a\n     standard 'name <email>' string\ndiff --git a/stgit/commands/pull.py b/stgit/commands/pull.py\nindex 843b579..8f26f4d 100644\n--- a/stgit/commands/pull.py\n+++ b/stgit/commands/pull.py\n@@ -39,6 +39,9 @@ format.\"\"\"\n \n options = [make_option('-n', '--nopush',\n                        help = 'do not push the patches back after pulling',\n+                       action = 'store_true'),\n+           make_option('-m', '--merged',\n+                       help = 'check for patches merged upstream',\n                        action = 'store_true')]\n \n def func(parser, options, args):\n@@ -75,15 +78,7 @@ def func(parser, options, args):\n     print 'done'\n \n     # push the patches back\n-    if options.nopush:\n-        applied = []\n-    for p in applied:\n-        print 'Pushing patch \"%s\"...' % p,\n-        sys.stdout.flush()\n-        crt_series.push_patch(p)\n-        if crt_series.empty_patch(p):\n-            print 'done (empty patch)'\n-        else:\n-            print 'done'\n+    if not options.nopush:\n+        push_patches(applied, options.merged)\n \n     print_crt_patch()\ndiff --git a/stgit/commands/push.py b/stgit/commands/push.py\nindex 9924a78..90777c1 100644\n--- a/stgit/commands/push.py\n+++ b/stgit/commands/push.py\n@@ -49,6 +49,9 @@ options = [make_option('-a', '--all',\n            make_option('--reverse',\n                        help = 'push the patches in reverse order',\n                        action = 'store_true'),\n+           make_option('-m', '--merged',\n+                       help = 'check for patches merged upstream',\n+                       action = 'store_true'),\n            make_option('--undo',\n                        help = 'undo the last push operation',\n                        action = 'store_true')]\n@@ -58,9 +61,9 @@ def is_patch_appliable(p):\n     \"\"\"See if patch exists, or is already applied.\n     \"\"\"\n     if p in applied:\n-        raise CmdException, 'Patch \"%s\" is already applied.' % p\n+        raise CmdException, 'Patch \"%s\" is already applied' % p\n     if p not in unapplied:\n-        raise CmdException, 'Patch \"%s\" does not exist.' % p\n+        raise CmdException, 'Patch \"%s\" does not exist' % p\n \n def func(parser, options, args):\n     \"\"\"Pushes the given patch or all onto the series\n@@ -127,25 +130,6 @@ def func(parser, options, args):\n     if options.reverse:\n         patches.reverse()\n \n-    forwarded = crt_series.forward_patches(patches)\n-    if forwarded > 1:\n-        print 'Fast-forwarded patches \"%s\" - \"%s\"' % (patches[0],\n-                                                      patches[forwarded - 1])\n-    elif forwarded == 1:\n-        print 'Fast-forwarded patch \"%s\"' % patches[0]\n-\n-    for p in patches[forwarded:]:\n-        is_patch_appliable(p)\n-\n-        print 'Pushing patch \"%s\"...' % p,\n-        sys.stdout.flush()\n+    push_patches(patches, options.merged)\n \n-        modified = crt_series.push_patch(p)\n-\n-        if crt_series.empty_patch(p):\n-            print 'done (empty patch)'\n-        elif modified:\n-            print 'done (modified)'\n-        else:\n-            print 'done'\n     print_crt_patch()\ndiff --git a/stgit/git.py b/stgit/git.py\nindex a3488ff..40d54ef 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -465,14 +465,20 @@ def commit(message, files = None, parent\n \n     return commit_id\n \n-def apply_diff(rev1, rev2):\n+def apply_diff(rev1, rev2, check_index = True):\n     \"\"\"Apply the diff between rev1 and rev2 onto the current\n     index. This function doesn't need to raise an exception since it\n     is only used for fast-pushing a patch. If this operation fails,\n     the pushing would fall back to the three-way merge.\n     \"\"\"\n-    return os.system('git-diff-tree -p %s %s | git-apply --index 2> /dev/null'\n-                     % (rev1, rev2)) == 0\n+    if check_index:\n+        index_opt = '--index'\n+    else:\n+        index_opt = ''\n+    cmd = 'git-diff-tree -p %s %s | git-apply %s 2> /dev/null' \\\n+          % (rev1, rev2, index_opt)\n+\n+    return os.system(cmd) == 0\n \n def merge(base, head1, head2):\n     \"\"\"Perform a 3-way merge between base, head1 and head2 into the\ndiff --git a/stgit/stack.py b/stgit/stack.py\nindex e1c55f0..165b5a7 100644\n--- a/stgit/stack.py\n+++ b/stgit/stack.py\n@@ -780,7 +780,27 @@ class Series:\n \n         return forwarded\n \n-    def push_patch(self, name):\n+    def merged_patches(self, names):\n+        \"\"\"Test which patches were merged upstream by reverse-applying\n+        them in reverse order. The function returns the list of\n+        patches detected to have been applied. The state of the tree\n+        is restored to the original one\n+        \"\"\"\n+        patches = [Patch(name, self.__patch_dir, self.__refs_dir)\n+                   for name in names]\n+        patches.reverse()\n+\n+        merged = []\n+        for p in patches:\n+            if git.apply_diff(p.get_top(), p.get_bottom(), False):\n+                merged.append(p.get_name())\n+        merged.reverse()\n+\n+        git.reset()\n+\n+        return merged\n+\n+    def push_patch(self, name, empty = False):\n         \"\"\"Pushes a patch on the stack\n         \"\"\"\n         unapplied = self.get_unapplied()\n@@ -798,7 +818,15 @@ class Series:\n         modified = False\n \n         # top != bottom always since we have a commit for each patch\n-        if head == bottom:\n+        if empty:\n+            # just make an empty patch (top = bottom = HEAD). This\n+            # option is useful to allow undoing already merged\n+            # patches. The top is updated by refresh_patch since we\n+            # need an empty commit\n+            patch.set_bottom(head, backup = True)\n+            patch.set_top(head, backup = True)\n+            modified = True\n+        elif head == bottom:\n             # reset the backup information\n             patch.set_bottom(bottom, backup = True)\n             patch.set_top(top, backup = True)\n@@ -835,7 +863,7 @@ class Series:\n         self.__set_current(name)\n \n         # head == bottom case doesn't need to refresh the patch\n-        if head != bottom:\n+        if empty or head != bottom:\n             if not ex:\n                 # if the merge was OK and no conflicts, just refresh the patch\n                 # The GIT cache was already updated by the merge operation\n"},{"id":"16938","messageId":"tnx1wxmig75.fsf@arm.com","threadId":"3482","inReplyTo":"20060227222600.GA11797@spearce.org","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@arm.com","sentAt":"2006-03-01T10:59:10Z","receivedAt":"2006-03-01T10:59:10Z","isPatch":false,"sender":{"key":"catalin.marinas@arm.com","avatar":null},"body":"Shawn Pearce <spearce@spearce.org> wrote:\n> Karl Hasselstr?m <kha@treskal.com> wrote:\n>> If I make a patch series where more than one patch touches the same\n>> line, I get a lot of merge errors when upstream has accepted them and\n>> I try to merge them back.\n>\n> When pg grabs its (possibly remote) parent (\"stg pull\" aka pg-rebase)\n> we try to push down PatchA.  If PatchA fails to push cleanly we'll\n> pop it off and try to push PatchA + PatchB.  If that pushes cleanly\n> then we fold the content of PatchA into PatchB, effectively making\n> PatchA part of PatchB.  If PatchA + PatchB failed to push down\n> cleanly then we pop both and retry pushing PatchA + PatchB + PatchC.\n\nHow do you solve the situation where only PatchA, PatchC and PatchE\nwere merged, B and D still pending? Trying combinations of patches is\nnot a good idea.\n\nAs I said, if you have a big number of patches this might be pretty\nslow. Have a look at my patch for trying the reversed patches in\nreverse order. It seems to solve this problem for most of the\ncases. There are cases when this method would fail like adjacent\nchanges made by third-party patches that break the context of the git\npatches and git-apply would fail. An addition to this would be to try\na diff3 merge with the reversed patch but I don't think it's worth\nsince it would become much slower.\n\n> If that pushes down cleanly then we make PatchA and PatchB officially\n> part of PatchC.\n\nI don't agree with this. For example, patches A, B and C change the\nsame line in file1 but patch A also changes file2 and patch B changed\nfile3. With your approach, merging A+B+C succeeds and you make A and B\npart of C and hence move the changed to file2 and file3 in patch C.\n\nThe above can happen when the maintainer only merges part of the patch\nor simply decides to merge patch C only and manually solve the\nconflict in file1 (since patch C is based on the context from patches\nA+B).\n\n-- \nCatalin\n"},{"id":"16943","messageId":"20060301145105.GB3313@spearce.org","threadId":"3482","inReplyTo":"tnx1wxmig75.fsf@arm.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-03-01T14:51:05Z","receivedAt":"2006-03-01T14:51:05Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"[Side Note: I've suddenly stopped receiving mail from vger.\n Even majordomo isn't replying to my pleas for help.  Arggh!\n Yet all other incoming email seems to be fine.]\n\nCatalin Marinas <catalin.marinas@arm.com> wrote:\n> Shawn Pearce <spearce@spearce.org> wrote:\n> > Karl Hasselstr?m <kha@treskal.com> wrote:\n> >> If I make a patch series where more than one patch touches the same\n> >> line, I get a lot of merge errors when upstream has accepted them and\n> >> I try to merge them back.\n> >\n> > When pg grabs its (possibly remote) parent (\"stg pull\" aka pg-rebase)\n> > we try to push down PatchA.  If PatchA fails to push cleanly we'll\n> > pop it off and try to push PatchA + PatchB.  If that pushes cleanly\n> > then we fold the content of PatchA into PatchB, effectively making\n> > PatchA part of PatchB.  If PatchA + PatchB failed to push down\n> > cleanly then we pop both and retry pushing PatchA + PatchB + PatchC.\n> \n> How do you solve the situation where only PatchA, PatchC and PatchE\n> were merged, B and D still pending? Trying combinations of patches is\n> not a good idea.\n\nYea, ouch.  pg would fold everything into E, destroying the B\nand D boundary.  A (not so good) workaround right now would be to\nundo the rebase, pop all patches, rebase, then push one by one.\nI didn't even consider this case as its not my workflow style:\nat least not right now.\n\n> As I said, if you have a big number of patches this might be pretty\n> slow. Have a look at my patch for trying the reversed patches in\n> reverse order. It seems to solve this problem for most of the\n> cases. There are cases when this method would fail like adjacent\n> changes made by third-party patches that break the context of the git\n> patches and git-apply would fail. An addition to this would be to try\n> a diff3 merge with the reversed patch but I don't think it's worth\n> since it would become much slower.\n\nTrue.  The constant reapplication does really slow it down.  So does\ngrabbing the reverse patch and seeing if it applies backwards\ncleanly.  Neither operation is fast, and neither is really going\nto be fast.\n\nBTW - I did read through your patch when it was posted: the reverse\napply idea is pretty slick and should work a large part of the time,\nas you said.  Nice addition to StGIT.\n \n> > If that pushes down cleanly then we make PatchA and PatchB officially\n> > part of PatchC.\n> \n> I don't agree with this. For example, patches A, B and C change the\n> same line in file1 but patch A also changes file2 and patch B changed\n> file3. With your approach, merging A+B+C succeeds and you make A and B\n> part of C and hence move the changed to file2 and file3 in patch C.\n> \n> The above can happen when the maintainer only merges part of the patch\n> or simply decides to merge patch C only and manually solve the\n> conflict in file1 (since patch C is based on the context from patches\n> A+B).\n\nAh, yes.  The upstream maintainer who doesn't take everything.\nShame on them.  :-) Shame on me for also not dealing with this\ncase in pg, you are completely correct that folding these patches\ntogether in this scenario is a really bad idea.\n\nIn the one environment where I really use pg the upstream is forced\nto take the entire patch: I have my own foreign SCM interface to PVCS\nVM (its heavily customized crap, so I'm not going to contribute it)\nand in this interface the upstream is forced to take the entire patch\nevery time.  So right now its not a huge concern to me personally,\nbut if anyone else is trying to use pg it might be.\n\n-- \nShawn.\n"},{"id":"16945","messageId":"b0943d9e0603010708l72cb14d1w@mail.gmail.com","threadId":"3482","inReplyTo":"20060301145105.GB3313@spearce.org","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-03-01T15:08:39Z","receivedAt":"2006-03-01T15:08:39Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 01/03/06, Shawn Pearce <spearce@spearce.org> wrote:\n> [Side Note: I've suddenly stopped receiving mail from vger.\n>  Even majordomo isn't replying to my pleas for help.  Arggh!\n>  Yet all other incoming email seems to be fine.]\n\nnews.gmane.org\n\n> True.  The constant reapplication does really slow it down.  So does\n> grabbing the reverse patch and seeing if it applies backwards\n> cleanly.  Neither operation is fast, and neither is really going\n> to be fast.\n\nI realised that, depending on the number of patches merged upstream,\nusing this option can make StGIT faster. That's because when pushing a\npatch (without the --merged option), StGIT first tries a diff | apply\nfollowed by a three-way merge (even slower) if the former method\nfails. This means that for all the patches merged upstream, StGIT\ntries both methods since diff | apply fails anyway. With the --merged\noption, StGIT would only try the reverse-diff | apply and, if this\nsucceeds, it will skip the normal push methods.\n\n--\nCatalin\n"},{"id":"16948","messageId":"20060301155043.GA3706@spearce.org","threadId":"3482","inReplyTo":"b0943d9e0603010708l72cb14d1w@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-03-01T15:50:43Z","receivedAt":"2006-03-01T15:50:43Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Catalin Marinas <catalin.marinas@gmail.com> wrote:\n> On 01/03/06, Shawn Pearce <spearce@spearce.org> wrote:\n> > True.  The constant reapplication does really slow it down.  So does\n> > grabbing the reverse patch and seeing if it applies backwards\n> > cleanly.  Neither operation is fast, and neither is really going\n> > to be fast.\n> \n> I realised that, depending on the number of patches merged upstream,\n> using this option can make StGIT faster. That's because when pushing a\n> patch (without the --merged option), StGIT first tries a diff | apply\n> followed by a three-way merge (even slower) if the former method\n> fails. This means that for all the patches merged upstream, StGIT\n> tries both methods since diff | apply fails anyway. With the --merged\n> option, StGIT would only try the reverse-diff | apply and, if this\n> succeeds, it will skip the normal push methods.\n\nSpeaking of making StGIT faster: earlier we were talking about how\ngit-diff|git-apply is faster than a 3 way git-read-tree on large\nmerges when there are many structural changes in the tree due to\nthe smaller number of process spawns required.\n\nYou might want to take a look at pg--merge-all: This is sort of based\non git-merge-recursive, but I've gotten it down to just a handful\nof process spawns, aside from the stupidity of git-checkout-index.\n(My recent git-checkout-index patches are working to correct that.)\n\n-- \nShawn.\n"},{"id":"16961","messageId":"4405DC41.8020700@citi.umich.edu","threadId":"3482","inReplyTo":"b0943d9e0602281445w7160d915y@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Chuck Lever","fromEmail":"cel@citi.umich.edu","sentAt":"2006-03-01T17:39:13Z","receivedAt":"2006-03-01T17:39:13Z","isPatch":false,"sender":{"key":"cel@citi.umich.edu","avatar":null},"body":"Catalin Marinas wrote:\n> On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:\n> \n>>An idea (untested, I don't even know whether it's feasible) would be to\n>>check which patches were merged by reverse-applying them starting with\n>>the last. In this situation, all the merged patches should just revert\n>>their changes. You only need to do a git-diff between the bottom and the\n>>top of the patch and git-apply the output (maybe without even modifying\n>>the tree). If this operation succeeds, the patch was integrated and you\n>>don't even need to push it.\n> \n> \n> I attached another patch that should work properly. It also pushes\n> empty patches on the stack if they were merged upstream (a 'stg clean'\n> is required to remove them). This is useful for the push --undo\n> command if you are not happy with the result.\n> \n> I'll try this patch for a bit more before pushing into the repository.\n\ni think this is a cool idea.  but it seems still to require a bit of \nconvention on the part of the maintainer.\n\nif maintainer X takes a patch \"a\" from developer Y, but modifies patch \n\"a\" before committing it, then your nifty automated mechanism will still \nhave trouble merging developer Y's stack when Y pulls again.\n\nthe convention might be that maintainers who accept patches will always \naccept exactly what was sent, and then immediately apply another commit \nthat addresses any issues they have with the original commit.  this is \nalso a good idea so that the history contains the exact attribution of \neach change.\n\n\nbegin:vcard\nfn:Chuck Lever\nn:Lever;Charles\norg:Network Appliance, Incorporated;Open Source NFS Client Development\nadr:535 West William Street, Suite 3100;;Center for Information Technology Integration;Ann Arbor;MI;48103-4943;USA\nemail;internet:cel@citi.umich.edu\ntitle:Member of Technical Staff\ntel;work:+1 734 763-4415\ntel;fax:+1 734 763 4434\ntel;home:+1 734 668-1089\nx-mozilla-html:FALSE\nurl:http://troy.citi.umich.edu/u/cel/\nversion:2.1\nend:vcard\n\n"},{"id":"16964","messageId":"b0943d9e0603010953iccf64a4v@mail.gmail.com","threadId":"3482","inReplyTo":"4405DC41.8020700@citi.umich.edu","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-03-01T17:53:53Z","receivedAt":"2006-03-01T17:53:53Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 01/03/06, Chuck Lever <cel@citi.umich.edu> wrote:\n> Catalin Marinas wrote:\n> > I attached another patch that should work properly. It also pushes\n> > empty patches on the stack if they were merged upstream (a 'stg clean'\n> > is required to remove them). This is useful for the push --undo\n> > command if you are not happy with the result.\n>\n> if maintainer X takes a patch \"a\" from developer Y, but modifies patch\n> \"a\" before committing it, then your nifty automated mechanism will still\n> have trouble merging developer Y's stack when Y pulls again.\n>\n> the convention might be that maintainers who accept patches will always\n> accept exactly what was sent, and then immediately apply another commit\n> that addresses any issues they have with the original commit.\n\nThis won't solve the problem since testing whether patch \"a\" was\nmerged upstream will fail because its reverse won't apply cleanly onto\nthe upstream HEAD. Of course, you can try combination of upstream\ncommits and local patches but it's not really feasible.\n\nAs I said, this method doesn't solve all the upstream merge situations\nbut it is OK for most of them.\n\n--\nCatalin\n"},{"id":"17116","messageId":"20060303141329.GA16456@diana.vm.bytemark.co.uk","threadId":"3482","inReplyTo":"b0943d9e0603010953iccf64a4v@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2006-03-03T14:13:29Z","receivedAt":"2006-03-03T14:13:29Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2006-03-01 17:53:53 +0000, Catalin Marinas wrote:\n\n> This won't solve the problem since testing whether patch \"a\" was\n> merged upstream will fail because its reverse won't apply cleanly\n> onto the upstream HEAD. Of course, you can try combination of\n> upstream commits and local patches but it's not really feasible.\n>\n> As I said, this method doesn't solve all the upstream merge\n> situations but it is OK for most of them.\n\nWe could perhaps do a little better. Instead of just noting whether\nthe patch vanishes when reverse-applied, save the top and bottom of\nthe patch as reverse-applied, and then replace the patch with the\nreverse of that. If the patch vanishes, this does what your patch does\nright now. If the patch does not vanish, all that remains is the parts\nthat upstream didn't accept. (And as before, if the patch didn't\nreverse-apply cleanly, assume upstream hasn't accepted it at all yet.)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"17117","messageId":"20060303142413.GB16456@diana.vm.bytemark.co.uk","threadId":"3482","inReplyTo":"b0943d9e0602281445w7160d915y@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2006-03-03T14:24:13Z","receivedAt":"2006-03-03T14:24:13Z","isPatch":false,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2006-02-28 22:45:56 +0000, Catalin Marinas wrote:\n\n> On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:\n>\n> > An idea (untested, I don't even know whether it's feasible) would\n> > be to check which patches were merged by reverse-applying them\n> > starting with the last. In this situation, all the merged patches\n> > should just revert their changes. You only need to do a git-diff\n> > between the bottom and the top of the patch and git-apply the\n> > output (maybe without even modifying the tree). If this operation\n> > succeeds, the patch was integrated and you don't even need to push\n> > it.\n>\n> I attached another patch that should work properly. It also pushes\n> empty patches on the stack if they were merged upstream (a 'stg\n> clean' is required to remove them). This is useful for the push\n> --undo command if you are not happy with the result.\n>\n> I'll try this patch for a bit more before pushing into the\n> repository.\n\nIt appears to work for me. I still had to fix things up manually when\npulling the uncommit patch though, since you had made a minor change\nin \"uncommit.py\":\n\n  Pushing patch \"uncommit\"...Error: File \"stgit/commands/uncommit.py\" added in branches but different\n\nIs there a way to make stgit not fall on its face when faced with this\nsituation? Surely it ought to be possible to create a merged file with\nconflict markers? (I realize this is harder when there is no common\nancestor, but these files are 95% identical!)\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"17122","messageId":"4408BBDC.10802@gmail.com","threadId":"3482","inReplyTo":"20060303141329.GA16456@diana.vm.bytemark.co.uk","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-03-03T21:57:48Z","receivedAt":"2006-03-03T21:57:48Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"Karl Hasselström wrote:\n> We could perhaps do a little better. Instead of just noting whether\n> the patch vanishes when reverse-applied, save the top and bottom of\n> the patch as reverse-applied, and then replace the patch with the\n> reverse of that. If the patch vanishes, this does what your patch does\n> right now. If the patch does not vanish, all that remains is the parts\n> that upstream didn't accept. (And as before, if the patch didn't\n> reverse-apply cleanly, assume upstream hasn't accepted it at all yet.)\n\nI don't fully understand this. If a patch reverse-applies cleanly, it\nmeans that it was fully merged upstream. If it wasn't fully merged,\ndirect applying would fail and we should fall back to a three-way merge.\nI'm not sure whether the latter would cause conflicts or not. The\ndisadvantage would be more time spent with trying two types of merges.\n\nAnyway, I'll push the current patch but remain open to improvements. If\nyou get something working with your idea, please post a patch.\n\nCatalin\n"},{"id":"17123","messageId":"4408BE2A.1060601@gmail.com","threadId":"3482","inReplyTo":"20060303142413.GB16456@diana.vm.bytemark.co.uk","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-03-03T22:07:38Z","receivedAt":"2006-03-03T22:07:38Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"Karl Hasselström wrote:\n> On 2006-02-28 22:45:56 +0000, Catalin Marinas wrote:\n>>I attached another patch that should work properly. It also pushes\n>>empty patches on the stack if they were merged upstream (a 'stg\n>>clean' is required to remove them). This is useful for the push\n>>--undo command if you are not happy with the result.\n> \n> It appears to work for me. I still had to fix things up manually when\n> pulling the uncommit patch though, since you had made a minor change\n> in \"uncommit.py\":\n> \n>   Pushing patch \"uncommit\"...Error: File \"stgit/commands/uncommit.py\" added in branches but different\n\nYes, I made some minor modifications (one of them was the copyright).\n\n> Is there a way to make stgit not fall on its face when faced with this\n> situation? Surely it ought to be possible to create a merged file with\n> conflict markers? (I realize this is harder when there is no common\n> ancestor, but these files are 95% identical!)\n\nI've been thinking about this but it's not straight-forward. I tried\nusing /dev/null as the common ancestor but both diff3 and wiggle put the\nwhole file text in the conflict regions. These tools are not smart\nenough to compare the conflict regions and reduce them.\n\nAnother approach would be to have a script that creates the common\nancestor only with the common lines between the two files and pass this\nfile as an argument to diff3. This wouldn't probably be that difficult,\nmaybe some combination of diff and sed and apply the result to one of\nthe files to remove the diff'ed lines.\n\nCatalin\n"},{"id":"17396","messageId":"b0943d9e0603091400o2cd0291h@mail.gmail.com","threadId":"3482","inReplyTo":"20060301155043.GA3706@spearce.org","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-03-09T22:00:25Z","receivedAt":"2006-03-09T22:00:25Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 01/03/06, Shawn Pearce <spearce@spearce.org> wrote:\n> Speaking of making StGIT faster: earlier we were talking about how\n> git-diff|git-apply is faster than a 3 way git-read-tree on large\n> merges when there are many structural changes in the tree due to\n> the smaller number of process spawns required.\n>\n> You might want to take a look at pg--merge-all: This is sort of based\n> on git-merge-recursive, but I've gotten it down to just a handful\n> of process spawns, aside from the stupidity of git-checkout-index.\n\nTrying to implement this, I've just noticed that git-read-tree has a\n--aggressive option which takes care of the file removals. Adding this\noption lowered the pushing time in StGIT from ~2 min to under 2\nseconds (merges between 2.6.14 and the latest kernel). There's\nprobably no need to deal with file removals in pg--merge-all anymore.\n\n--\nCatalin\n"},{"id":"17398","messageId":"7vslpr2ojz.fsf@assigned-by-dhcp.cox.net","threadId":"3482","inReplyTo":"b0943d9e0603091400o2cd0291h@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-09T23:20:16Z","receivedAt":"2006-03-09T23:20:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Catalin Marinas\" <catalin.marinas@gmail.com> writes:\n\n> Trying to implement this, I've just noticed that git-read-tree has a\n> --aggressive option which takes care of the file removals. Adding this\n> option lowered the pushing time in StGIT from ~2 min to under 2\n> seconds (merges between 2.6.14 and the latest kernel). There's\n> probably no need to deal with file removals in pg--merge-all anymore.\n\nYup, it was originally done to improve the performance of\nresolve merge strategy, but I am glad somebody else has found\nuse for it.\n"},{"id":"17428","messageId":"b0943d9e0603100313l37f67f62h@mail.gmail.com","threadId":"3482","inReplyTo":"7vslpr2ojz.fsf@assigned-by-dhcp.cox.net","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-03-10T11:13:41Z","receivedAt":"2006-03-10T11:13:41Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 09/03/06, Junio C Hamano <junkio@cox.net> wrote:\n> \"Catalin Marinas\" <catalin.marinas@gmail.com> writes:\n>\n> > Trying to implement this, I've just noticed that git-read-tree has a\n> > --aggressive option which takes care of the file removals. Adding this\n> > option lowered the pushing time in StGIT from ~2 min to under 2\n> > seconds (merges between 2.6.14 and the latest kernel). There's\n> > probably no need to deal with file removals in pg--merge-all anymore.\n>\n> Yup, it was originally done to improve the performance of\n> resolve merge strategy, but I am glad somebody else has found\n> use for it.\n\nActually, I asked for it about 6 months ago:\n\nhttp://marc.theaimsgroup.com/?l=git&m=112677889118711&w=2\n\nand I got the reply from you :-):\n\nhttp://marc.theaimsgroup.com/?l=git&m=112690084826630&w=2\n\nAnyway, it's good we have it, it saved me some time with implementing\nShawn's merging algorithm.\n\n--\nCatalin\n"},{"id":"17437","messageId":"20060310162322.GB7004@spearce.org","threadId":"3482","inReplyTo":"b0943d9e0603091400o2cd0291h@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-03-10T16:23:22Z","receivedAt":"2006-03-10T16:23:22Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Catalin Marinas <catalin.marinas@gmail.com> wrote:\n> On 01/03/06, Shawn Pearce <spearce@spearce.org> wrote:\n> > Speaking of making StGIT faster: earlier we were talking about how\n> > git-diff|git-apply is faster than a 3 way git-read-tree on large\n> > merges when there are many structural changes in the tree due to\n> > the smaller number of process spawns required.\n> >\n> > You might want to take a look at pg--merge-all: This is sort of based\n> > on git-merge-recursive, but I've gotten it down to just a handful\n> > of process spawns, aside from the stupidity of git-checkout-index.\n> \n> Trying to implement this, I've just noticed that git-read-tree has a\n> --aggressive option which takes care of the file removals. Adding this\n> option lowered the pushing time in StGIT from ~2 min to under 2\n> seconds (merges between 2.6.14 and the latest kernel). There's\n> probably no need to deal with file removals in pg--merge-all anymore.\n\n\nThanks for the heads up.  I'll have to add that in.  In case you\ndidn't notice the list traffic I have added a --stage=all switch to\ngit-checkout-index to grab into temporary files all unmerged stages.\n\nI'm still working on integrating that into pg--merge-all but the\nidea is to save on the fork/exec of git-unpack-file when I get into\nthe diff portion of the merge process.  At least on Cygwin (a place\nwhere I'm really using pg) it will save time as the forks are so\nexpensive there.  Linux users may not see any improvement from it.\n\nI also added --stdin to git-checkout-index but pg--merge-all is\nstill using xargs.  I just haven't had time to convert it over and\npush it up to my public repo.  Hopefully I'll get both of those\ndone this weekend.\n\nI've started to get busy with an Eclipse plugin for GIT so my work\nwith pg is likely going to slow down a little (besides its doing\nmost of what I need at this point).  But the next thing I was going\nto try to add to GIT to boost pg's performance was to integrate\na diff library, so we aren't forking out a diff process for every\nfile we need to extract a diff for.\n\n-- \nShawn.\n"},{"id":"17452","messageId":"7vfylpxyvc.fsf@assigned-by-dhcp.cox.net","threadId":"3482","inReplyTo":"b0943d9e0603100313l37f67f62h@mail.gmail.com","subject":"Re: bug?: stgit creates (unneccessary?) conflicts when pulling","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-11T06:46:15Z","receivedAt":"2006-03-11T06:46:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Catalin Marinas\" <catalin.marinas@gmail.com> writes:\n\n> On 09/03/06, Junio C Hamano <junkio@cox.net> wrote:\n>\n>> Yup, it was originally done to improve the performance of\n>> resolve merge strategy, but I am glad somebody else has found\n>> use for it.\n>\n> Actually, I asked for it about 6 months ago:\n>\n> http://marc.theaimsgroup.com/?l=git&m=112677889118711&w=2\n>\n> and I got the reply from you :-):\n>\n> http://marc.theaimsgroup.com/?l=git&m=112690084826630&w=2\n>\n> Anyway, it's good we have it...\n\nI had this one in mind:\n\n        http://marc.theaimsgroup.com/?t=113874460800001&r=1&w=2\n\nSpecifically, this message:\n\n\thttp://marc.theaimsgroup.com/?l=git&m=113874886615202&w=2\n\nIt seems that this has been an recurring issue.\n"}]}