From: "Catalin Marinas" <catalin.marinas@gmail.com>
To: "Karl Hasselström" <kha@treskal.com>
Cc: git <git@vger.kernel.org>
Subject: Re: bug?: stgit creates (unneccessary?) conflicts when pulling
Date: Tue, 28 Feb 2006 15:00:22 +0000 [thread overview]
Message-ID: <b0943d9e0602280700p132c6da2v@mail.gmail.com> (raw)
In-Reply-To: <44037A5C.6080409@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 833 bytes --]
On 27/02/06, Catalin Marinas <catalin.marinas@gmail.com> wrote:
> An idea (untested, I don't even know whether it's feasible) would be to
> check which patches were merged by reverse-applying them starting with
> the last. In this situation, all the merged patches should just revert
> their changes. You only need to do a git-diff between the bottom and the
> top of the patch and git-apply the output (maybe without even modifying
> the tree). If this operation succeeds, the patch was integrated and you
> don't even need to push it.
I tried some simple tests with the idea above. I attached a patch if
you'd like to try (I won't push it to the main StGIT repository yet.
For safety reasons, it only skips the merged patches when pushing
them. A future version could simply delete the merged patches.
--
Catalin
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: merged-test.diff --]
[-- Type: text/x-patch; name="merged-test.diff", Size: 5189 bytes --]
Add a merged upstream test for pull and push
From: Catalin Marinas <catalin.marinas@gmail.com>
This patch adds the --merged option to both pull and push commands. With
this option, these commands will first try to check which patches were
merged upstream by reverse-applying them in reverse order. This should
solve the situation where several patches modify the same line in a file.
Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
---
stgit/commands/pull.py | 20 +++++++++++++++++++-
stgit/commands/push.py | 17 ++++++++++++++++-
stgit/git.py | 12 +++++++++---
stgit/stack.py | 20 ++++++++++++++++++++
4 files changed, 64 insertions(+), 5 deletions(-)
diff --git a/stgit/commands/pull.py b/stgit/commands/pull.py
index 843b579..5d75530 100644
--- a/stgit/commands/pull.py
+++ b/stgit/commands/pull.py
@@ -39,6 +39,9 @@ format."""
options = [make_option('-n', '--nopush',
help = 'do not push the patches back after pulling',
+ action = 'store_true'),
+ make_option('-m', '--merged',
+ help = 'check for patches merged upstream (slower)',
action = 'store_true')]
def func(parser, options, args):
@@ -77,12 +80,27 @@ def func(parser, options, args):
# push the patches back
if options.nopush:
applied = []
+
+ # check for patches merged upstream
+ if options.merged:
+ merged = crt_series.merged_patches(patches)
+ else:
+ merged = []
+
for p in applied:
+ if p in merged:
+ print 'Patch "%s" merged upstream' % p
+ continue
+
print 'Pushing patch "%s"...' % p,
sys.stdout.flush()
- crt_series.push_patch(p)
+
+ modified = crt_series.push_patch(p)
+
if crt_series.empty_patch(p):
print 'done (empty patch)'
+ elif modified:
+ print 'done (modified)'
else:
print 'done'
diff --git a/stgit/commands/push.py b/stgit/commands/push.py
index 9924a78..72b2663 100644
--- a/stgit/commands/push.py
+++ b/stgit/commands/push.py
@@ -49,6 +49,9 @@ options = [make_option('-a', '--all',
make_option('--reverse',
help = 'push the patches in reverse order',
action = 'store_true'),
+ make_option('-m', '--merged',
+ help = 'check for patches merged upstream (slower)',
+ action = 'store_true'),
make_option('--undo',
help = 'undo the last push operation',
action = 'store_true')]
@@ -134,9 +137,21 @@ def func(parser, options, args):
elif forwarded == 1:
print 'Fast-forwarded patch "%s"' % patches[0]
- for p in patches[forwarded:]:
+ patches = patches[forwarded:]
+
+ # check for patches merged upstream
+ if options.merged:
+ merged = crt_series.merged_patches(patches)
+ else:
+ merged = []
+
+ for p in patches:
is_patch_appliable(p)
+ if p in merged:
+ print 'Patch "%s" merged upstream' % p
+ continue
+
print 'Pushing patch "%s"...' % p,
sys.stdout.flush()
diff --git a/stgit/git.py b/stgit/git.py
index 016bc3a..66b8612 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -462,14 +462,20 @@ def commit(message, files = None, parent
return commit_id
-def apply_diff(rev1, rev2):
+def apply_diff(rev1, rev2, check_index = True):
"""Apply the diff between rev1 and rev2 onto the current
index. This function doesn't need to raise an exception since it
is only used for fast-pushing a patch. If this operation fails,
the pushing would fall back to the three-way merge.
"""
- return os.system('git-diff-tree -p %s %s | git-apply --index 2> /dev/null'
- % (rev1, rev2)) == 0
+ if check_index:
+ index_opt = '--index'
+ else:
+ index_opt = ''
+ cmd = 'git-diff-tree -p %s %s | git-apply %s 2> /dev/null' \
+ % (rev1, rev2, index_opt)
+
+ return os.system(cmd) == 0
def merge(base, head1, head2):
"""Perform a 3-way merge between base, head1 and head2 into the
diff --git a/stgit/stack.py b/stgit/stack.py
index e1c55f0..9d5f043 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -780,6 +780,26 @@ class Series:
return forwarded
+ def merged_patches(self, names):
+ """Test which patches were merged upstream by reverse-applying
+ them in reverse order. The function returns the list of
+ patches detected to have been applied. The state of the tree
+ is restored to the original one
+ """
+ patches = [Patch(name, self.__patch_dir, self.__refs_dir)
+ for name in names]
+ patches.reverse()
+
+ merged = []
+ for p in patches:
+ if git.apply_diff(p.get_top(), p.get_bottom(), False):
+ merged.append(p.get_name())
+ merged.reverse()
+
+ git.reset()
+
+ return merged
+
def push_patch(self, name):
"""Pushes a patch on the stack
"""
next prev parent reply other threads:[~2006-02-28 15:00 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-27 20:42 bug?: stgit creates (unneccessary?) conflicts when pulling Karl Hasselström
2006-02-27 21:45 ` Sam Vilain
2006-02-27 22:17 ` Catalin Marinas
2006-02-28 15:00 ` Catalin Marinas [this message]
2006-02-28 18:53 ` Catalin Marinas
2006-02-28 22:45 ` Catalin Marinas
2006-03-01 17:39 ` Chuck Lever
2006-03-01 17:53 ` Catalin Marinas
2006-03-03 14:13 ` Karl Hasselström
2006-03-03 21:57 ` Catalin Marinas
2006-03-03 14:24 ` Karl Hasselström
2006-03-03 22:07 ` Catalin Marinas
2006-02-27 22:26 ` Shawn Pearce
2006-03-01 10:59 ` Catalin Marinas
2006-03-01 14:51 ` Shawn Pearce
2006-03-01 15:08 ` Catalin Marinas
2006-03-01 15:50 ` Shawn Pearce
2006-03-09 22:00 ` Catalin Marinas
2006-03-09 23:20 ` Junio C Hamano
2006-03-10 11:13 ` Catalin Marinas
2006-03-11 6:46 ` Junio C Hamano
2006-03-10 16:23 ` Shawn Pearce
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=b0943d9e0602280700p132c6da2v@mail.gmail.com \
--to=catalin.marinas@gmail.com \
--cc=git@vger.kernel.org \
--cc=kha@treskal.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).