- sign_str = None
-
- files = [path for (stat,path) in git.tree_status(verbose = True)]
- if args:
- files = [f for f in files if f in args]
-
- if files or not crt_series.head_top_equal() \
- or options.edit or options.message \
- or options.authname or options.authemail or options.authdate \
- or options.commname or options.commemail \
- or options.sign or options.ack:
-
- if options.patch:
- applied = crt_series.get_applied()
- between = applied[:applied.index(patch):-1]
- pop_patches(between, keep = True)
- elif options.update:
- rev1 = git_id('//bottom')
- rev2 = git_id('//top')
- patch_files = git.barefiles(rev1, rev2).split('\n')
- files = [f for f in files if f in patch_files]
- if not files:
- out.info('No modified files for updating patch "%s"' % patch)
- return
-
- out.start('Refreshing patch "%s"' % patch)
-
- if autoresolved == 'yes':
- resolved_all()
- crt_series.refresh_patch(files = files,
- message = options.message,
- edit = options.edit,
- show_patch = options.showpatch,
- author_name = options.authname,
- author_email = options.authemail,
- author_date = options.authdate,
- committer_name = options.commname,
- committer_email = options.commemail,
- backup = True, sign_str = sign_str,
- notes = options.annotate)
-
- if crt_series.empty_patch(patch):
- out.done('empty patch')
- else:
- out.done()
-
- if options.patch:
- between.reverse()
- push_patches(between)
- elif options.annotate:
- # only annotate the top log entry as there is no need to
- # refresh the patch and generate a full commit
- crt_series.log_patch(crt_series.get_patch(patch), None,
- notes = options.annotate)
+ return go(stack.repository.default_index)
+
+def make_temp_patch(stack, patch_name, paths, temp_index):
+ """Commit index to temp patch, in a complete transaction. If any path
+ limiting is in effect, use a temp index."""
+ tree = write_tree(stack, paths, temp_index)
+ commit = stack.repository.commit(git.CommitData(
+ tree = tree, parents = [stack.head],
+ message = 'Refresh of %s' % patch_name))
+ temp_name = utils.make_patch_name('refresh-temp', stack.patches.exists)
+ trans = transaction.StackTransaction(stack,
+ 'refresh (create temporary patch)')
+ trans.patches[temp_name] = commit
+ trans.applied.append(temp_name)
+ return trans.run(stack.repository.default_iw,
+ print_current_patch = False), temp_name
+
+def absorb_applied(trans, iw, patch_name, temp_name, edit_fun):
+ """Absorb the temp patch (C{temp_name}) into the given patch
+ (C{patch_name}), which must be applied. If the absorption
+ succeeds, call C{edit_fun} on the resulting
+ L{CommitData<stgit.lib.git.CommitData>} before committing it and
+ commit the return value.
+
+ @return: C{True} if we managed to absorb the temp patch, C{False}
+ if we had to leave it for the user to deal with."""
+ temp_absorbed = False
+ try:
+ # Pop any patch on top of the patch we're refreshing.
+ to_pop = trans.applied[trans.applied.index(patch_name)+1:]
+ if len(to_pop) > 1:
+ popped = trans.pop_patches(lambda pn: pn in to_pop)
+ assert not popped # no other patches were popped
+ trans.push_patch(temp_name, iw)
+ assert to_pop.pop() == temp_name
+
+ # Absorb the temp patch.
+ temp_cd = trans.patches[temp_name].data
+ assert trans.patches[patch_name] == temp_cd.parent
+ trans.patches[patch_name] = trans.stack.repository.commit(
+ edit_fun(trans.patches[patch_name].data.set_tree(temp_cd.tree)))
+ popped = trans.delete_patches(lambda pn: pn == temp_name, quiet = True)
+ assert not popped # the temp patch was topmost
+ temp_absorbed = True
+
+ # Push back any patch we were forced to pop earlier.
+ for pn in to_pop:
+ trans.push_patch(pn, iw)
+ except transaction.TransactionHalted:
+ pass
+ return temp_absorbed
+
+def absorb_unapplied(trans, iw, patch_name, temp_name, edit_fun):
+ """Absorb the temp patch (C{temp_name}) into the given patch
+ (C{patch_name}), which must be unapplied. If the absorption
+ succeeds, call C{edit_fun} on the resulting
+ L{CommitData<stgit.lib.git.CommitData>} before committing it and
+ commit the return value.
+
+ @param iw: Not used.
+ @return: C{True} if we managed to absorb the temp patch, C{False}
+ if we had to leave it for the user to deal with."""
+
+ # Pop the temp patch.
+ popped = trans.pop_patches(lambda pn: pn == temp_name)
+ assert not popped # the temp patch was topmost
+
+ # Try to create the new tree of the refreshed patch. (This is the
+ # same operation as pushing the temp patch onto the patch we're
+ # trying to refresh -- but we don't have a worktree to spill
+ # conflicts to, so if the simple merge doesn't succeed, we have to
+ # give up.)
+ patch_cd = trans.patches[patch_name].data
+ temp_cd = trans.patches[temp_name].data
+ new_tree = trans.stack.repository.simple_merge(
+ base = temp_cd.parent.data.tree,
+ ours = patch_cd.tree, theirs = temp_cd.tree)
+ if new_tree:
+ # It worked. Refresh the patch with the new tree, and delete
+ # the temp patch.
+ trans.patches[patch_name] = trans.stack.repository.commit(
+ edit_fun(patch_cd.set_tree(new_tree)))
+ popped = trans.delete_patches(lambda pn: pn == temp_name, quiet = True)
+ assert not popped # the temp patch was not applied
+ return True