Chromium Code Reviews| Index: scm.py |
| =================================================================== |
| --- scm.py (revision 195308) |
| +++ scm.py (working copy) |
| @@ -781,84 +781,94 @@ |
| 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]) |
|
wtc
2013/04/20 01:16:41
This change breaks the gcl command:
$ gcl chang
|
| + 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 |
| - # 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)) |
| + # 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 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.""" |