Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: scm.py

Issue 14064017: Use --internal-diff on svn 1.7+ to slightly reduce disk thrashing. (Closed) Base URL: http://src.chromium.org/svn/trunk/tools/depot_tools/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """SCM-specific utility classes.""" 5 """SCM-specific utility classes."""
6 6
7 import cStringIO 7 import cStringIO
8 import glob 8 import glob
9 import logging 9 import logging
10 import os 10 import os
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 @staticmethod 774 @staticmethod
775 def GenerateDiff(filenames, cwd, full_move, revision): 775 def GenerateDiff(filenames, cwd, full_move, revision):
776 """Returns a string containing the diff for the given file list. 776 """Returns a string containing the diff for the given file list.
777 777
778 The files in the list should either be absolute paths or relative to the 778 The files in the list should either be absolute paths or relative to the
779 given root. If no root directory is provided, the repository root will be 779 given root. If no root directory is provided, the repository root will be
780 used. 780 used.
781 The diff will always use relative paths. 781 The diff will always use relative paths.
782 """ 782 """
783 assert isinstance(filenames, (list, tuple)) 783 assert isinstance(filenames, (list, tuple))
784 # If the user specified a custom diff command in their svn config file,
785 # then it'll be used when we do svn diff, which we don't want to happen
786 # since we want the unified diff.
787 if SVN.AssertVersion("1.7")[0]:
788 # On svn >= 1.7, the "--internal-diff" flag will solve this.
789 return SVN._GenerateDiffInternal(filenames, cwd, full_move, revision,
790 ["diff", "--internal-diff"])
791 else:
792 # On svn < 1.7, the "--internal-diff" flag doesn't exist. Using
793 # --diff-cmd=diff doesn't always work, since e.g. Windows cmd users may
794 # not have a "diff" executable in their path at all. So we use an empty
795 # temporary directory as the config directory, which bypasses any user
796 # settings for the diff-cmd.
797 bogus_dir = tempfile.mkdtemp()
798 try:
799 return SVN._GenerateDiffInternal(filenames, cwd, full_move, revision,
800 ["diff", "--config_dir", bogus_dir])
wtc 2013/04/20 01:16:41 This change breaks the gcl command: $ gcl chang
801 finally:
802 gclient_utils.RemoveDirectory(bogus_dir)
803
804 @staticmethod
805 def _GenerateDiffInternal(filenames, cwd, full_move, revision, diff_command):
784 root = os.path.normcase(os.path.join(cwd, '')) 806 root = os.path.normcase(os.path.join(cwd, ''))
785 def RelativePath(path, root): 807 def RelativePath(path, root):
786 """We must use relative paths.""" 808 """We must use relative paths."""
787 if os.path.normcase(path).startswith(root): 809 if os.path.normcase(path).startswith(root):
788 return path[len(root):] 810 return path[len(root):]
789 return path 811 return path
790 # If the user specified a custom diff command in their svn config file, 812 # Cleanup filenames
791 # then it'll be used when we do svn diff, which we don't want to happen 813 filenames = [RelativePath(f, root) for f in filenames]
792 # since we want the unified diff. Using --diff-cmd=diff doesn't always 814 # Get information about the modified items (files and directories)
793 # work, since e.g. Windows cmd users may not have a "diff" executable in 815 data = dict((f, SVN.CaptureLocalInfo([f], root)) for f in filenames)
794 # their path at all. So we use an empty temporary directory as the config 816 diffs = []
795 # directory, which gets around these problems. 817 if full_move:
796 bogus_dir = tempfile.mkdtemp() 818 # Eliminate modified files inside moved/copied directory.
797 command = ['diff', '--config-dir', bogus_dir] 819 for (filename, info) in data.iteritems():
798 try: 820 if SVN.IsMovedInfo(info) and info.get("Node Kind") == "directory":
799 # Cleanup filenames 821 # Remove files inside the directory.
800 filenames = [RelativePath(f, root) for f in filenames] 822 filenames = [f for f in filenames
801 # Get information about the modified items (files and directories) 823 if not f.startswith(filename + os.path.sep)]
802 data = dict((f, SVN.CaptureLocalInfo([f], root)) for f in filenames) 824 for filename in data.keys():
803 diffs = [] 825 if not filename in filenames:
804 if full_move: 826 # Remove filtered out items.
805 # Eliminate modified files inside moved/copied directory. 827 del data[filename]
806 for (filename, info) in data.iteritems(): 828 else:
807 if SVN.IsMovedInfo(info) and info.get("Node Kind") == "directory": 829 metaheaders = []
808 # Remove files inside the directory. 830 for (filename, info) in data.iteritems():
809 filenames = [f for f in filenames 831 if SVN.IsMovedInfo(info):
810 if not f.startswith(filename + os.path.sep)] 832 # for now, the most common case is a head copy,
811 for filename in data.keys(): 833 # so let's just encode that as a straight up cp.
812 if not filename in filenames: 834 srcurl = info.get('Copied From URL')
813 # Remove filtered out items. 835 file_root = info.get('Repository Root')
814 del data[filename] 836 rev = int(info.get('Copied From Rev'))
815 else: 837 assert srcurl.startswith(file_root)
816 metaheaders = [] 838 src = srcurl[len(file_root)+1:]
817 for (filename, info) in data.iteritems(): 839 try:
818 if SVN.IsMovedInfo(info): 840 srcinfo = SVN.CaptureRemoteInfo(srcurl)
819 # for now, the most common case is a head copy, 841 except subprocess2.CalledProcessError, e:
820 # so let's just encode that as a straight up cp. 842 if not 'Not a valid URL' in e.stderr:
821 srcurl = info.get('Copied From URL') 843 raise
822 file_root = info.get('Repository Root') 844 # Assume the file was deleted. No idea how to figure out at which
823 rev = int(info.get('Copied From Rev')) 845 # revision the file was deleted.
824 assert srcurl.startswith(file_root) 846 srcinfo = {'Revision': rev}
825 src = srcurl[len(file_root)+1:] 847 if (srcinfo.get('Revision') != rev and
826 try: 848 SVN.Capture(diff_command + ['-r', '%d:head' % rev, srcurl], cwd)):
827 srcinfo = SVN.CaptureRemoteInfo(srcurl) 849 metaheaders.append("#$ svn cp -r %d %s %s "
828 except subprocess2.CalledProcessError, e: 850 "### WARNING: note non-trunk copy\n" %
829 if not 'Not a valid URL' in e.stderr: 851 (rev, src, filename))
830 raise 852 else:
831 # Assume the file was deleted. No idea how to figure out at which 853 metaheaders.append("#$ cp %s %s\n" % (src,
832 # revision the file was deleted. 854 filename))
833 srcinfo = {'Revision': rev} 855 if metaheaders:
834 if (srcinfo.get('Revision') != rev and 856 diffs.append("### BEGIN SVN COPY METADATA\n")
835 SVN.Capture(command + ['-r', '%d:head' % rev, srcurl], cwd)): 857 diffs.extend(metaheaders)
836 metaheaders.append("#$ svn cp -r %d %s %s " 858 diffs.append("### END SVN COPY METADATA\n")
837 "### WARNING: note non-trunk copy\n" % 859 # Now ready to do the actual diff.
838 (rev, src, filename)) 860 for filename in sorted(data):
839 else: 861 diffs.append(SVN._DiffItemInternal(
840 metaheaders.append("#$ cp %s %s\n" % (src, 862 filename, cwd, data[filename], diff_command, full_move, revision))
841 filename)) 863 # Use StringIO since it can be messy when diffing a directory move with
842 864 # full_move=True.
843 if metaheaders: 865 buf = cStringIO.StringIO()
844 diffs.append("### BEGIN SVN COPY METADATA\n") 866 for d in filter(None, diffs):
845 diffs.extend(metaheaders) 867 buf.write(d)
846 diffs.append("### END SVN COPY METADATA\n") 868 result = buf.getvalue()
847 # Now ready to do the actual diff. 869 buf.close()
848 for filename in sorted(data): 870 return result
849 diffs.append(SVN._DiffItemInternal(
850 filename, cwd, data[filename], command, full_move, revision))
851 # Use StringIO since it can be messy when diffing a directory move with
852 # full_move=True.
853 buf = cStringIO.StringIO()
854 for d in filter(None, diffs):
855 buf.write(d)
856 result = buf.getvalue()
857 buf.close()
858 return result
859 finally:
860 gclient_utils.RemoveDirectory(bogus_dir)
861 871
862 @staticmethod 872 @staticmethod
863 def _DiffItemInternal(filename, cwd, info, diff_command, full_move, revision): 873 def _DiffItemInternal(filename, cwd, info, diff_command, full_move, revision):
864 """Grabs the diff data.""" 874 """Grabs the diff data."""
865 command = diff_command + [filename] 875 command = diff_command + [filename]
866 if revision: 876 if revision:
867 command.extend(['--revision', revision]) 877 command.extend(['--revision', revision])
868 data = None 878 data = None
869 if SVN.IsMovedInfo(info): 879 if SVN.IsMovedInfo(info):
870 if full_move: 880 if full_move:
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 # revert, like for properties. 1078 # revert, like for properties.
1069 if not os.path.isdir(cwd): 1079 if not os.path.isdir(cwd):
1070 # '.' was deleted. It's not worth continuing. 1080 # '.' was deleted. It's not worth continuing.
1071 return 1081 return
1072 try: 1082 try:
1073 SVN.Capture(['revert', file_status[1]], cwd=cwd) 1083 SVN.Capture(['revert', file_status[1]], cwd=cwd)
1074 except subprocess2.CalledProcessError: 1084 except subprocess2.CalledProcessError:
1075 if not os.path.exists(file_path): 1085 if not os.path.exists(file_path):
1076 continue 1086 continue
1077 raise 1087 raise
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698