{"thread":{"id":"9587","subject":"[StGit PATCH 0/6] Use git conflict handling on push","startedAt":"2007-08-20T08:11:57Z","lastAt":"2007-08-23T14:54:51Z","messageCount":18,"participants":["David Kågedal","Junio C Hamano","Uwe Kleine-König","Karl Hasselström","Catalin Marinas"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"51062","messageId":"11875975232619-git-send-email-davidk@lysator.liu.se","threadId":"9587","inReplyTo":null,"subject":"[StGit PATCH 0/6] Use git conflict handling on push","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:11:57Z","receivedAt":"2007-08-20T08:11:57Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"This series of patches updates \"stg push\" to leave conflicts in the\nindex, in the normal git fashion.\n\nThis means that conflict handling and resolution are handled by git\nand not stg, which should make it possible to simplify stg quite a\nbit.  For instance, the 'conflicts' file should go away.\n\nUnfortunately, this patch series isn't complete, since it doesn't\nremove all uses of the stg merge code.  The remaining client of that\ncode is the \"sync\" command, which I have never used, and haven't\nstudied very much.  But if that command is changed somehow, then most\nof the code in gitmergeonefile.py will go simply away. And the\n'conflicts' file will not be used.\n\n\nSee also previous discussions:\n\nhttps://gna.org/task/?5140\nhttp://thread.gmane.org/gmane.comp.version-control.git/48271\n\n-- \nDavid KÃ¥gedal\n"},{"id":"51065","messageId":"1187597523433-git-send-email-davidk@lysator.liu.se","threadId":"9587","inReplyTo":"11875975232619-git-send-email-davidk@lysator.liu.se","subject":"[StGit PATCH 1/6] Split git.merge into two functions","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:11:58Z","receivedAt":"2007-08-20T08:11:58Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"From: David KÃ¥gedal <davidk@lysator.liu.se>\n\nThis only prepares for later simplifications.\n\nSigned-off-by: David KÃ¥gedal <davidk@lysator.liu.se>\n---\n stgit/commands/pick.py |    2 +-\n stgit/git.py           |   86 ++++++++++++++++++++++++++++++++++++++----------\n stgit/stack.py         |    2 +-\n 3 files changed, 70 insertions(+), 20 deletions(-)\n\ndiff --git a/stgit/commands/pick.py b/stgit/commands/pick.py\nindex 27fdf9c..9913e63 100644\n--- a/stgit/commands/pick.py\n+++ b/stgit/commands/pick.py\n@@ -98,7 +98,7 @@ def func(parser, options, args):\n \n         # try a direct git-apply first\n         if not git.apply_diff(bottom, top):\n-            git.merge(bottom, git.get_head(), top, recursive = True)\n+            git.merge_recursive(bottom, git.get_head(), top)\n \n         out.done()\n     elif options.update:\ndiff --git a/stgit/git.py b/stgit/git.py\nindex 72bf889..9d8da5d 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -667,33 +667,83 @@ def apply_diff(rev1, rev2, check_index = True, files = None):\n \n     return True\n \n-def merge(base, head1, head2, recursive = False):\n+stages_re = re.compile('^([0-7]+) ([0-9a-f]{40}) ([1-3])\\t(.*)$', re.S)\n+\n+def merge_recursive(base, head1, head2):\n     \"\"\"Perform a 3-way merge between base, head1 and head2 into the\n     local tree\n     \"\"\"\n     refresh_index()\n \n     err_output = None\n-    if recursive:\n-        # this operation tracks renames but it is slower (used in\n-        # general when pushing or picking patches)\n-        try:\n-            # use _output() to mask the verbose prints of the tool\n-            _output(['git-merge-recursive', base, '--', head1, head2])\n-        except GitException, ex:\n-            err_output = str(ex)\n-            pass\n-    else:\n-        # the fast case where we don't track renames (used when the\n-        # distance between base and heads is small, i.e. folding or\n-        # synchronising patches)\n-        if __run('git-read-tree -u -m --aggressive',\n-                 [base, head1, head2]) != 0:\n-            raise GitException, 'git-read-tree failed (local changes maybe?)'\n+    # this operation tracks renames but it is slower (used in\n+    # general when pushing or picking patches)\n+    try:\n+        # use _output() to mask the verbose prints of the tool\n+        _output(['git-merge-recursive', base, '--', head1, head2])\n+    except GitException, ex:\n+        err_output = str(ex)\n+        pass\n+\n+    # check the index for unmerged entries\n+    files = {}\n+\n+    for line in _output(['git-ls-files', '--unmerged', '--stage', '-z']).split('\\0'):\n+        if not line:\n+            continue\n+\n+        mode, hash, stage, path = stages_re.findall(line)[0]\n+\n+        if not path in files:\n+            files[path] = {}\n+            files[path]['1'] = ('', '')\n+            files[path]['2'] = ('', '')\n+            files[path]['3'] = ('', '')\n+\n+        files[path][stage] = (mode, hash)\n+\n+    if err_output and not files:\n+        # if no unmerged files, there was probably a different type of\n+        # error and we have to abort the merge\n+        raise GitException, err_output\n+\n+    # merge the unmerged files\n+    errors = False\n+    for path in files:\n+        # remove additional files that might be generated for some\n+        # newer versions of GIT\n+        for suffix in [base, head1, head2]:\n+            if not suffix:\n+                continue\n+            fname = path + '~' + suffix\n+            if os.path.exists(fname):\n+                os.remove(fname)\n+\n+        stages = files[path]\n+        if gitmergeonefile.merge(stages['1'][1], stages['2'][1],\n+                                 stages['3'][1], path, stages['1'][0],\n+                                 stages['2'][0], stages['3'][0]) != 0:\n+            errors = True\n+\n+    if errors:\n+        raise GitException, 'GIT index merging failed (possible conflicts)'\n+\n+def merge(base, head1, head2):\n+    \"\"\"Perform a 3-way merge between base, head1 and head2 into the\n+    local tree\n+    \"\"\"\n+    refresh_index()\n+\n+    err_output = None\n+    # the fast case where we don't track renames (used when the\n+    # distance between base and heads is small, i.e. folding or\n+    # synchronising patches)\n+    if __run('git-read-tree -u -m --aggressive',\n+             [base, head1, head2]) != 0:\n+        raise GitException, 'git-read-tree failed (local changes maybe?)'\n \n     # check the index for unmerged entries\n     files = {}\n-    stages_re = re.compile('^([0-7]+) ([0-9a-f]{40}) ([1-3])\\t(.*)$', re.S)\n \n     for line in _output(['git-ls-files', '--unmerged', '--stage', '-z']).split('\\0'):\n         if not line:\ndiff --git a/stgit/stack.py b/stgit/stack.py\nindex dbd7ea4..8b77943 100644\n--- a/stgit/stack.py\n+++ b/stgit/stack.py\n@@ -1061,7 +1061,7 @@ class Series(PatchSet):\n \n                 # merge can fail but the patch needs to be pushed\n                 try:\n-                    git.merge(bottom, head, top, recursive = True)\n+                    git.merge_recursive(bottom, head, top)\n                 except git.GitException, ex:\n                     out.error('The merge failed during \"push\".',\n                               'Use \"refresh\" after fixing the conflicts or'\n-- \n1.5.3.rc3.119.g1812\n"},{"id":"51064","messageId":"11875975232734-git-send-email-davidk@lysator.liu.se","threadId":"9587","inReplyTo":"1187597523433-git-send-email-davidk@lysator.liu.se","subject":"[StGit PATCH 2/6] Don't try to merge files that merge-recursive already merged","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:11:59Z","receivedAt":"2007-08-20T08:11:59Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"From: David KÃ¥gedal <davidk@lysator.liu.se>\n\nThis avoid duplicating work, but also changes the resulting index state\nso that the conflicts are left in the index in the three stages.\n\nSigned-off-by: David KÃ¥gedal <davidk@lysator.liu.se>\n---\n stgit/git.py |   20 +-------------------\n 1 files changed, 1 insertions(+), 19 deletions(-)\n\ndiff --git a/stgit/git.py b/stgit/git.py\nindex 9d8da5d..5e1548c 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -707,25 +707,7 @@ def merge_recursive(base, head1, head2):\n         # error and we have to abort the merge\n         raise GitException, err_output\n \n-    # merge the unmerged files\n-    errors = False\n-    for path in files:\n-        # remove additional files that might be generated for some\n-        # newer versions of GIT\n-        for suffix in [base, head1, head2]:\n-            if not suffix:\n-                continue\n-            fname = path + '~' + suffix\n-            if os.path.exists(fname):\n-                os.remove(fname)\n-\n-        stages = files[path]\n-        if gitmergeonefile.merge(stages['1'][1], stages['2'][1],\n-                                 stages['3'][1], path, stages['1'][0],\n-                                 stages['2'][0], stages['3'][0]) != 0:\n-            errors = True\n-\n-    if errors:\n+    if files:\n         raise GitException, 'GIT index merging failed (possible conflicts)'\n \n def merge(base, head1, head2):\n-- \n1.5.3.rc3.119.g1812\n"},{"id":"51063","messageId":"11875975232606-git-send-email-davidk@lysator.liu.se","threadId":"9587","inReplyTo":"11875975232734-git-send-email-davidk@lysator.liu.se","subject":"[StGit PATCH 3/6] Don't touch state after conflict in push","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:12:00Z","receivedAt":"2007-08-20T08:12:00Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"From: David KÃ¥gedal <davidk@lysator.liu.se>\n\nThis leaves the index and working tree in the state that merge-recursive\nleft it, with unmerged files in different stages, and the non-conflicting\nchanges in the index.\n\nSigned-off-by: David KÃ¥gedal <davidk@lysator.liu.se>\n---\n stgit/stack.py |   17 ++++++++++++-----\n 1 files changed, 12 insertions(+), 5 deletions(-)\n\ndiff --git a/stgit/stack.py b/stgit/stack.py\nindex 8b77943..0e43f75 100644\n--- a/stgit/stack.py\n+++ b/stgit/stack.py\n@@ -728,6 +728,7 @@ class Series(PatchSet):\n         config.unset(self.format_version_key())\n \n     def refresh_patch(self, files = None, message = None, edit = False,\n+                      empty = False,\n                       show_patch = False,\n                       cache_update = True,\n                       author_name = None, author_email = None,\n@@ -777,9 +778,16 @@ class Series(PatchSet):\n \n         bottom = patch.get_bottom()\n \n+        if empty:\n+            tree_id = git.get_commit(bottom).get_tree()\n+        else:\n+            tree_id = None\n+\n         commit_id = git.commit(files = files,\n                                message = descr, parents = [bottom],\n                                cache_update = cache_update,\n+                               tree_id = tree_id,\n+                               set_head = True,\n                                allowempty = True,\n                                author_name = author_name,\n                                author_email = author_email,\n@@ -1083,11 +1091,10 @@ class Series(PatchSet):\n                     log = 'push'\n                 self.refresh_patch(cache_update = False, log = log)\n             else:\n-                # we store the correctly merged files only for\n-                # tracking the conflict history. Note that the\n-                # git.merge() operations should always leave the index\n-                # in a valid state (i.e. only stage 0 files)\n-                self.refresh_patch(cache_update = False, log = 'push(c)')\n+                # we make the patch empty, with the merged state in\n+                # the working tree.\n+                self.refresh_patch(cache_update = False, empty = True,\n+                                   log = 'push(c)')\n                 raise StackException, str(ex)\n \n         return modified\n-- \n1.5.3.rc3.119.g1812\n"},{"id":"51068","messageId":"1187597523884-git-send-email-davidk@lysator.liu.se","threadId":"9587","inReplyTo":"11875975232606-git-send-email-davidk@lysator.liu.se","subject":"[StGit PATCH 4/6] Added a test case to check what happens when push finds a conflict","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:12:01Z","receivedAt":"2007-08-20T08:12:01Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"From: David KÃ¥gedal <davidk@lysator.liu.se>\n\n\nSigned-off-by: David KÃ¥gedal <davidk@lysator.liu.se>\n---\n t/t1203-push-conflict.sh |   64 ++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 64 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t1203-push-conflict.sh b/t/t1203-push-conflict.sh\nnew file mode 100755\nindex 0000000..57fb477\n--- /dev/null\n+++ b/t/t1203-push-conflict.sh\n@@ -0,0 +1,64 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2006 David KÃ¥gedal\n+#\n+\n+test_description='Exercise push conflicts.\n+\n+Test that the index has no modifications after a push with conflicts.\n+'\n+\n+. ./test-lib.sh\n+\n+test_expect_success \\\n+\t'Initialize the StGIT repository' \\\n+\t'stg init\n+'\n+\n+test_expect_success \\\n+\t'Create the first patch' \\\n+\t'\n+\tstg new foo -m foo &&\n+\techo foo > test &&\n+\techo fie > test2 &&\n+\tstg add test test2 &&\n+\tstg refresh &&\n+        stg pop\n+\t'\n+\n+test_expect_success \\\n+\t'Create the second patch' \\\n+\t'\n+\tstg new bar -m bar &&\n+\techo bar > test &&\n+\tstg add test &&\n+\tstg refresh\n+\t'\n+\n+test_expect_failure \\\n+\t'Push the first patch with conflict' \\\n+\t'\n+\tstg push foo\n+\t'\n+\n+test_expect_failure \\\n+\t'Show the, now empty, first patch' \\\n+\t'\n+\tstg show foo | grep -q -e \"^diff \"\n+\t'\n+\n+test_expect_success \\\n+\t'Check that the index has the non-conflict updates' \\\n+\t'\n+\tgit diff --cached --stat | grep -q -e \"^ test2 | *1 \"\n+\t'\n+\n+test_expect_success \\\n+\t'Resolve the conflict' \\\n+\t'\n+\techo resolved > test &&\n+\tgit add test &&\n+\tstg refresh\n+\t'\n+\n+test_done\n-- \n1.5.3.rc3.119.g1812\n"},{"id":"51066","messageId":"11875975233747-git-send-email-davidk@lysator.liu.se","threadId":"9587","inReplyTo":"1187597523884-git-send-email-davidk@lysator.liu.se","subject":"[StGit PATCH 5/6] Simplify merge_recursive","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:12:02Z","receivedAt":"2007-08-20T08:12:02Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"From: David KÃ¥gedal <davidk@lysator.liu.se>\n\nListing the unmerged files is unnecessary, since the information\nisn't really used anyway. Just note if the merge failed or succeeded.\n\nSigned-off-by: David KÃ¥gedal <davidk@lysator.liu.se>\n---\n stgit/git.py |   33 ++-------------------------------\n 1 files changed, 2 insertions(+), 31 deletions(-)\n\ndiff --git a/stgit/git.py b/stgit/git.py\nindex 5e1548c..63798bd 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -675,39 +675,10 @@ def merge_recursive(base, head1, head2):\n     \"\"\"\n     refresh_index()\n \n-    err_output = None\n-    # this operation tracks renames but it is slower (used in\n-    # general when pushing or picking patches)\n+    # use _output() to mask the verbose prints of the tool\n     try:\n-        # use _output() to mask the verbose prints of the tool\n         _output(['git-merge-recursive', base, '--', head1, head2])\n-    except GitException, ex:\n-        err_output = str(ex)\n-        pass\n-\n-    # check the index for unmerged entries\n-    files = {}\n-\n-    for line in _output(['git-ls-files', '--unmerged', '--stage', '-z']).split('\\0'):\n-        if not line:\n-            continue\n-\n-        mode, hash, stage, path = stages_re.findall(line)[0]\n-\n-        if not path in files:\n-            files[path] = {}\n-            files[path]['1'] = ('', '')\n-            files[path]['2'] = ('', '')\n-            files[path]['3'] = ('', '')\n-\n-        files[path][stage] = (mode, hash)\n-\n-    if err_output and not files:\n-        # if no unmerged files, there was probably a different type of\n-        # error and we have to abort the merge\n-        raise GitException, err_output\n-\n-    if files:\n+    except GitException:\n         raise GitException, 'GIT index merging failed (possible conflicts)'\n \n def merge(base, head1, head2):\n-- \n1.5.3.rc3.119.g1812\n"},{"id":"51067","messageId":"11875975231887-git-send-email-davidk@lysator.liu.se","threadId":"9587","inReplyTo":"11875975233747-git-send-email-davidk@lysator.liu.se","subject":"[StGit PATCH 6/6] Use the output from merge-recursive to list conflicts","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:12:03Z","receivedAt":"2007-08-20T08:12:03Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"From: David KÃ¥gedal <davidk@lysator.liu.se>\n\nmerge-recursive already has useful information about what the conflicts\nwere, so we reuse that when pushing.\n\nSigned-off-by: David KÃ¥gedal <davidk@lysator.liu.se>\n---\n stgit/git.py   |   27 +++++++++++++++++++++------\n stgit/stack.py |    2 ++\n 2 files changed, 23 insertions(+), 6 deletions(-)\n\ndiff --git a/stgit/git.py b/stgit/git.py\nindex 63798bd..59423ab 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -30,7 +30,14 @@ from sets import Set\n class GitException(Exception):\n     pass\n \n-\n+class GitConflictException(GitException):\n+    def __init__(self, conflicts):\n+        GitException.__init__(self)\n+        self.conflicts = conflicts\n+    def __str__(self):\n+        return \"%d conflicts\" % len(self.conflicts)\n+    def list(self):\n+        out.info(*self.conflicts)\n \n #\n # Classes\n@@ -675,11 +682,19 @@ def merge_recursive(base, head1, head2):\n     \"\"\"\n     refresh_index()\n \n-    # use _output() to mask the verbose prints of the tool\n-    try:\n-        _output(['git-merge-recursive', base, '--', head1, head2])\n-    except GitException:\n-        raise GitException, 'GIT index merging failed (possible conflicts)'\n+    # Duplicate _output(), since we need the exit status\n+    p=popen2.Popen3(['git-merge-recursive', base, '--', head1, head2], True)\n+    output = p.fromchild.readlines()\n+    st = p.wait() >> 8\n+    if st == 0:\n+        # No problems\n+        return\n+    elif st == 1:\n+        # There were conflicts\n+        conflicts = [l.strip() for l in output if l.startswith('CONFLICT')]\n+        raise GitConflictException(conflicts)\n+    else:\n+        raise GitException, 'git-merge-recursive failed (%s)' % (p.childerr.read().strip())\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 0e43f75..3b06ca5 100644\n--- a/stgit/stack.py\n+++ b/stgit/stack.py\n@@ -1070,6 +1070,8 @@ class Series(PatchSet):\n                 # merge can fail but the patch needs to be pushed\n                 try:\n                     git.merge_recursive(bottom, head, top)\n+                except git.GitConflictException, ex:\n+                    ex.list()\n                 except git.GitException, ex:\n                     out.error('The merge failed during \"push\".',\n                               'Use \"refresh\" after fixing the conflicts or'\n-- \n1.5.3.rc3.119.g1812\n"},{"id":"51071","messageId":"87odh2d1q7.fsf@morpheus.local","threadId":"9587","inReplyTo":"1187597523433-git-send-email-davidk@lysator.liu.se","subject":"Re: [StGit PATCH 1/6] Split git.merge into two functions","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-20T08:55:28Z","receivedAt":"2007-08-20T08:55:28Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"David Kågedal <davidk@lysator.liu.se> writes:\n\n> From: David KÃ¥gedal <davidk@lysator.liu.se>\n\nIt seems that git-send-email didn't like me for some reason.  Double\nUTF-8 encoding is not very pretty.\n\nI also got a number of these when running it:\n\nW: unable to extract a valid address from: David KÃ¥gedal <davidk@lysator.liu.se>\nW: unable to extract a valid address from: David KÃ¥gedal <davidk@lysator.liu.se>\n\n(the above was written in my latin1 xterm, so it wasn't double-encoded\nthere)\n\nIs there a way to make send-email not add a \"From:\" header to the body\nof the message?  The header already had the correct \"From:\" line.\n\n-- \nDavid Kågedal\n"},{"id":"51139","messageId":"7vejhxrcgl.fsf@gitster.siamese.dyndns.org","threadId":"9587","inReplyTo":"87odh2d1q7.fsf@morpheus.local","subject":"Re: [StGit PATCH 1/6] Split git.merge into two functions","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-08-20T23:52:10Z","receivedAt":"2007-08-20T23:52:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"David Kågedal <davidk@lysator.liu.se> writes:\n\n> David Kågedal <davidk@lysator.liu.se> writes:\n>\n> It seems that git-send-email didn't like me for some reason.  Double\n> UTF-8 encoding is not very pretty.\n\nI believe Uwe (CC'ed) had a few patches to deal with this area.\nDo they help?\n"},{"id":"51195","messageId":"20070821193504.GA20823@informatik.uni-freiburg.de","threadId":"9587","inReplyTo":"7vejhxrcgl.fsf@gitster.siamese.dyndns.org","subject":"Re: [StGit PATCH 1/6] Split git.merge into two functions","fromName":"Uwe Kleine-König","fromEmail":"ukleinek@informatik.uni-freiburg.de","sentAt":"2007-08-21T19:35:05Z","receivedAt":"2007-08-21T19:35:05Z","isPatch":true,"sender":{"key":"u.kleine-koenig@pengutronix.de","avatar":"https://gravatar.com/avatar/354b5e3ceb2806a2f1e1e382ac29ddbdad18288654da62b61eb13583a857eee7?d=mp&s=160"},"body":"Hello David,\n\nJunio C Hamano wrote:\n> David Kågedal <davidk@lysator.liu.se> writes:\n> \n> > David Kågedal <davidk@lysator.liu.se> writes:\n> >\n> > It seems that git-send-email didn't like me for some reason.  Double\n> > UTF-8 encoding is not very pretty.\n> \n> I believe Uwe (CC'ed) had a few patches to deal with this area.\n> Do they help?\nMy patches are already in next, the relevant being probably\nv1.5.3-rc4-38-g94638f8.\n\nDavid, can you retry with a more recent version that includes that\npatch?\n\nAnd IIRC send-email expects the patch being encoded in UTF-8, but I'm\nnot sure.  If you could send me the patches you sent as a tar-ball or\nsomething similar, I can look into it.\n\nBest regards\nUwe\n\n-- \nUwe Kleine-König\n\n$ dc << EOF\n[d1-d1<a]sa99d1<a1[rdn555760928P*pz1<a]salax\nEOF\n"},{"id":"51229","messageId":"20070822091757.GA30748@diana.vm.bytemark.co.uk","threadId":"9587","inReplyTo":"11875975232619-git-send-email-davidk@lysator.liu.se","subject":"Re: [StGit PATCH 0/6] Use git conflict handling on push","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-08-22T09:17:57Z","receivedAt":"2007-08-22T09:17:57Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-08-20 10:11:57 +0200, David Kågedal wrote:\n\n> This series of patches updates \"stg push\" to leave conflicts in the\n> index, in the normal git fashion.\n\nGreat initiative! This will make stg conceptually simpler to anyone\nwho already knows git (which ought to be a large fraction of the user\nbase), _and_ get rid of a lot of complicated code.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"51230","messageId":"20070822092152.GB30748@diana.vm.bytemark.co.uk","threadId":"9587","inReplyTo":"11875975232734-git-send-email-davidk@lysator.liu.se","subject":"Re: [StGit PATCH 2/6] Don't try to merge files that merge-recursive already merged","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-08-22T09:21:52Z","receivedAt":"2007-08-22T09:21:52Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-08-20 10:11:59 +0200, David Kågedal wrote:\n\n> This avoid duplicating work, but also changes the resulting index\n> state so that the conflicts are left in the index in the three\n> stages.\n\nAfter this patch, t1400-patch-history fails:\n\n*   ok 1: Initialize the StGIT repository\n*   ok 2: Create the first patch\n*   ok 3: Create the second patch\n*   ok 4: Check the \"new\" and \"refresh\" logs\n*   ok 5: Check the log annotation\n*   ok 6: Check the \"push\" log\n*   ok 7: Check the \"push(f)\" log\n*   ok 8: Check the \"push(m)\" log\n* FAIL 9: Check the \"push(c)\" log\n\n                echo bar > test && stg refresh &&\n                stg pop &&\n                echo foo > test && stg refresh &&\n                ! stg push &&\n                stg log --full | grep -q -e \"^push(c) \"\n\n*   ok 10: Check the push \"undo\" log\n*   ok 11: Check the refresh \"undo\" log\n* failed 1 among 11 test(s)\n\nI'll see if I can figure out what's wrong.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"51231","messageId":"87sl6bewqo.fsf@morpheus.local","threadId":"9587","inReplyTo":"20070822092152.GB30748@diana.vm.bytemark.co.uk","subject":"Re: [StGit PATCH 2/6] Don't try to merge files that merge-recursive already merged","fromName":"David Kågedal","fromEmail":"davidk@lysator.liu.se","sentAt":"2007-08-22T09:37:03Z","receivedAt":"2007-08-22T09:37:03Z","isPatch":true,"sender":{"key":"davidk@lysator.liu.se","avatar":"https://avatars.githubusercontent.com/u/60530?v=4"},"body":"Karl Hasselström <kha@treskal.com> writes:\n\n> On 2007-08-20 10:11:59 +0200, David Kågedal wrote:\n>\n>> This avoid duplicating work, but also changes the resulting index\n>> state so that the conflicts are left in the index in the three\n>> stages.\n>\n> After this patch, t1400-patch-history fails:\n\nI think that the push(c) commits will never happen with my patches, so\nthe test case needs an update.\n\n> *   ok 1: Initialize the StGIT repository\n> *   ok 2: Create the first patch\n> *   ok 3: Create the second patch\n> *   ok 4: Check the \"new\" and \"refresh\" logs\n> *   ok 5: Check the log annotation\n> *   ok 6: Check the \"push\" log\n> *   ok 7: Check the \"push(f)\" log\n> *   ok 8: Check the \"push(m)\" log\n> * FAIL 9: Check the \"push(c)\" log\n>\n>                 echo bar > test && stg refresh &&\n>                 stg pop &&\n>                 echo foo > test && stg refresh &&\n>                 ! stg push &&\n>                 stg log --full | grep -q -e \"^push(c) \"\n>\n> *   ok 10: Check the push \"undo\" log\n> *   ok 11: Check the refresh \"undo\" log\n> * failed 1 among 11 test(s)\n>\n> I'll see if I can figure out what's wrong.\n\n-- \nDavid Kågedal\n"},{"id":"51232","messageId":"20070822094413.GC30748@diana.vm.bytemark.co.uk","threadId":"9587","inReplyTo":"87sl6bewqo.fsf@morpheus.local","subject":"Re: [StGit PATCH 2/6] Don't try to merge files that merge-recursive already merged","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-08-22T09:44:13Z","receivedAt":"2007-08-22T09:44:13Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-08-22 11:37:03 +0200, David Kågedal wrote:\n\n> Karl Hasselström <kha@treskal.com> writes:\n>\n> > On 2007-08-20 10:11:59 +0200, David Kågedal wrote:\n> >\n> > > This avoid duplicating work, but also changes the resulting\n> > > index state so that the conflicts are left in the index in the\n> > > three stages.\n> >\n> > After this patch, t1400-patch-history fails:\n>\n> I think that the push(c) commits will never happen with my patches,\n> so the test case needs an update.\n\nActually, the failure vanishes once the next patch in the series is\napplied. I thought this was a good thing, but if they're never\nsupposed to happen, maybe the test is still broken, just not in a way\nthat's detected?\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"51233","messageId":"20070822095954.GE30748@diana.vm.bytemark.co.uk","threadId":"9587","inReplyTo":"20070822094413.GC30748@diana.vm.bytemark.co.uk","subject":"Re: [StGit PATCH 2/6] Don't try to merge files that merge-recursive already merged","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-08-22T09:59:54Z","receivedAt":"2007-08-22T09:59:54Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"On 2007-08-22 11:44:13 +0200, Karl Hasselström wrote:\n\n> On 2007-08-22 11:37:03 +0200, David Kågedal wrote:\n>\n> > I think that the push(c) commits will never happen with my\n> > patches, so the test case needs an update.\n>\n> Actually, the failure vanishes once the next patch in the series is\n> applied. I thought this was a good thing, but if they're never\n> supposed to happen, maybe the test is still broken, just not in a\n> way that's detected?\n\nNo, after path 2 we don't get a push(c) entry, and the test fails, but\nafter patch 3 we get it again and the test succeeds.\n\nLooking at the code (the string \"push(c)\" occurs exactly once, so it's\neasy to find), it seems the log stuff continues to work as expected\nafter patch 3: it writes a \"push(c)\" entry when the patch becomes\nempty due to conflicts, and its entire contents are dumped in the wd\n(or the index+wd with your patches). So it is just patch 2 that needs\nfixing -- and I suspect the fix might be to merge it with patch 3.\n\n-- \nKarl Hasselström, kha@treskal.com\n      www.treskal.com/kalle\n"},{"id":"51235","messageId":"7v7innkhqi.fsf@gitster.siamese.dyndns.org","threadId":"9587","inReplyTo":"20070821193504.GA20823@informatik.uni-freiburg.de","subject":"Re: [StGit PATCH 1/6] Split git.merge into two functions","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2007-08-22T10:04:37Z","receivedAt":"2007-08-22T10:04:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Uwe Kleine-König  <ukleinek@informatik.uni-freiburg.de> writes:\n\n> Hello David,\n>\n> Junio C Hamano wrote:\n>> David Kågedal <davidk@lysator.liu.se> writes:\n>> \n>> > David Kågedal <davidk@lysator.liu.se> writes:\n>> >\n>> > It seems that git-send-email didn't like me for some reason.  Double\n>> > UTF-8 encoding is not very pretty.\n>> \n>> I believe Uwe (CC'ed) had a few patches to deal with this area.\n>> Do they help?\n>\n> My patches are already in next, the relevant being probably\n> v1.5.3-rc4-38-g94638f8.\n\nIt is in 'master' and in -rc5/-rc6.\n"},{"id":"51239","messageId":"20070822102902.30714.47437.stgit@yoghurt","threadId":"9587","inReplyTo":"20070822095954.GE30748@diana.vm.bytemark.co.uk","subject":"[StGIT PATCH] Leave working dir and index alone after failed (conflicting) push","fromName":"Karl Hasselström","fromEmail":"kha@treskal.com","sentAt":"2007-08-22T10:29:48Z","receivedAt":"2007-08-22T10:29:48Z","isPatch":true,"sender":{"key":"kha@treskal.com","avatar":"https://gravatar.com/avatar/f0120c734b5279b345075a28521e1ac66acb20c9913ffe9bf6ae97e53f7f3f13?d=mp&s=160"},"body":"From: David Kågedal <davidk@lysator.liu.se>\n\nThis leaves the index and working tree in the state that merge-recursive\nleft it, with unmerged files in different stages, and the non-conflicting\nchanges in the index.\n\nSigned-off-by: David Kågedal <davidk@lysator.liu.se>\nSigned-off-by: Karl Hasselström <kha@treskal.com>\n\n---\n\nThis is David's patch 2 and 3 clumped together, so that there is no\nintermediate stage where the test suite fails.\n\n stgit/git.py   |   20 +-------------------\n stgit/stack.py |   18 +++++++++++++-----\n 2 files changed, 14 insertions(+), 24 deletions(-)\n\ndiff --git a/stgit/git.py b/stgit/git.py\nindex 170c5d1..676314a 100644\n--- a/stgit/git.py\n+++ b/stgit/git.py\n@@ -723,25 +723,7 @@ def merge_recursive(base, head1, head2):\n         # error and we have to abort the merge\n         raise GitException, err_output\n \n-    # merge the unmerged files\n-    errors = False\n-    for path in files:\n-        # remove additional files that might be generated for some\n-        # newer versions of GIT\n-        for suffix in [base, head1, head2]:\n-            if not suffix:\n-                continue\n-            fname = path + '~' + suffix\n-            if os.path.exists(fname):\n-                os.remove(fname)\n-\n-        stages = files[path]\n-        if gitmergeonefile.merge(stages['1'][1], stages['2'][1],\n-                                 stages['3'][1], path, stages['1'][0],\n-                                 stages['2'][0], stages['3'][0]) != 0:\n-            errors = True\n-\n-    if errors:\n+    if files:\n         raise GitException, 'GIT index merging failed (possible conflicts)'\n \n def merge(base, head1, head2):\ndiff --git a/stgit/stack.py b/stgit/stack.py\nindex 95f20f1..123efac 100644\n--- a/stgit/stack.py\n+++ b/stgit/stack.py\n@@ -732,6 +732,7 @@ class Series(PatchSet):\n         config.unset(self.format_version_key())\n \n     def refresh_patch(self, files = None, message = None, edit = False,\n+                      empty = False,\n                       show_patch = False,\n                       cache_update = True,\n                       author_name = None, author_email = None,\n@@ -781,9 +782,16 @@ class Series(PatchSet):\n \n         bottom = patch.get_bottom()\n \n+        if empty:\n+            tree_id = git.get_commit(bottom).get_tree()\n+        else:\n+            tree_id = None\n+\n         commit_id = git.commit(files = files,\n                                message = descr, parents = [bottom],\n                                cache_update = cache_update,\n+                               tree_id = tree_id,\n+                               set_head = True,\n                                allowempty = True,\n                                author_name = author_name,\n                                author_email = author_email,\n@@ -1086,11 +1094,11 @@ class Series(PatchSet):\n                     log = 'push'\n                 self.refresh_patch(cache_update = False, log = log)\n             else:\n-                # we store the correctly merged files only for\n-                # tracking the conflict history. Note that the\n-                # git.merge() operations should always leave the index\n-                # in a valid state (i.e. only stage 0 files)\n-                self.refresh_patch(cache_update = False, log = 'push(c)')\n+                # We make the patch empty, with the merged state in\n+                # the working tree and index just like after a failed\n+                # git merge.\n+                self.refresh_patch(cache_update = False, empty = True,\n+                                   log = 'push(c)')\n                 raise StackException, str(ex)\n \n         return modified\n"},{"id":"51374","messageId":"b0943d9e0708230754r533f7749l63b5e2ba9a5dcfe8@mail.gmail.com","threadId":"9587","inReplyTo":"11875975232619-git-send-email-davidk@lysator.liu.se","subject":"Re: [StGit PATCH 0/6] Use git conflict handling on push","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2007-08-23T14:54:51Z","receivedAt":"2007-08-23T14:54:51Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"On 20/08/07, David Kågedal <davidk@lysator.liu.se> wrote:\n> This series of patches updates \"stg push\" to leave conflicts in the\n> index, in the normal git fashion.\n\nThanks for this series. I'll give it a try (importing it from the kha\nbranch as it is easier) and check other issues it might break.\n\n> This means that conflict handling and resolution are handled by git\n> and not stg, which should make it possible to simplify stg quite a\n> bit.  For instance, the 'conflicts' file should go away.\n\nYes, indeed.\n\n> Unfortunately, this patch series isn't complete, since it doesn't\n> remove all uses of the stg merge code.  The remaining client of that\n> code is the \"sync\" command, which I have never used, and haven't\n> studied very much.  But if that command is changed somehow, then most\n> of the code in gitmergeonefile.py will go simply away.\n\nI still like to keep the interactive merging from that file.\n\n> https://gna.org/task/?5140\n\nBTW, would you like to be added as a project member at gna.org/projects/stgit?\n\nRegards.\n\n-- \nCatalin\n"}]}