summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2011-07-09 14:10:50 -0400
committerOwen W. Taylor <otaylor@fishsoup.net>2012-03-01 13:24:46 -0500
commite422eea9999a02262d3bad996879378ce1824541 (patch)
treefb48f52ef6cd7f2cc442ced66eece979789eee6f
parent483d5e258f14176ed3cacd1138fae723a6a5fce3 (diff)
apply: add interactive option
Rather than asking whether or not to apply each patch individually, list all of the patches at once and allow the user to either apply all of them, apply none of them, or interactively choose which ones to apply (a la interactive rebasing). In addition to choosing which patches to apply, the interactive option also allows reordering the patches before applying, and choosing to apply committed or rejected patches. https://bugzilla.gnome.org/show_bug.cgi?id=657558
-rwxr-xr-xgit-bz57
-rw-r--r--git-bz.txt11
2 files changed, 58 insertions, 10 deletions
diff --git a/git-bz b/git-bz
index cfda958..150598c 100755
--- a/git-bz
+++ b/git-bz
@@ -835,6 +835,16 @@ def prompt(message):
elif line == 'n' or line == 'N':
return False
+def prompt_multi(message, options):
+ while True:
+ # Using print here could result in Python adding a stray space
+ # before the next print
+ sys.stdout.write(message + " ")
+ line = sys.stdin.readline()
+ opt = line[0].lower()
+ if opt in options:
+ return opt
+
def die(message):
print >>sys.stderr, message
sys.exit(1)
@@ -1531,21 +1541,56 @@ def do_add_url(bug_reference, commit_or_revision_range):
def do_apply(bug_reference):
bug = Bug.load(BugHandle.parse_or_die(bug_reference),
attachmentdata=True)
+ if len(bug.patches) == 0:
+ die("No patches on bug %d" % bug.id)
+
+ patches = []
+ patches_by_id = {}
print "Bug %d - %s" % (bug.id, bug.short_desc)
print
for patch in bug.patches:
if patch.status == 'committed' or patch.status == 'rejected':
- print "Skipping, %s: %s" % (patch.status, patch.description)
- continue
+ print "%d (skipping, %s) - %s" % (patch.attach_id, patch.status, patch.description)
+ else:
+ patches.append(patch)
- print patch.description
- if not prompt("Apply?"):
- continue
+ for patch in patches:
+ print "%d - %s" % (patch.attach_id, patch.description)
+ print
+ opt = prompt_multi("Apply? [(y)es, (n)o, (i)nteractive]", ["y", "n", "i"])
- print
+ if opt == "n":
+ return
+ elif opt == "i":
+ template = StringIO()
+ template.write("# Bug %d - %s\n\n" % (bug.id, bug.short_desc))
+ for patch in bug.patches:
+ patches_by_id[patch.attach_id] = patch
+ if patch.status == 'committed' or patch.status == 'rejected':
+ template.write("#%d - %s (%s)\n" % (patch.attach_id, patch.description, patch.status))
+ else:
+ template.write("%d - %s\n" % (patch.attach_id, patch.description))
+ template.write("\n")
+ template.write("""# Uncommented patches will be applied in the order they appear.
+# Lines starting with '#' will be ignored. Delete everything to abort.
+""")
+
+ lines = edit_template(template.getvalue())
+ patches = []
+ for line in lines:
+ match = re.match('^(\d+)', line)
+ if match:
+ pid = int(match.group(1))
+ if not patches_by_id.has_key(pid):
+ die("Unknown attachment id " + pid)
+ patches.append(patches_by_id[pid])
+
+ if len(patches) == 0:
+ die("No patches to apply, aborting")
+ for patch in patches:
handle, filename = tempfile.mkstemp(".patch", make_filename(patch.description) + "-")
f = os.fdopen(handle, "w")
f.write(patch.data)
diff --git a/git-bz.txt b/git-bz.txt
index 18bce74..0dcf7f7 100644
--- a/git-bz.txt
+++ b/git-bz.txt
@@ -134,10 +134,13 @@ apply
'git bz apply' [-n | --no-add-url] <bug reference>
-For each patch attachment (except for obsolete patches) of the specified
-bug, prompts whether to apply. If prompt is agreed to runs 'git am' on
-the patch to apply it to the current branch. Aborts if 'git am' fails to
-allow cleaning up conflicts.
+Lists all "pending" patches on the specified bug (ie, the patches that
+are not obsolete, committed, or rejected), and then prompts whether to
+apply them. In addition to simply accepting or rejecting the list of
+patches, you can also type "i" to interactively choose which patches
+to apply, and in what order, as with 'git rebase -i'. If any patches
+are selected, it runs 'git am' on each one to apply it to the current
+branch. Aborts if 'git am' fails, to allow cleaning up conflicts.
Examples: