Reland "Make gclient ready for the Blink (DEPS to main project)"
Reland crrev.com/743083002, which was reverted in crrev.com/796053002
due to some test flakiness, probably related with an old version of Git on
the bots. Relanding now that the infra has been updated to Trusty (plus
adding some de-flake precautions).
Original CL Description:
Make gclient ready for the Blink (DEPS to main project) transition
This CL makes gclient understand correctly whether a git project is
being moved from DEPS to an upper project and vice-versa.
The driving use case for this is the upcoming Blink merge, where
third_party/Webkit will be removed from DEPS (and .gitignore) and will
become part of the main project.
At present state, gclient leaves the .git folder around when a project
is removed from DEPS, and that causes many problems.
Furthermore this CL solves the performance problem of bisecting across
the merge point. The subproject's (Blink) .git/ folder is moved to a
backup location (in the main checkout root) and is restored when moving
backwards, avoiding a re-fetch when bisecting across the merge point.
BUG=431469
Review URL: https://codereview.chromium.org/910913003
git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@294082 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gclient_scm.py b/gclient_scm.py
index 69dec50..243387b 100644
--- a/gclient_scm.py
+++ b/gclient_scm.py
@@ -389,6 +389,20 @@
if mirror:
url = mirror.mirror_path
+ # If we are going to introduce a new project, there is a possibility that
+ # we are syncing back to a state where the project was originally a
+ # sub-project rolled by DEPS (realistic case: crossing the Blink merge point
+ # syncing backwards, when Blink was a DEPS entry and not part of src.git).
+ # In such case, we might have a backup of the former .git folder, which can
+ # be used to avoid re-fetching the entire repo again (useful for bisects).
+ backup_dir = self.GetGitBackupDirPath()
+ target_dir = os.path.join(self.checkout_path, '.git')
+ if os.path.exists(backup_dir) and not os.path.exists(target_dir):
+ gclient_utils.safe_makedirs(self.checkout_path)
+ os.rename(backup_dir, target_dir)
+ # Reset to a clean state
+ self._Run(['reset', '--hard', 'HEAD'], options)
+
if (not os.path.exists(self.checkout_path) or
(os.path.isdir(self.checkout_path) and
not os.path.exists(os.path.join(self.checkout_path, '.git')))):
@@ -799,6 +813,12 @@
base_url = self.url
return base_url[:base_url.rfind('/')] + url
+ def GetGitBackupDirPath(self):
+ """Returns the path where the .git folder for the current project can be
+ staged/restored. Use case: subproject moved from DEPS <-> outer project."""
+ return os.path.join(self._root_dir,
+ 'old_' + self.relpath.replace(os.sep, '_')) + '.git'
+
def _GetMirror(self, url, options):
"""Get a git_cache.Mirror object for the argument url."""
if not git_cache.Mirror.GetCachePath():