summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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: