Index: trunk/tools/depot_tools/scm.py |
=================================================================== |
--- trunk/tools/depot_tools/scm.py (revision 195420) |
+++ trunk/tools/depot_tools/scm.py (working copy) |
@@ -781,94 +781,84 @@ |
The diff will always use relative paths. |
""" |
assert isinstance(filenames, (list, tuple)) |
- # If the user specified a custom diff command in their svn config file, |
- # then it'll be used when we do svn diff, which we don't want to happen |
- # since we want the unified diff. |
- if SVN.AssertVersion("1.7")[0]: |
- # On svn >= 1.7, the "--internal-diff" flag will solve this. |
- return SVN._GenerateDiffInternal(filenames, cwd, full_move, revision, |
- ["diff", "--internal-diff"]) |
- else: |
- # On svn < 1.7, the "--internal-diff" flag doesn't exist. Using |
- # --diff-cmd=diff doesn't always work, since e.g. Windows cmd users may |
- # not have a "diff" executable in their path at all. So we use an empty |
- # temporary directory as the config directory, which bypasses any user |
- # settings for the diff-cmd. |
- bogus_dir = tempfile.mkdtemp() |
- try: |
- return SVN._GenerateDiffInternal(filenames, cwd, full_move, revision, |
- ["diff", "--config_dir", bogus_dir]) |
- finally: |
- gclient_utils.RemoveDirectory(bogus_dir) |
- |
- @staticmethod |
- def _GenerateDiffInternal(filenames, cwd, full_move, revision, diff_command): |
root = os.path.normcase(os.path.join(cwd, '')) |
def RelativePath(path, root): |
"""We must use relative paths.""" |
if os.path.normcase(path).startswith(root): |
return path[len(root):] |
return path |
- # Cleanup filenames |
- filenames = [RelativePath(f, root) for f in filenames] |
- # Get information about the modified items (files and directories) |
- data = dict((f, SVN.CaptureLocalInfo([f], root)) for f in filenames) |
- diffs = [] |
- if full_move: |
- # Eliminate modified files inside moved/copied directory. |
- for (filename, info) in data.iteritems(): |
- if SVN.IsMovedInfo(info) and info.get("Node Kind") == "directory": |
- # Remove files inside the directory. |
- filenames = [f for f in filenames |
- if not f.startswith(filename + os.path.sep)] |
- for filename in data.keys(): |
- if not filename in filenames: |
- # Remove filtered out items. |
- del data[filename] |
- else: |
- metaheaders = [] |
- for (filename, info) in data.iteritems(): |
- if SVN.IsMovedInfo(info): |
- # for now, the most common case is a head copy, |
- # so let's just encode that as a straight up cp. |
- srcurl = info.get('Copied From URL') |
- file_root = info.get('Repository Root') |
- rev = int(info.get('Copied From Rev')) |
- assert srcurl.startswith(file_root) |
- src = srcurl[len(file_root)+1:] |
- try: |
- srcinfo = SVN.CaptureRemoteInfo(srcurl) |
- except subprocess2.CalledProcessError, e: |
- if not 'Not a valid URL' in e.stderr: |
- raise |
- # Assume the file was deleted. No idea how to figure out at which |
- # revision the file was deleted. |
- srcinfo = {'Revision': rev} |
- if (srcinfo.get('Revision') != rev and |
- SVN.Capture(diff_command + ['-r', '%d:head' % rev, srcurl], cwd)): |
- metaheaders.append("#$ svn cp -r %d %s %s " |
- "### WARNING: note non-trunk copy\n" % |
- (rev, src, filename)) |
- else: |
- metaheaders.append("#$ cp %s %s\n" % (src, |
- filename)) |
- if metaheaders: |
- diffs.append("### BEGIN SVN COPY METADATA\n") |
- diffs.extend(metaheaders) |
- diffs.append("### END SVN COPY METADATA\n") |
- # Now ready to do the actual diff. |
- for filename in sorted(data): |
- diffs.append(SVN._DiffItemInternal( |
- filename, cwd, data[filename], diff_command, full_move, revision)) |
- # Use StringIO since it can be messy when diffing a directory move with |
- # full_move=True. |
- buf = cStringIO.StringIO() |
- for d in filter(None, diffs): |
- buf.write(d) |
- result = buf.getvalue() |
- buf.close() |
- return result |
+ # If the user specified a custom diff command in their svn config file, |
+ # then it'll be used when we do svn diff, which we don't want to happen |
+ # since we want the unified diff. Using --diff-cmd=diff doesn't always |
+ # work, since e.g. Windows cmd users may not have a "diff" executable in |
+ # their path at all. So we use an empty temporary directory as the config |
+ # directory, which gets around these problems. |
+ bogus_dir = tempfile.mkdtemp() |
+ command = ['diff', '--config-dir', bogus_dir] |
+ try: |
+ # Cleanup filenames |
+ filenames = [RelativePath(f, root) for f in filenames] |
+ # Get information about the modified items (files and directories) |
+ data = dict((f, SVN.CaptureLocalInfo([f], root)) for f in filenames) |
+ diffs = [] |
+ if full_move: |
+ # Eliminate modified files inside moved/copied directory. |
+ for (filename, info) in data.iteritems(): |
+ if SVN.IsMovedInfo(info) and info.get("Node Kind") == "directory": |
+ # Remove files inside the directory. |
+ filenames = [f for f in filenames |
+ if not f.startswith(filename + os.path.sep)] |
+ for filename in data.keys(): |
+ if not filename in filenames: |
+ # Remove filtered out items. |
+ del data[filename] |
+ else: |
+ metaheaders = [] |
+ for (filename, info) in data.iteritems(): |
+ if SVN.IsMovedInfo(info): |
+ # for now, the most common case is a head copy, |
+ # so let's just encode that as a straight up cp. |
+ srcurl = info.get('Copied From URL') |
+ file_root = info.get('Repository Root') |
+ rev = int(info.get('Copied From Rev')) |
+ assert srcurl.startswith(file_root) |
+ src = srcurl[len(file_root)+1:] |
+ try: |
+ srcinfo = SVN.CaptureRemoteInfo(srcurl) |
+ except subprocess2.CalledProcessError, e: |
+ if not 'Not a valid URL' in e.stderr: |
+ raise |
+ # Assume the file was deleted. No idea how to figure out at which |
+ # revision the file was deleted. |
+ srcinfo = {'Revision': rev} |
+ if (srcinfo.get('Revision') != rev and |
+ SVN.Capture(command + ['-r', '%d:head' % rev, srcurl], cwd)): |
+ metaheaders.append("#$ svn cp -r %d %s %s " |
+ "### WARNING: note non-trunk copy\n" % |
+ (rev, src, filename)) |
+ else: |
+ metaheaders.append("#$ cp %s %s\n" % (src, |
+ filename)) |
+ if metaheaders: |
+ diffs.append("### BEGIN SVN COPY METADATA\n") |
+ diffs.extend(metaheaders) |
+ diffs.append("### END SVN COPY METADATA\n") |
+ # Now ready to do the actual diff. |
+ for filename in sorted(data): |
+ diffs.append(SVN._DiffItemInternal( |
+ filename, cwd, data[filename], command, full_move, revision)) |
+ # Use StringIO since it can be messy when diffing a directory move with |
+ # full_move=True. |
+ buf = cStringIO.StringIO() |
+ for d in filter(None, diffs): |
+ buf.write(d) |
+ result = buf.getvalue() |
+ buf.close() |
+ return result |
+ finally: |
+ gclient_utils.RemoveDirectory(bogus_dir) |
+ |
@staticmethod |
def _DiffItemInternal(filename, cwd, info, diff_command, full_move, revision): |
"""Grabs the diff data.""" |