from common_includes import *
+def IsSvnNumber(rev):
+ return rev.isdigit() and len(rev) < 8
+
class Preparation(Step):
MESSAGE = "Preparation."
self._options.revisions))
port_revision_list = []
for revision in self["full_revision_list"]:
- # Search for commits which matches the "Port rXXX" pattern.
+ # Search for commits which matches the "Port XXX" pattern.
git_hashes = self.GitLog(reverse=True, format="%H",
- grep="Port r%d" % int(revision),
+ grep="Port %s" % revision,
branch=self.vc.RemoteMasterBranch())
for git_hash in git_hashes.splitlines():
- svn_revision = self.vc.GitSvn(git_hash, self.vc.RemoteMasterBranch())
- if not svn_revision: # pragma: no cover
- self.Die("Cannot determine svn revision for %s" % git_hash)
revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash)
# Is this revision included in the original revision list?
- if svn_revision in self["full_revision_list"]:
- print("Found port of r%s -> r%s (already included): %s"
- % (revision, svn_revision, revision_title))
+ if git_hash in self["full_revision_list"]:
+ print("Found port of %s -> %s (already included): %s"
+ % (revision, git_hash, revision_title))
else:
- print("Found port of r%s -> r%s: %s"
- % (revision, svn_revision, revision_title))
- port_revision_list.append(svn_revision)
+ print("Found port of %s -> %s: %s"
+ % (revision, git_hash, revision_title))
+ port_revision_list.append(git_hash)
# Do we find any port?
if len(port_revision_list) > 0:
self["full_revision_list"].extend(port_revision_list)
-class FindGitRevisions(Step):
- MESSAGE = "Find the git revisions associated with the patches."
+class CreateCommitMessage(Step):
+ MESSAGE = "Create commit message."
def RunStep(self):
- self["patch_commit_hashes"] = []
- for revision in self["full_revision_list"]:
- next_hash = self.vc.SvnGit(revision, self.vc.RemoteMasterBranch())
- if not next_hash: # pragma: no cover
- self.Die("Cannot determine git hash for r%s" % revision)
- self["patch_commit_hashes"].append(next_hash)
# Stringify: [123, 234] -> "r123, r234"
self["revision_list"] = ", ".join(map(lambda s: "r%s" % s,
if not self["revision_list"]: # pragma: no cover
self.Die("Revision list is empty.")
+ if self._options.revert and not self._options.revert_bleeding_edge:
+ action_text = "Rollback of %s"
+ else:
+ action_text = "Merged %s"
+
# The commit message title is added below after the version is specified.
- self["new_commit_msg"] = ""
+ msg_pieces = [
+ "\n".join(action_text % s for s in self["full_revision_list"]),
+ ]
+ msg_pieces.append("\n\n")
- for commit_hash in self["patch_commit_hashes"]:
+ for commit_hash in self["full_revision_list"]:
patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash)
- self["new_commit_msg"] += "%s\n\n" % patch_merge_desc
+ msg_pieces.append("%s\n\n" % patch_merge_desc)
bugs = []
- for commit_hash in self["patch_commit_hashes"]:
+ for commit_hash in self["full_revision_list"]:
msg = self.GitLog(n=1, git_hash=commit_hash)
- for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg,
- re.M):
- bugs.extend(map(lambda s: s.strip(), bug.split(",")))
+ for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg, re.M):
+ bugs.extend(s.strip() for s in bug.split(","))
bug_aggregate = ",".join(sorted(filter(lambda s: s and s != "none", bugs)))
if bug_aggregate:
- self["new_commit_msg"] += "BUG=%s\nLOG=N\n" % bug_aggregate
+ msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate)
+
+ self["new_commit_msg"] = "".join(msg_pieces)
class ApplyPatches(Step):
MESSAGE = "Apply patches for selected revisions."
def RunStep(self):
- for commit_hash in self["patch_commit_hashes"]:
+ for commit_hash in self["full_revision_list"]:
print("Applying patch for %s to %s..."
% (commit_hash, self["merge_to_branch"]))
patch = self.GitGetPatch(commit_hash)
def RunStep(self):
# Add a commit message title.
- if self._options.revert:
- if not self._options.revert_bleeding_edge:
- title = ("Version %s (rollback of %s)"
- % (self["version"], self["revision_list"]))
- else:
- title = "Revert %s." % self["revision_list"]
+ if self._options.revert and self._options.revert_bleeding_edge:
+ # TODO(machenbach): Find a better convention if multiple patches are
+ # reverted in one CL.
+ self["commit_title"] = "Revert on master"
else:
- title = ("Version %s (merged %s)"
- % (self["version"], self["revision_list"]))
- self["commit_title"] = title
- self["new_commit_msg"] = "%s\n\n%s" % (title, self["new_commit_msg"])
+ self["commit_title"] = "Version %s (cherry-pick)" % self["version"]
+ self["new_commit_msg"] = "%s\n\n%s" % (self["commit_title"],
+ self["new_commit_msg"])
TextToFile(self["new_commit_msg"], self.Config("COMMITMSG_FILE"))
self.GitCommit(file_name=self.Config("COMMITMSG_FILE"))
options.bypass_upload_hooks = True
# CC ulan to make sure that fixes are merged to Google3.
options.cc = "ulan@chromium.org"
+
+ # Thd old git-svn workflow is deprecated for this script.
+ assert options.vc_interface != "git_svn"
+
+ # Make sure to use git hashes in the new workflows.
+ for revision in options.revisions:
+ if (IsSvnNumber(revision) or
+ (revision[0:1] == "r" and IsSvnNumber(revision[1:]))):
+ print "Please provide full git hashes of the patches to merge."
+ print "Got: %s" % revision
+ return False
return True
def _Config(self):
Preparation,
CreateBranch,
SearchArchitecturePorts,
- FindGitRevisions,
+ CreateCommitMessage,
ApplyPatches,
PrepareVersion,
IncrementVersion,
Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
])
args = ["--branch", "candidates", "--vc-interface", "git_read_svn_write",
- "12345"]
+ "ab12345"]
self._state["version"] = "tag_name"
self._state["commit_title"] = "Title"
self.assertRaises(Exception,
return lambda: self.assertEquals(patch,
FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
- msg = """Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)
+ msg = """Version 3.22.5.1 (cherry-pick)
-Title4
-
-Title2
-
-Title3
-
-Title1
-
-Revert "Something"
-
-BUG=123,234,345,456,567,v8:123
-LOG=N
-"""
-
- def VerifySVNCommit():
- commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
- self.assertEquals(msg, commit)
- version = FileToText(
- os.path.join(TEST_CONFIG["DEFAULT_CWD"], VERSION_FILE))
- self.assertTrue(re.search(r"#define MINOR_VERSION\s+22", version))
- self.assertTrue(re.search(r"#define BUILD_NUMBER\s+5", version))
- self.assertTrue(re.search(r"#define PATCH_LEVEL\s+1", version))
- self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
-
- self.Expect([
- Cmd("git status -s -uno", ""),
- Cmd("git status -s -b -uno", "## some_branch\n"),
- Cmd("git svn fetch", ""),
- Cmd("git branch", " branch1\n* branch2\n"),
- Cmd("git new-branch %s --upstream svn/trunk" % TEST_CONFIG["BRANCHNAME"],
- ""),
- Cmd(("git log --format=%H --grep=\"Port r12345\" "
- "--reverse svn/bleeding_edge"),
- "hash1\nhash2"),
- Cmd("git svn find-rev hash1 svn/bleeding_edge", "45678"),
- Cmd("git log -1 --format=%s hash1", "Title1"),
- Cmd("git svn find-rev hash2 svn/bleeding_edge", "23456"),
- Cmd("git log -1 --format=%s hash2", "Title2"),
- Cmd(("git log --format=%H --grep=\"Port r23456\" "
- "--reverse svn/bleeding_edge"),
- ""),
- Cmd(("git log --format=%H --grep=\"Port r34567\" "
- "--reverse svn/bleeding_edge"),
- "hash3"),
- Cmd("git svn find-rev hash3 svn/bleeding_edge", "56789"),
- Cmd("git log -1 --format=%s hash3", "Title3"),
- RL("Y"), # Automatically add corresponding ports (34567, 56789)?
- Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
- # Simulate svn being down which stops the script.
- Cmd("git svn find-rev r23456 svn/bleeding_edge", None),
- # Restart script in the failing step.
- Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
- Cmd("git svn find-rev r23456 svn/bleeding_edge", "hash2"),
- Cmd("git svn find-rev r34567 svn/bleeding_edge", "hash3"),
- Cmd("git svn find-rev r45678 svn/bleeding_edge", "hash1"),
- Cmd("git svn find-rev r56789 svn/bleeding_edge", "hash5"),
- Cmd("git log -1 --format=%s hash4", "Title4"),
- Cmd("git log -1 --format=%s hash2", "Title2"),
- Cmd("git log -1 --format=%s hash3", "Title3"),
- Cmd("git log -1 --format=%s hash1", "Title1"),
- Cmd("git log -1 --format=%s hash5", "Revert \"Something\""),
- Cmd("git log -1 hash4", "Title4\nBUG=123\nBUG=234"),
- Cmd("git log -1 hash2", "Title2\n BUG = v8:123,345"),
- Cmd("git log -1 hash3", "Title3\nLOG=n\nBUG=567, 456"),
- Cmd("git log -1 hash1", "Title1\nBUG="),
- Cmd("git log -1 hash5", "Revert \"Something\"\nBUG=none"),
- Cmd("git log -1 -p hash4", "patch4"),
- Cmd(("git apply --index --reject \"%s\"" %
- TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
- "", cb=VerifyPatch("patch4")),
- Cmd("git log -1 -p hash2", "patch2"),
- Cmd(("git apply --index --reject \"%s\"" %
- TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
- "", cb=VerifyPatch("patch2")),
- Cmd("git log -1 -p hash3", "patch3"),
- Cmd(("git apply --index --reject \"%s\"" %
- TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
- "", cb=VerifyPatch("patch3")),
- Cmd("git log -1 -p hash1", "patch1"),
- Cmd(("git apply --index --reject \"%s\"" %
- TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
- "", cb=VerifyPatch("patch1")),
- Cmd("git log -1 -p hash5", "patch5\n"),
- Cmd(("git apply --index --reject \"%s\"" %
- TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
- "", cb=VerifyPatch("patch5\n")),
- Cmd("git apply --index --reject \"%s\"" % extra_patch, ""),
- RL("Y"), # Automatically increment patch level?
- Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
- RL("reviewer@chromium.org"), # V8 reviewer.
- Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
- "--bypass-hooks --cc \"ulan@chromium.org\"", ""),
- Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
- RL("LGTM"), # Enter LGTM for V8 CL.
- Cmd("git cl presubmit", "Presubmit successfull\n"),
- Cmd("git cl dcommit -f --bypass-hooks", "Closing issue\n",
- cb=VerifySVNCommit),
- Cmd("git svn fetch", ""),
- Cmd("git rebase svn/trunk", ""),
- Cmd("git svn tag 3.22.5.1 -m \"Tagging version 3.22.5.1\"", ""),
- Cmd("git checkout -f some_branch", ""),
- Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
- ])
-
- # r12345 and r34567 are patches. r23456 (included) and r45678 are the MIPS
- # ports of r12345. r56789 is the MIPS port of r34567.
- args = ["-f", "-p", extra_patch, "--branch", "trunk",
- "--vc-interface", "git_svn", "12345", "23456", "34567"]
-
- # The first run of the script stops because of the svn being down.
- self.assertRaises(GitFailedException,
- lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
-
- # Test that state recovery after restarting the script works.
- args += ["-s", "4"]
- MergeToBranch(TEST_CONFIG, self).Run(args)
-
- def testMergeToBranchNewGit(self):
- TEST_CONFIG["ALREADY_MERGING_SENTINEL_FILE"] = self.MakeEmptyTempFile()
- TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
- self.WriteFakeVersionFile(build=5)
- os.environ["EDITOR"] = "vi"
- extra_patch = self.MakeEmptyTempFile()
-
- def VerifyPatch(patch):
- return lambda: self.assertEquals(patch,
- FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
-
- msg = """Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)
+Merged ab12345
+Merged ab23456
+Merged ab34567
+Merged ab45678
+Merged ab56789
Title4
Cmd("git branch", " branch1\n* branch2\n"),
Cmd("git new-branch %s --upstream origin/candidates" %
TEST_CONFIG["BRANCHNAME"], ""),
- Cmd(("git log --format=%H --grep=\"Port r12345\" "
+ Cmd(("git log --format=%H --grep=\"Port ab12345\" "
"--reverse origin/master"),
- "hash1\nhash2"),
- Cmd("git svn find-rev hash1 origin/master", "45678"),
- Cmd("git log -1 --format=%s hash1", "Title1"),
- Cmd("git svn find-rev hash2 origin/master", "23456"),
- Cmd("git log -1 --format=%s hash2", "Title2"),
- Cmd(("git log --format=%H --grep=\"Port r23456\" "
+ "ab45678\nab23456"),
+ Cmd("git log -1 --format=%s ab45678", "Title1"),
+ Cmd("git log -1 --format=%s ab23456", "Title2"),
+ Cmd(("git log --format=%H --grep=\"Port ab23456\" "
"--reverse origin/master"),
""),
- Cmd(("git log --format=%H --grep=\"Port r34567\" "
+ Cmd(("git log --format=%H --grep=\"Port ab34567\" "
"--reverse origin/master"),
- "hash3"),
- Cmd("git svn find-rev hash3 origin/master", "56789"),
- Cmd("git log -1 --format=%s hash3", "Title3"),
- RL("Y"), # Automatically add corresponding ports (34567, 56789)?
- Cmd("git svn find-rev r12345 origin/master",
- "Partial-rebuilding bla\nDone rebuilding blub\nhash4"),
- # Simulate svn being down which stops the script.
- Cmd("git svn find-rev r23456 origin/master", None),
+ "ab56789"),
+ Cmd("git log -1 --format=%s ab56789", "Title3"),
+ RL("Y"), # Automatically add corresponding ports (ab34567, ab56789)?
+ # Simulate git being down which stops the script.
+ Cmd("git log -1 --format=%s ab12345", None),
# Restart script in the failing step.
- Cmd("git svn find-rev r12345 origin/master", "hash4"),
- Cmd("git svn find-rev r23456 origin/master", "hash2"),
- Cmd("git svn find-rev r34567 origin/master", "hash3"),
- Cmd("git svn find-rev r45678 origin/master", "hash1"),
- Cmd("git svn find-rev r56789 origin/master", "hash5"),
- Cmd("git log -1 --format=%s hash4", "Title4"),
- Cmd("git log -1 --format=%s hash2", "Title2"),
- Cmd("git log -1 --format=%s hash3", "Title3"),
- Cmd("git log -1 --format=%s hash1", "Title1"),
- Cmd("git log -1 --format=%s hash5", "Revert \"Something\""),
- Cmd("git log -1 hash4", "Title4\nBUG=123\nBUG=234"),
- Cmd("git log -1 hash2", "Title2\n BUG = v8:123,345"),
- Cmd("git log -1 hash3", "Title3\nLOG=n\nBUG=567, 456"),
- Cmd("git log -1 hash1", "Title1\nBUG="),
- Cmd("git log -1 hash5", "Revert \"Something\"\nBUG=none"),
- Cmd("git log -1 -p hash4", "patch4"),
+ Cmd("git log -1 --format=%s ab12345", "Title4"),
+ Cmd("git log -1 --format=%s ab23456", "Title2"),
+ Cmd("git log -1 --format=%s ab34567", "Title3"),
+ Cmd("git log -1 --format=%s ab45678", "Title1"),
+ Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
+ Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
+ Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
+ Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
+ Cmd("git log -1 ab45678", "Title1\nBUG="),
+ Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
+ Cmd("git log -1 -p ab12345", "patch4"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch4")),
- Cmd("git log -1 -p hash2", "patch2"),
+ Cmd("git log -1 -p ab23456", "patch2"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch2")),
- Cmd("git log -1 -p hash3", "patch3"),
+ Cmd("git log -1 -p ab34567", "patch3"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch3")),
- Cmd("git log -1 -p hash1", "patch1"),
+ Cmd("git log -1 -p ab45678", "patch1"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch1")),
- Cmd("git log -1 -p hash5", "patch5\n"),
+ Cmd("git log -1 -p ab56789", "patch5\n"),
Cmd(("git apply --index --reject \"%s\"" %
TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
"", cb=VerifyPatch("patch5\n")),
cb=VerifySVNCommit),
Cmd("git fetch", ""),
Cmd("git log -1 --format=%H --grep=\""
- "Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)"
+ "Version 3.22.5.1 (cherry-pick)"
"\" origin/candidates",
""),
Cmd("git fetch", ""),
Cmd("git log -1 --format=%H --grep=\""
- "Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)"
+ "Version 3.22.5.1 (cherry-pick)"
"\" origin/candidates",
"hsh_to_tag"),
Cmd("git tag 3.22.5.1 hsh_to_tag", ""),
Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
])
- # r12345 and r34567 are patches. r23456 (included) and r45678 are the MIPS
- # ports of r12345. r56789 is the MIPS port of r34567.
+ # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
+ # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
args = ["-f", "-p", extra_patch, "--branch", "candidates",
- "--vc-interface", "git_read_svn_write", "12345", "23456", "34567"]
+ "ab12345", "ab23456", "ab34567"]
- # The first run of the script stops because of the svn being down.
+ # The first run of the script stops because of git being down.
self.assertRaises(GitFailedException,
lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "",
cb=ResetVersion(3, 1, 1)),
Cmd("git log -1 --format=%B hash_234",
- "Version 3.3.1.1 (merged 12)\n\nReview URL: fake.com\n"),
+ "Version 3.3.1.1 (cherry-pick).\n\n"
+ "Merged abc12.\n\n"
+ "Review URL: fake.com\n"),
Cmd("git log -1 --format=%s hash_234", ""),
Cmd("git svn find-rev hash_234", "234"),
Cmd("git log -1 --format=%ci hash_234", "18:15"),
"3.28.40,master,22624,4567,\r\n"
"3.22.3,candidates,345,3456:4566,\r\n"
"3.21.2,3.21,123,,\r\n"
- "3.3.1.1,3.3,234,,12\r\n")
+ "3.3.1.1,3.3,234,,abc12\r\n")
self.assertEquals(csv, FileToText(csv_output))
expected_json = [
{
"revision": "234",
"revision_git": "hash_234",
- "patches_merged": "12",
+ "patches_merged": "abc12",
"bleeding_edge": "",
"bleeding_edge_git": "",
"version": "3.3.1.1",