summaryrefslogtreecommitdiffstats
path: root/subcmds/cherry_pick.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/cherry_pick.py')
-rw-r--r--subcmds/cherry_pick.py177
1 files changed, 94 insertions, 83 deletions
diff --git a/subcmds/cherry_pick.py b/subcmds/cherry_pick.py
index eecf4e17..4cfb8c88 100644
--- a/subcmds/cherry_pick.py
+++ b/subcmds/cherry_pick.py
@@ -17,96 +17,107 @@ import sys
17from command import Command 17from command import Command
18from git_command import GitCommand 18from git_command import GitCommand
19 19
20CHANGE_ID_RE = re.compile(r'^\s*Change-Id: I([0-9a-f]{40})\s*$') 20CHANGE_ID_RE = re.compile(r"^\s*Change-Id: I([0-9a-f]{40})\s*$")
21 21
22 22
23class CherryPick(Command): 23class CherryPick(Command):
24 COMMON = True 24 COMMON = True
25 helpSummary = "Cherry-pick a change." 25 helpSummary = "Cherry-pick a change."
26 helpUsage = """ 26 helpUsage = """
27%prog <sha1> 27%prog <sha1>
28""" 28"""
29 helpDescription = """ 29 helpDescription = """
30'%prog' cherry-picks a change from one branch to another. 30'%prog' cherry-picks a change from one branch to another.
31The change id will be updated, and a reference to the old 31The change id will be updated, and a reference to the old
32change id will be added. 32change id will be added.
33""" 33"""
34 34
35 def ValidateOptions(self, opt, args): 35 def ValidateOptions(self, opt, args):
36 if len(args) != 1: 36 if len(args) != 1:
37 self.Usage() 37 self.Usage()
38 38
39 def Execute(self, opt, args): 39 def Execute(self, opt, args):
40 reference = args[0] 40 reference = args[0]
41 41
42 p = GitCommand(None, 42 p = GitCommand(
43 ['rev-parse', '--verify', reference], 43 None,
44 capture_stdout=True, 44 ["rev-parse", "--verify", reference],
45 capture_stderr=True) 45 capture_stdout=True,
46 if p.Wait() != 0: 46 capture_stderr=True,
47 print(p.stderr, file=sys.stderr) 47 )
48 sys.exit(1) 48 if p.Wait() != 0:
49 sha1 = p.stdout.strip() 49 print(p.stderr, file=sys.stderr)
50 50 sys.exit(1)
51 p = GitCommand(None, ['cat-file', 'commit', sha1], capture_stdout=True) 51 sha1 = p.stdout.strip()
52 if p.Wait() != 0: 52
53 print("error: Failed to retrieve old commit message", file=sys.stderr) 53 p = GitCommand(None, ["cat-file", "commit", sha1], capture_stdout=True)
54 sys.exit(1) 54 if p.Wait() != 0:
55 old_msg = self._StripHeader(p.stdout) 55 print(
56 56 "error: Failed to retrieve old commit message", file=sys.stderr
57 p = GitCommand(None, 57 )
58 ['cherry-pick', sha1], 58 sys.exit(1)
59 capture_stdout=True, 59 old_msg = self._StripHeader(p.stdout)
60 capture_stderr=True) 60
61 status = p.Wait() 61 p = GitCommand(
62 62 None,
63 if p.stdout: 63 ["cherry-pick", sha1],
64 print(p.stdout.strip(), file=sys.stdout) 64 capture_stdout=True,
65 if p.stderr: 65 capture_stderr=True,
66 print(p.stderr.strip(), file=sys.stderr) 66 )
67 67 status = p.Wait()
68 if status == 0: 68
69 # The cherry-pick was applied correctly. We just need to edit the 69 if p.stdout:
70 # commit message. 70 print(p.stdout.strip(), file=sys.stdout)
71 new_msg = self._Reformat(old_msg, sha1) 71 if p.stderr:
72 72 print(p.stderr.strip(), file=sys.stderr)
73 p = GitCommand(None, ['commit', '--amend', '-F', '-'], 73
74 input=new_msg, 74 if status == 0:
75 capture_stdout=True, 75 # The cherry-pick was applied correctly. We just need to edit the
76 capture_stderr=True) 76 # commit message.
77 if p.Wait() != 0: 77 new_msg = self._Reformat(old_msg, sha1)
78 print("error: Failed to update commit message", file=sys.stderr) 78
79 sys.exit(1) 79 p = GitCommand(
80 80 None,
81 else: 81 ["commit", "--amend", "-F", "-"],
82 print('NOTE: When committing (please see above) and editing the commit ' 82 input=new_msg,
83 'message, please remove the old Change-Id-line and add:') 83 capture_stdout=True,
84 print(self._GetReference(sha1), file=sys.stderr) 84 capture_stderr=True,
85 print(file=sys.stderr) 85 )
86 86 if p.Wait() != 0:
87 def _IsChangeId(self, line): 87 print("error: Failed to update commit message", file=sys.stderr)
88 return CHANGE_ID_RE.match(line) 88 sys.exit(1)
89 89
90 def _GetReference(self, sha1): 90 else:
91 return "(cherry picked from commit %s)" % sha1 91 print(
92 92 "NOTE: When committing (please see above) and editing the "
93 def _StripHeader(self, commit_msg): 93 "commit message, please remove the old Change-Id-line and add:"
94 lines = commit_msg.splitlines() 94 )
95 return "\n".join(lines[lines.index("") + 1:]) 95 print(self._GetReference(sha1), file=sys.stderr)
96 96 print(file=sys.stderr)
97 def _Reformat(self, old_msg, sha1): 97
98 new_msg = [] 98 def _IsChangeId(self, line):
99 99 return CHANGE_ID_RE.match(line)
100 for line in old_msg.splitlines(): 100
101 if not self._IsChangeId(line): 101 def _GetReference(self, sha1):
102 new_msg.append(line) 102 return "(cherry picked from commit %s)" % sha1
103 103
104 # Add a blank line between the message and the change id/reference 104 def _StripHeader(self, commit_msg):
105 try: 105 lines = commit_msg.splitlines()
106 if new_msg[-1].strip() != "": 106 return "\n".join(lines[lines.index("") + 1 :])
107 new_msg.append("") 107
108 except IndexError: 108 def _Reformat(self, old_msg, sha1):
109 pass 109 new_msg = []
110 110
111 new_msg.append(self._GetReference(sha1)) 111 for line in old_msg.splitlines():
112 return "\n".join(new_msg) 112 if not self._IsChangeId(line):
113 new_msg.append(line)
114
115 # Add a blank line between the message and the change id/reference.
116 try:
117 if new_msg[-1].strip() != "":
118 new_msg.append("")
119 except IndexError:
120 pass
121
122 new_msg.append(self._GetReference(sha1))
123 return "\n".join(new_msg)