diff --git a/scm.py b/scm.py index 3481219ba..7a6f66422 100644 --- a/scm.py +++ b/scm.py @@ -4,6 +4,7 @@ """SCM-specific utility classes.""" +import glob import os import re import shutil @@ -19,6 +20,26 @@ def ValidateEmail(email): is not None) +def GetCasedPath(path): + """Elcheapos way to get the real path case on Windows.""" + if sys.platform.startswith('win') and os.path.exists(path): + # Reconstruct the path. + path = os.path.abspath(path) + paths = path.split('\\') + for i in range(len(paths)): + if i == 0: + # Skip drive letter. + continue + subpath = '\\'.join(paths[:i+1]) + prev = len('\\'.join(paths[:i])) + # glob.glob will return the cased path for the last item only. This is why + # we are calling it in a loop. Extract the data we want and put it back + # into the list. + paths[i] = glob.glob(subpath + '*')[0][prev+1:len(subpath)] + path = '\\'.join(paths) + return path + + class GIT(object): COMMAND = "git" @@ -587,7 +608,6 @@ class SVN(object): file_content = ['+' + i for i in file_content.splitlines(True)] nb_lines = len(file_content) # We need to use / since patch on unix will fail otherwise. - filename = filename.replace('\\', '/') data = "Index: %s\n" % filename data += '=' * 67 + '\n' # Note: Should we use /dev/null instead? @@ -616,10 +636,11 @@ class SVN(object): The diff will always use relative paths. """ previous_cwd = os.getcwd() - root = os.path.join(root or SVN.GetCheckoutRoot(previous_cwd), '') + root = root or SVN.GetCheckoutRoot(previous_cwd) + root = os.path.normcase(os.path.join(root, '')) def RelativePath(path, root): """We must use relative paths.""" - if path.startswith(root): + if os.path.normcase(path).startswith(root): return path[len(root):] return path try: @@ -707,4 +728,4 @@ class SVN(object): "Repository Root") != cur_dir_repo_root): break directory = parent - return directory + return GetCasedPath(directory) diff --git a/tests/scm_unittest.py b/tests/scm_unittest.py index aa3288d17..14c1bc62e 100755 --- a/tests/scm_unittest.py +++ b/tests/scm_unittest.py @@ -24,9 +24,9 @@ class RootTestCase(BaseSCMTestCase): def testMembersChanged(self): self.mox.ReplayAll() members = [ - 'GIT', 'SVN', 'ValidateEmail', - 'gclient_utils', 'os', 're', 'shutil', 'subprocess', 'sys', 'tempfile', - 'xml', + 'GetCasedPath', 'GIT', 'SVN', 'ValidateEmail', + 'gclient_utils', 'glob', 'os', 're', 'shutil', 'subprocess', 'sys', + 'tempfile', 'xml', ] # If this test fails, you should add the relevant test. self.compareMembers(scm, members) @@ -153,7 +153,9 @@ class SVNTestCase(BaseSCMTestCase): def testGetCheckoutRoot(self): self.mox.StubOutWithMock(scm.SVN, 'CaptureInfo') + self.mox.StubOutWithMock(scm, 'GetCasedPath') scm.os.path.abspath(self.root_dir + 'x').AndReturn(self.root_dir) + scm.GetCasedPath(self.root_dir).AndReturn(self.root_dir) result1 = { "Repository Root": "Some root" } scm.SVN.CaptureInfo(self.root_dir, print_error=False).AndReturn(result1) results2 = { "Repository Root": "A different root" } diff --git a/trychange.py b/trychange.py index 4bce7a15d..a48a658df 100755 --- a/trychange.py +++ b/trychange.py @@ -568,7 +568,8 @@ def TryChange(argv, path_diff = gclient_utils.PathDifference(root, checkout.checkout_root) for i in range(len(diff)): if diff[i].startswith('--- ') or diff[i].startswith('+++ '): - diff[i] = diff[i][0:4] + posixpath.join(path_diff, diff[i][4:]) + new_file = posixpath.join(path_diff, diff[i][4:]).replace('\\', '/') + diff[i] = diff[i][0:4] + new_file diffs.extend(diff) options.diff = ''.join(diffs)