Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(571)

Side by Side Diff: tools/push-to-trunk/merge_to_branch.py

Issue 171423013: Refactoring: Extract low-level git from push and merge scripts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Correct copyright year. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/push-to-trunk/git_recipes.py ('k') | tools/push-to-trunk/push_to_trunk.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 the V8 project authors. All rights reserved. 2 # Copyright 2014 the V8 project authors. All rights reserved.
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following 10 # copyright notice, this list of conditions and the following
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 } 50 }
51 51
52 52
53 class MergeToBranchOptions(CommonOptions): 53 class MergeToBranchOptions(CommonOptions):
54 def __init__(self, options, args): 54 def __init__(self, options, args):
55 super(MergeToBranchOptions, self).__init__(options, True) 55 super(MergeToBranchOptions, self).__init__(options, True)
56 self.requires_editor = True 56 self.requires_editor = True
57 self.wait_for_lgtm = True 57 self.wait_for_lgtm = True
58 self.delete_sentinel = options.f 58 self.delete_sentinel = options.f
59 self.message = getattr(options, "message", "") 59 self.message = getattr(options, "message", "")
60 self.revert = "--reverse" if getattr(options, "r", None) else "" 60 self.revert = getattr(options, "r", False)
61 self.revert_bleeding_edge = getattr(options, "revert_bleeding_edge", False) 61 self.revert_bleeding_edge = getattr(options, "revert_bleeding_edge", False)
62 self.patch = getattr(options, "p", "") 62 self.patch = getattr(options, "p", "")
63 self.args = args 63 self.args = args
64 64
65 65
66 class Preparation(Step): 66 class Preparation(Step):
67 MESSAGE = "Preparation." 67 MESSAGE = "Preparation."
68 68
69 def RunStep(self): 69 def RunStep(self):
70 if os.path.exists(self.Config(ALREADY_MERGING_SENTINEL_FILE)): 70 if os.path.exists(self.Config(ALREADY_MERGING_SENTINEL_FILE)):
(...skipping 13 matching lines...) Expand all
84 self.Die("Please specify a branch to merge to") 84 self.Die("Please specify a branch to merge to")
85 85
86 self.CommonPrepare() 86 self.CommonPrepare()
87 self.PrepareBranch() 87 self.PrepareBranch()
88 88
89 89
90 class CreateBranch(Step): 90 class CreateBranch(Step):
91 MESSAGE = "Create a fresh branch for the patch." 91 MESSAGE = "Create a fresh branch for the patch."
92 92
93 def RunStep(self): 93 def RunStep(self):
94 self.Git("checkout -b %s svn/%s" % (self.Config(BRANCHNAME), 94 self.GitCreateBranch(self.Config(BRANCHNAME),
95 self["merge_to_branch"])) 95 "svn/%s" % self["merge_to_branch"])
96 96
97 97
98 class SearchArchitecturePorts(Step): 98 class SearchArchitecturePorts(Step):
99 MESSAGE = "Search for corresponding architecture ports." 99 MESSAGE = "Search for corresponding architecture ports."
100 100
101 def RunStep(self): 101 def RunStep(self):
102 self["full_revision_list"] = list(OrderedDict.fromkeys(self._options.args)) 102 self["full_revision_list"] = list(OrderedDict.fromkeys(self._options.args))
103 port_revision_list = [] 103 port_revision_list = []
104 for revision in self["full_revision_list"]: 104 for revision in self["full_revision_list"]:
105 # Search for commits which matches the "Port rXXX" pattern. 105 # Search for commits which matches the "Port rXXX" pattern.
106 args = ("log svn/bleeding_edge --reverse " 106 git_hashes = self.GitLog(reverse=True, format="%H",
107 "--format=%%H --grep=\"Port r%d\"" % int(revision)) 107 grep="Port r%d" % int(revision),
108 git_hashes = self.Git(args) or "" 108 branch="svn/bleeding_edge")
109 for git_hash in git_hashes.strip().splitlines(): 109 for git_hash in git_hashes.splitlines():
110 args = "svn find-rev %s svn/bleeding_edge" % git_hash 110 svn_revision = self.GitSVNFindSVNRev(git_hash, "svn/bleeding_edge")
111 svn_revision = self.Git(args).strip()
112 if not svn_revision: 111 if not svn_revision:
113 self.Die("Cannot determine svn revision for %s" % git_hash) 112 self.Die("Cannot determine svn revision for %s" % git_hash)
114 revision_title = self.Git("log -1 --format=%%s %s" % git_hash) 113 revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash)
115 114
116 # Is this revision included in the original revision list? 115 # Is this revision included in the original revision list?
117 if svn_revision in self["full_revision_list"]: 116 if svn_revision in self["full_revision_list"]:
118 print("Found port of r%s -> r%s (already included): %s" 117 print("Found port of r%s -> r%s (already included): %s"
119 % (revision, svn_revision, revision_title)) 118 % (revision, svn_revision, revision_title))
120 else: 119 else:
121 print("Found port of r%s -> r%s: %s" 120 print("Found port of r%s -> r%s: %s"
122 % (revision, svn_revision, revision_title)) 121 % (revision, svn_revision, revision_title))
123 port_revision_list.append(svn_revision) 122 port_revision_list.append(svn_revision)
124 123
125 # Do we find any port? 124 # Do we find any port?
126 if len(port_revision_list) > 0: 125 if len(port_revision_list) > 0:
127 if self.Confirm("Automatically add corresponding ports (%s)?" 126 if self.Confirm("Automatically add corresponding ports (%s)?"
128 % ", ".join(port_revision_list)): 127 % ", ".join(port_revision_list)):
129 #: 'y': Add ports to revision list. 128 #: 'y': Add ports to revision list.
130 self["full_revision_list"].extend(port_revision_list) 129 self["full_revision_list"].extend(port_revision_list)
131 130
132 131
133 class FindGitRevisions(Step): 132 class FindGitRevisions(Step):
134 MESSAGE = "Find the git revisions associated with the patches." 133 MESSAGE = "Find the git revisions associated with the patches."
135 134
136 def RunStep(self): 135 def RunStep(self):
137 self["patch_commit_hashes"] = [] 136 self["patch_commit_hashes"] = []
138 for revision in self["full_revision_list"]: 137 for revision in self["full_revision_list"]:
139 next_hash = self.Git("svn find-rev \"r%s\" svn/bleeding_edge" % revision) 138 next_hash = self.GitSVNFindGitHash(revision, "svn/bleeding_edge")
140 if not next_hash: 139 if not next_hash:
141 self.Die("Cannot determine git hash for r%s" % revision) 140 self.Die("Cannot determine git hash for r%s" % revision)
142 self["patch_commit_hashes"].append(next_hash) 141 self["patch_commit_hashes"].append(next_hash)
143 142
144 # Stringify: [123, 234] -> "r123, r234" 143 # Stringify: [123, 234] -> "r123, r234"
145 self["revision_list"] = ", ".join(map(lambda s: "r%s" % s, 144 self["revision_list"] = ", ".join(map(lambda s: "r%s" % s,
146 self["full_revision_list"])) 145 self["full_revision_list"]))
147 146
148 if not self["revision_list"]: 147 if not self["revision_list"]:
149 self.Die("Revision list is empty.") 148 self.Die("Revision list is empty.")
150 149
151 if self._options.revert: 150 if self._options.revert:
152 if not self._options.revert_bleeding_edge: 151 if not self._options.revert_bleeding_edge:
153 self["new_commit_msg"] = ("Rollback of %s in %s branch." 152 self["new_commit_msg"] = ("Rollback of %s in %s branch."
154 % (self["revision_list"], self["merge_to_branch"])) 153 % (self["revision_list"], self["merge_to_branch"]))
155 else: 154 else:
156 self["new_commit_msg"] = "Revert %s." % self["revision_list"] 155 self["new_commit_msg"] = "Revert %s." % self["revision_list"]
157 else: 156 else:
158 self["new_commit_msg"] = ("Merged %s into %s branch." 157 self["new_commit_msg"] = ("Merged %s into %s branch."
159 % (self["revision_list"], self["merge_to_branch"])) 158 % (self["revision_list"], self["merge_to_branch"]))
160 self["new_commit_msg"] += "\n\n" 159 self["new_commit_msg"] += "\n\n"
161 160
162 for commit_hash in self["patch_commit_hashes"]: 161 for commit_hash in self["patch_commit_hashes"]:
163 patch_merge_desc = self.Git("log -1 --format=%%s %s" % commit_hash) 162 patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash)
164 self["new_commit_msg"] += "%s\n\n" % patch_merge_desc.strip() 163 self["new_commit_msg"] += "%s\n\n" % patch_merge_desc
165 164
166 bugs = [] 165 bugs = []
167 for commit_hash in self["patch_commit_hashes"]: 166 for commit_hash in self["patch_commit_hashes"]:
168 msg = self.Git("log -1 %s" % commit_hash) 167 msg = self.GitLog(n=1, git_hash=commit_hash)
169 for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg, 168 for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg,
170 re.M): 169 re.M):
171 bugs.extend(map(lambda s: s.strip(), bug.split(","))) 170 bugs.extend(map(lambda s: s.strip(), bug.split(",")))
172 bug_aggregate = ",".join(sorted(bugs)) 171 bug_aggregate = ",".join(sorted(bugs))
173 if bug_aggregate: 172 if bug_aggregate:
174 self["new_commit_msg"] += "BUG=%s\nLOG=N\n" % bug_aggregate 173 self["new_commit_msg"] += "BUG=%s\nLOG=N\n" % bug_aggregate
175 TextToFile(self["new_commit_msg"], self.Config(COMMITMSG_FILE)) 174 TextToFile(self["new_commit_msg"], self.Config(COMMITMSG_FILE))
176 175
177 176
178 class ApplyPatches(Step): 177 class ApplyPatches(Step):
179 MESSAGE = "Apply patches for selected revisions." 178 MESSAGE = "Apply patches for selected revisions."
180 179
181 def RunStep(self): 180 def RunStep(self):
182 for commit_hash in self["patch_commit_hashes"]: 181 for commit_hash in self["patch_commit_hashes"]:
183 print("Applying patch for %s to %s..." 182 print("Applying patch for %s to %s..."
184 % (commit_hash, self["merge_to_branch"])) 183 % (commit_hash, self["merge_to_branch"]))
185 patch = self.Git("log -1 -p %s" % commit_hash) 184 patch = self.GitLog(n=1, patch=True, git_hash=commit_hash)
186 TextToFile(patch, self.Config(TEMPORARY_PATCH_FILE)) 185 TextToFile(patch, self.Config(TEMPORARY_PATCH_FILE))
187 self.ApplyPatch(self.Config(TEMPORARY_PATCH_FILE), self._options.revert) 186 self.ApplyPatch(self.Config(TEMPORARY_PATCH_FILE), self._options.revert)
188 if self._options.patch: 187 if self._options.patch:
189 self.ApplyPatch(self._options.patch, self._options.revert) 188 self.ApplyPatch(self._options.patch, self._options.revert)
190 189
191 190
192 class PrepareVersion(Step): 191 class PrepareVersion(Step):
193 MESSAGE = "Prepare version file." 192 MESSAGE = "Prepare version file."
194 193
195 def RunStep(self): 194 def RunStep(self):
(...skipping 21 matching lines...) Expand all
217 TextToFile(text, self.Config(VERSION_FILE)) 216 TextToFile(text, self.Config(VERSION_FILE))
218 else: 217 else:
219 self.Editor(self.Config(VERSION_FILE)) 218 self.Editor(self.Config(VERSION_FILE))
220 self.ReadAndPersistVersion("new_") 219 self.ReadAndPersistVersion("new_")
221 220
222 221
223 class CommitLocal(Step): 222 class CommitLocal(Step):
224 MESSAGE = "Commit to local branch." 223 MESSAGE = "Commit to local branch."
225 224
226 def RunStep(self): 225 def RunStep(self):
227 self.Git("commit -a -F \"%s\"" % self.Config(COMMITMSG_FILE)) 226 self.GitCommit(file_name=self.Config(COMMITMSG_FILE))
228 227
229 228
230 class CommitRepository(Step): 229 class CommitRepository(Step):
231 MESSAGE = "Commit to the repository." 230 MESSAGE = "Commit to the repository."
232 231
233 def RunStep(self): 232 def RunStep(self):
234 self.Git("checkout %s" % self.Config(BRANCHNAME)) 233 self.GitCheckout(self.Config(BRANCHNAME))
235 self.WaitForLGTM() 234 self.WaitForLGTM()
236 self.Git("cl presubmit", "PRESUBMIT_TREE_CHECK=\"skip\"") 235 self.GitPresubmit()
237 self.Git("cl dcommit -f --bypass-hooks", retry_on=lambda x: x is None) 236 self.GitDCommit()
238 237
239 238
240 class PrepareSVN(Step): 239 class PrepareSVN(Step):
241 MESSAGE = "Determine svn commit revision." 240 MESSAGE = "Determine svn commit revision."
242 241
243 def RunStep(self): 242 def RunStep(self):
244 if self._options.revert_bleeding_edge: 243 if self._options.revert_bleeding_edge:
245 return 244 return
246 self.Git("svn fetch") 245 self.GitSVNFetch()
247 args = ("log -1 --format=%%H --grep=\"%s\" svn/%s" 246 commit_hash = self.GitLog(n=1, format="%H", grep=self["new_commit_msg"],
248 % (self["new_commit_msg"], self["merge_to_branch"])) 247 branch="svn/%s" % self["merge_to_branch"])
249 commit_hash = self.Git(args).strip()
250 if not commit_hash: 248 if not commit_hash:
251 self.Die("Unable to map git commit to svn revision.") 249 self.Die("Unable to map git commit to svn revision.")
252 self["svn_revision"] = self.Git( 250 self["svn_revision"] = self.GitSVNFindSVNRev(commit_hash)
253 "svn find-rev %s" % commit_hash).strip()
254 print "subversion revision number is r%s" % self["svn_revision"] 251 print "subversion revision number is r%s" % self["svn_revision"]
255 252
256 253
257 class TagRevision(Step): 254 class TagRevision(Step):
258 MESSAGE = "Create the tag." 255 MESSAGE = "Create the tag."
259 256
260 def RunStep(self): 257 def RunStep(self):
261 if self._options.revert_bleeding_edge: 258 if self._options.revert_bleeding_edge:
262 return 259 return
263 self["version"] = "%s.%s.%s.%s" % (self["new_major"], 260 self["version"] = "%s.%s.%s.%s" % (self["new_major"],
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 def Main(): 353 def Main():
357 parser = BuildOptions() 354 parser = BuildOptions()
358 (options, args) = parser.parse_args() 355 (options, args) = parser.parse_args()
359 if not ProcessOptions(options, args): 356 if not ProcessOptions(options, args):
360 parser.print_help() 357 parser.print_help()
361 return 1 358 return 1
362 RunMergeToBranch(CONFIG, MergeToBranchOptions(options, args)) 359 RunMergeToBranch(CONFIG, MergeToBranchOptions(options, args))
363 360
364 if __name__ == "__main__": 361 if __name__ == "__main__":
365 sys.exit(Main()) 362 sys.exit(Main())
OLDNEW
« no previous file with comments | « tools/push-to-trunk/git_recipes.py ('k') | tools/push-to-trunk/push_to_trunk.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698