diff --git a/gcl.py b/gcl.py index 5d14793784..4258f400eb 100755 --- a/gcl.py +++ b/gcl.py @@ -65,18 +65,9 @@ def GetRepositoryRoot(): """ global REPOSITORY_ROOT if not REPOSITORY_ROOT: - infos = SVN.CaptureInfo(os.getcwd(), print_error=False) - cur_dir_repo_root = infos.get("Repository Root") - if not cur_dir_repo_root: + REPOSITORY_ROOT = SVN.GetCheckoutRoot(os.getcwd()) + if not REPOSITORY_ROOT: raise gclient_utils.Error("gcl run outside of repository") - - REPOSITORY_ROOT = os.getcwd() - while True: - parent = os.path.dirname(REPOSITORY_ROOT) - if (SVN.CaptureInfo(parent, print_error=False).get( - "Repository Root") != cur_dir_repo_root): - break - REPOSITORY_ROOT = parent return REPOSITORY_ROOT diff --git a/scm.py b/scm.py index 8dc127e33e..96ae2647c6 100644 --- a/scm.py +++ b/scm.py @@ -486,3 +486,22 @@ class SVN(object): break values[key] = value return values + + @staticmethod + def GetCheckoutRoot(directory): + """Returns the top level directory of the current repository. + + The directory is returned as an absolute path. + """ + infos = SVN.CaptureInfo(directory, print_error=False) + cur_dir_repo_root = infos.get("Repository Root") + if not cur_dir_repo_root: + return None + + while True: + parent = os.path.dirname(directory) + if (SVN.CaptureInfo(parent, print_error=False).get( + "Repository Root") != cur_dir_repo_root): + break + directory = parent + return directory diff --git a/tests/gcl_unittest.py b/tests/gcl_unittest.py index e598312067..64f5f63427 100755 --- a/tests/gcl_unittest.py +++ b/tests/gcl_unittest.py @@ -75,7 +75,6 @@ class GclUnittest(GclTestsBase): gcl.os.getcwd().AndReturn(root_path) result1 = { "Repository Root": "Some root" } gcl.SVN.CaptureInfo(root_path, print_error=False).AndReturn(result1) - gcl.os.getcwd().AndReturn(root_path) results2 = { "Repository Root": "A different root" } gcl.SVN.CaptureInfo(gcl.os.path.dirname(root_path), print_error=False).AndReturn(results2) diff --git a/tests/gclient_scm_test.py b/tests/gclient_scm_test.py index 99b4a9e1ce..f86231947a 100755 --- a/tests/gclient_scm_test.py +++ b/tests/gclient_scm_test.py @@ -65,7 +65,7 @@ class SVNWrapperTestCase(BaseTestCase): def testDir(self): members = [ 'COMMAND', 'Capture', 'CaptureHeadRevision', 'CaptureInfo', - 'CaptureStatus', 'DiffItem', 'GetEmail', + 'CaptureStatus', 'DiffItem', 'GetCheckoutRoot', 'GetEmail', 'GetFileProperty', 'IsMoved', 'ReadSimpleAuth', 'Run', 'RunAndFilterOutput', 'RunAndGetFileList', 'RunCommand', 'cleanup', 'diff', 'export', 'pack', 'relpath', 'revert', diff --git a/tests/scm_unittest.py b/tests/scm_unittest.py index 5d5fa97b92..fc05677405 100755 --- a/tests/scm_unittest.py +++ b/tests/scm_unittest.py @@ -139,7 +139,8 @@ class SVNTestCase(BaseSCMTestCase): self.mox.ReplayAll() members = [ 'COMMAND', 'Capture', 'CaptureHeadRevision', 'CaptureInfo', - 'CaptureStatus', 'DiffItem', 'GetEmail', 'GetFileProperty', 'IsMoved', + 'CaptureStatus', 'DiffItem', 'GetCheckoutRoot', 'GetEmail', + 'GetFileProperty', 'IsMoved', 'ReadSimpleAuth', 'Run', 'RunAndFilterOutput', 'RunAndGetFileList', ] # If this test fails, you should add the relevant test. diff --git a/trychange.py b/trychange.py index 39af71ed0e..691c67de28 100755 --- a/trychange.py +++ b/trychange.py @@ -138,10 +138,7 @@ class SVN(SCM): used. """ previous_cwd = os.getcwd() - if root is None: - os.chdir(gcl.GetRepositoryRoot()) - else: - os.chdir(root) + os.chdir(root or scm.SVN.GetCheckoutRoot(previous_cwd)) # Directories will return None so filter them out. diff = filter(None, [scm.SVN.DiffItem(f) for f in files]) @@ -157,19 +154,23 @@ class SVN(SCM): return self.change_info.GetLocalRoot() def ProcessOptions(self): + checkout_root = None if not self.options.diff: # Generate the diff with svn and write it to the submit queue path. The # files are relative to the repository root, but we need patches relative # to one level up from there (i.e., 'src'), so adjust both the file # paths and the root of the diff. + # TODO(maruel): Remove this hack. source_root = GetSourceRoot() - prefix = PathDifference(source_root, gcl.GetRepositoryRoot()) + checkout_root = scm.SVN.GetCheckoutRoot(os.getcwd()) + prefix = PathDifference(source_root, checkout_root) adjusted_paths = [os.path.join(prefix, x) for x in self.options.files] self.options.diff = self.GenerateDiff(adjusted_paths, root=source_root) self.change_info = gcl.LoadChangelistInfoForMultiple(self.options.name, gcl.GetRepositoryRoot(), True, True) if not self.options.email: - self.options.email = scm.SVN.GetEmail(gcl.GetRepositoryRoot()) + checkout_root = checkout_root or scm.SVN.GetCheckoutRoot(os.getcwd()) + self.options.email = scm.SVN.GetEmail(checkout_root) class GIT(SCM):