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.""" |