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

Unified Diff: patch.py

Issue 8038056: Fix handling of file renames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Rebase against HEAD Created 9 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « checkout.py ('k') | tests/checkout_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: patch.py
diff --git a/patch.py b/patch.py
index 8b0407fab0aaec979a2d66b5a86d1b4484e1c820..4c96de3561339925048cd4398b3636191634b599 100644
--- a/patch.py
+++ b/patch.py
@@ -32,6 +32,7 @@ class FilePatchBase(object):
is_new = False
def __init__(self, filename):
+ assert self.__class__ is not FilePatchBase
self.filename = self._process_filename(filename)
# Set when the file is copied or moved.
self.source_filename = None
@@ -50,9 +51,6 @@ class FilePatchBase(object):
filename, 'Filename can\'t start with \'%s\'.' % i)
return filename
- def get(self): # pragma: no coverage
- raise NotImplementedError('Nothing to grab')
-
def set_relpath(self, relpath):
if not relpath:
return
@@ -69,6 +67,27 @@ class FilePatchBase(object):
"""Shortcut function to raise UnsupportedPatchFormat."""
raise UnsupportedPatchFormat(self.filename, msg)
+ def __str__(self):
+ # Use a status-like board.
+ out = ''
+ if self.is_binary:
+ out += 'B'
+ else:
+ out += ' '
+ if self.is_delete:
+ out += 'D'
+ else:
+ out += ' '
+ if self.is_new:
+ out += 'N'
+ else:
+ out += ' '
+ if self.source_filename:
+ out += 'R'
+ else:
+ out += ' '
+ return out + ' %s->%s' % (self.source_filename, self.filename)
+
class FilePatchDelete(FilePatchBase):
"""Deletes a file."""
@@ -78,9 +97,6 @@ class FilePatchDelete(FilePatchBase):
super(FilePatchDelete, self).__init__(filename)
self.is_binary = is_binary
- def get(self):
- raise NotImplementedError('Nothing to grab')
-
class FilePatchBinary(FilePatchBase):
"""Content of a new binary file."""
@@ -111,9 +127,18 @@ class FilePatchDiff(FilePatchBase):
self._verify_git_header()
else:
self._verify_svn_header()
+ if self.source_filename and not self.is_new:
+ self._fail('If source_filename is set, is_new must be also be set')
- def get(self):
- return self.diff_header + self.diff_hunks
+ def get(self, for_git):
+ if for_git or not self.source_filename:
+ return self.diff_header + self.diff_hunks
+ else:
+ # patch is stupid. It patches the source_filename instead so get rid of
+ # any source_filename reference if needed.
+ return (
+ self.diff_header.replace(self.source_filename, self.filename) +
+ self.diff_hunks)
def set_relpath(self, relpath):
old_filename = self.filename
@@ -264,6 +289,7 @@ class FilePatchDiff(FilePatchBase):
(match.group(1), line))
return
+ # Ignore "deleted file mode 100644" since it's not needed.
match = re.match(r'^new(| file) mode (\d{6})$', line)
if match:
mode = match.group(2)
@@ -356,10 +382,23 @@ class PatchSet(object):
"""A list of FilePatch* objects."""
def __init__(self, patches):
- self.patches = patches
- for p in self.patches:
+ for p in patches:
assert isinstance(p, FilePatchBase)
+ def key(p):
+ """Sort by ordering of application.
+
+ File move are first.
+ Deletes are last.
+ """
+ if p.source_filename:
+ return (p.is_delete, p.source_filename, p.filename)
+ else:
+ # tuple are always greater than string, abuse that fact.
+ return (p.is_delete, (p.filename,), p.filename)
+
+ self.patches = sorted(patches, key=key)
+
def set_relpath(self, relpath):
"""Used to offset the patch into a subdirectory."""
for patch in self.patches:
@@ -369,6 +408,9 @@ class PatchSet(object):
for patch in self.patches:
yield patch
+ def __getitem__(self, key):
+ return self.patches[key]
+
@property
def filenames(self):
return [p.filename for p in self.patches]
« no previous file with comments | « checkout.py ('k') | tests/checkout_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698