bisect-kit: switch source version while maintaining project list
After bisectors migrated to use codechange module, they can enumerate
changes with add/del repos. This CL adds support of source code version
switching.
BUG=chromium:827092
TEST=test following cases:
(unrelated command line options are skipped)
- repo case 1
./bisect_cros_repo.py init --old R67-10502.0.0 --new R67-10503.0.0
./switch_cros_localbuild.py R67-10502.0.0~R67-10503.0.0/46
- repo case 2
./bisect_cros_repo.py init --old R70-10907.0.0 --new R70-10908.0.0
./switch_cros_localbuild.py R70-10907.0.0~R70-10908.0.0/68
- gclient
./bisect_cros_localbuild_internal.py init --old 70.0.3509.0 --new 70.0.3510.0
Change-Id: I416baf916fcdf7e7a80dbbde562469d290e5b2b4
Reviewed-on: https://chromium-review.googlesource.com/1218248
Commit-Ready: Kuang-che Wu <kcwu@chromium.org>
Tested-by: Kuang-che Wu <kcwu@chromium.org>
Reviewed-by: Chung-yih Wang <cywang@chromium.org>
diff --git a/bisect_kit/codechange.py b/bisect_kit/codechange.py
index c50407f..f301c4b 100644
--- a/bisect_kit/codechange.py
+++ b/bisect_kit/codechange.py
@@ -249,7 +249,7 @@
self.timestamp = timestamp
self.path = path
- def apply(self, _root_dir):
+ def apply(self, _code_storage, _root_dir):
raise NotImplementedError
def summary(self, _code_storage):
@@ -317,9 +317,9 @@
ag.add(unserialize_action(x))
return ag
- def apply(self, root_dir):
+ def apply(self, code_storage, root_dir):
for action in self.actions:
- action.apply(root_dir)
+ action.apply(code_storage, root_dir)
class GitCheckoutCommit(Action):
@@ -335,7 +335,8 @@
self.repo_url = repo_url
self.rev = rev
- def apply(self, root_dir):
+ def apply(self, code_storage, root_dir):
+ del code_storage # unused
git_repo = os.path.join(root_dir, self.path)
assert git_util.is_git_root(git_repo)
git_util.checkout_version(git_repo, self.rev)
@@ -359,10 +360,15 @@
self.repo_url = repo_url
self.rev = rev
- def apply(self, root_dir):
+ def apply(self, code_storage, root_dir):
git_repo = os.path.join(root_dir, self.path)
- assert os.path.exists(git_repo)
- assert git_util.is_git_root(git_repo)
+ assert not os.path.exists(git_repo)
+
+ reference = code_storage.cached_git_root(self.repo_url)
+ git_util.clone(git_repo, self.repo_url, reference=reference)
+ git_util.checkout_version(git_repo, self.rev)
+
+ code_storage.add_to_project_list(root_dir, self.path, self.repo_url)
def summary(self, _code_storage):
return 'add repo %s from %s@%s' % (self.path, self.repo_url, self.rev[:10])
@@ -371,13 +377,14 @@
class GitRemoveRepo(Action):
"""Describes a git repo remove action."""
- def apply(self, root_dir):
+ def apply(self, code_storage, root_dir):
assert self.path
git_repo = os.path.join(root_dir, self.path)
assert git_util.is_git_root(git_repo)
- assert 0
shutil.rmtree(git_repo)
+ code_storage.remove_from_project_list(root_dir, self.path)
+
def summary(self, _code_storage):
return 'remove repo %s' % self.path
@@ -391,7 +398,7 @@
def batch_apply(commits):
for i, commit_action in sorted(commits.values()):
logger.debug('[%d] applying "%r"', i, commit_action.summary(code_storage))
- commit_action.apply(root_dir)
+ commit_action.apply(code_storage, root_dir)
for i, action_group in enumerate(action_groups, 1):
for action in action_group.actions:
@@ -405,7 +412,7 @@
batch_apply(commits)
commits = {}
- action.apply(root_dir)
+ action.apply(code_storage, root_dir)
batch_apply(commits)
@@ -478,6 +485,12 @@
"""
raise NotImplementedError
+ def add_to_project_list(self, project_root, path, repo_url):
+ raise NotImplementedError
+
+ def remove_from_project_list(self, project_root, path):
+ raise NotImplementedError
+
def is_ancestor_commit(self, spec, path, old, new):
"""Determine one commit is ancestor of another.