The advantage is that patch application will resolve some file content
conflicts for us, so that we'll fall back to merge-recursive less
often. This is a significant speedup, especially since merge-recursive
needs to touch the worktree, which means we have to check out the
index first.
(A simple test, pushing 250 patches in a 32k-file repository, with one
file-level merge necessary per push, went from 1.07 to 0.36 seconds
per patch with this patch applied.)
Signed-off-by: Karl Hasselström <kha@treskal.com>
return ours
index = self.temp_index()
return ours
index = self.temp_index()
- index.merge(base, ours, theirs)
+ index.apply_treediff(base, theirs, quiet = True)
return index.write_tree()
except MergeException:
return None
return index.write_tree()
except MergeException:
return None
return False
else:
return True
return False
else:
return True
- def merge(self, base, ours, theirs):
- """In-index merge, no worktree involved."""
- self.run(['git', 'read-tree', '-m', '-i', '--aggressive',
- base.sha1, ours.sha1, theirs.sha1]).no_output()
def apply(self, patch_text, quiet):
"""In-index patch application, no worktree involved."""
try:
def apply(self, patch_text, quiet):
"""In-index patch application, no worktree involved."""
try:
r.no_output()
except run.RunException:
raise MergeException('Patch does not apply cleanly')
r.no_output()
except run.RunException:
raise MergeException('Patch does not apply cleanly')
+ def apply_treediff(self, tree1, tree2, quiet):
+ """Apply the diff from C{tree1} to C{tree2} to the index."""
+ # Passing --full-index here is necessary to support binary
+ # files. It is also sufficient, since the repository already
+ # contains all involved objects; in other words, we don't have
+ # to use --binary.
+ self.apply(self.__repository.diff_tree(tree1, tree2, ['--full-index']),
+ quiet)
def delete(self):
if os.path.isfile(self.__filename):
os.remove(self.__filename)
def delete(self):
if os.path.isfile(self.__filename):
os.remove(self.__filename)