When simplifying to rebase, relax the ff requirement.

When simplifying an incremental merge of BRANCH onto MASTER into a
rebase, a simplification with --branch=BRANCH would fail because
updating BRANCH to the result of the rebase is not a fast-forward
update.

But when doing a rebase, the user typically *wants* to discard the old
versions of the commits on BRANCH (just like with "git rebase").  So
allow such a simplification even if the reference update is not a
fast-forward, *provided* that the apex of the incremental merge (i.e.,
before the simplification) is a descendant of the commit pointed to by
the old value of the reference being pointed at the result.
This commit is contained in:
Michael Haggerty 2013-10-11 07:34:45 +02:00
parent f3523f6e83
commit eca0a79e29
2 changed files with 20 additions and 6 deletions

View File

@ -30,11 +30,6 @@ Convenience features
manual merge conflicts into suggested log messages for the
simplified commits.
* For "simplify --goal=rebase", relax the requirement that the final
result be a fast-forward of its original value. Instead, require
only that *the final incremental merge* commit (i.e., before
simplification) be a fast-forward of the original reference.
* Maybe remember the names of the two original branches for use in log
messages etc. (Should they be stored locally in ``git config`` or
shareably in the state blob?)

View File

@ -2279,6 +2279,23 @@ class MergeState(Block):
% (i1, i2)
)
if not force:
# A rebase simplification is allowed to discard history,
# as long as the *pre-simplification* apex commit is a
# descendant of the branch to be moved.
try:
ref_oldval = get_commit_sha1(refname)
except ValueError:
# refname doesn't already exist; no problem.
pass
else:
commit = self[-1, -1].sha1
if not MergeState._is_ancestor(ref_oldval, commit):
raise Failure(
'%s is not an ancestor of %s; use --force if you are sure'
% (commit, refname,)
)
commit = self[i1, 0].sha1
for i2 in range(1, self.len2):
orig = self[0, i2].sha1
@ -2290,7 +2307,9 @@ class MergeState(Block):
tree, [commit], msg=get_log_message(orig), metadata=authordata,
)
self._set_refname(refname, commit, force=force)
# We checked above that the update is OK, so here we can set
# force=True:
self._set_refname(refname, commit, force=True)
def simplify_to_merge(self, refname, force=False):
if not (-1, -1) in self: