+ # We've just caused conflicts, so we must allow them in
+ # the final checkout.
+ self.__allow_conflicts = lambda trans: True
+
+ # Save this update so that we can run it a little later.
+ self.__conflicting_push = update
+ self.__halt("%d merge conflict(s)" % len(self.__conflicts))
+ else:
+ # Update immediately.
+ update()
+
+ def push_tree(self, pn):
+ """Push the named patch without updating its tree."""
+ orig_cd = self.patches[pn].data
+ cd = orig_cd.set_committer(None).set_parent(self.top)
+
+ s = ''
+ if any(getattr(cd, a) != getattr(orig_cd, a) for a in
+ ['parent', 'tree', 'author', 'message']):
+ self.patches[pn] = self.__stack.repository.commit(cd)
+ else:
+ s = ' (unmodified)'
+ if cd.is_nochange():
+ s = ' (empty)'
+ out.info('Pushed %s%s' % (pn, s))
+
+ if pn in self.hidden:
+ x = self.hidden
+ else:
+ x = self.unapplied
+ del x[x.index(pn)]
+ self.applied.append(pn)
+
+ def reorder_patches(self, applied, unapplied, hidden = None, iw = None):
+ """Push and pop patches to attain the given ordering."""
+ if hidden is None:
+ hidden = self.hidden
+ common = len(list(it.takewhile(lambda (a, b): a == b,
+ zip(self.applied, applied))))
+ to_pop = set(self.applied[common:])
+ self.pop_patches(lambda pn: pn in to_pop)
+ for pn in applied[common:]:
+ self.push_patch(pn, iw)
+ assert self.applied == applied
+ assert set(self.unapplied + self.hidden) == set(unapplied + hidden)
+ self.unapplied = unapplied
+ self.hidden = hidden
+
+ def check_merged(self, patches):
+ """Return a subset of patches already merged."""
+ out.start('Checking for patches merged upstream')
+ merged = []
+ if self.temp_index_tree != self.stack.head.data.tree:
+ self.temp_index.read_tree(self.stack.head.data.tree)
+ self.temp_index_tree = self.stack.head.data.tree
+ for pn in reversed(patches):
+ # check whether patch changes can be reversed in the current index
+ cd = self.patches[pn].data
+ if cd.is_nochange():
+ continue
+ try:
+ self.temp_index.apply_treediff(cd.tree, cd.parent.data.tree,
+ quiet = True)
+ merged.append(pn)
+ # The self.temp_index was modified by apply_treediff() so
+ # force read_tree() the next time merge() is used.
+ self.temp_index_tree = None
+ except git.MergeException:
+ pass
+ out.done('%d found' % len(merged))
+ return merged