Mercurial > hg
comparison hgext/rebase.py @ 24998:c8a97fa742b7
rebase: use dirstateguard instead of dirstate.invalidate
Before this patch, "rebase.concludenode()" uses "dirstate.invalidate()"
as a kind of "restore .hg/dirstate to the original status" during a failure.
But it just discards changes in memory, and doesn't actually restore
".hg/dirstate". Then, it can't work as expected, if "dirstate.write()"
is executed while processing.
This patch uses "dirstateguard" instead of "dirstate.invalidate()" to
restore ".hg/dirstate" during a failure even if "dirstate.write()" is
executed before a failure.
This patch also removes "beginparentchage()" and "endparentchange()",
because "dirstateguard" makes them useless.
This is a part of preparations to fix the issue that the recent (in
memory) dirstate isn't visible to external processes (e.g. "precommit"
hook).
After this patch, the changed dirstate becomes visible to external
"precommit" hooks during "hg rebase" in "test-largefiles-misc.t",
because "dirstateguard()" writes it out. But this content isn't yet
correct, because:
- "normal3" should be marked as "A"(dded) at committing
It is newly added in the changeset being rebased.
- but it is marked as "M"(odified)
The result of "repo.setparents()" after "dirstateguard()" isn't
yet written out before "precommit". So, merging is still in
progress for "hg status" in it.
This causes marking the file newly added on "other" branch as "A".
This will be fixed by subsequent patch.
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Thu, 07 May 2015 12:07:11 +0900 |
parents | a02d293a1079 |
children | 72f7f98bc5e5 |
comparison
equal
deleted
inserted
replaced
24997:12f3c7144a39 | 24998:c8a97fa742b7 |
---|---|
528 | 528 |
529 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None): | 529 def concludenode(repo, rev, p1, p2, commitmsg=None, editor=None, extrafn=None): |
530 '''Commit the wd changes with parents p1 and p2. Reuse commit info from rev | 530 '''Commit the wd changes with parents p1 and p2. Reuse commit info from rev |
531 but also store useful information in extra. | 531 but also store useful information in extra. |
532 Return node of committed revision.''' | 532 Return node of committed revision.''' |
533 dsguard = cmdutil.dirstateguard(repo, 'rebase') | |
533 try: | 534 try: |
534 repo.dirstate.beginparentchange() | |
535 repo.setparents(repo[p1].node(), repo[p2].node()) | 535 repo.setparents(repo[p1].node(), repo[p2].node()) |
536 repo.dirstate.endparentchange() | |
537 ctx = repo[rev] | 536 ctx = repo[rev] |
538 if commitmsg is None: | 537 if commitmsg is None: |
539 commitmsg = ctx.description() | 538 commitmsg = ctx.description() |
540 extra = {'rebase_source': ctx.hex()} | 539 extra = {'rebase_source': ctx.hex()} |
541 if extrafn: | 540 if extrafn: |
550 date=ctx.date(), extra=extra, editor=editor) | 549 date=ctx.date(), extra=extra, editor=editor) |
551 finally: | 550 finally: |
552 repo.ui.restoreconfig(backup) | 551 repo.ui.restoreconfig(backup) |
553 | 552 |
554 repo.dirstate.setbranch(repo[newnode].branch()) | 553 repo.dirstate.setbranch(repo[newnode].branch()) |
554 dsguard.close() | |
555 return newnode | 555 return newnode |
556 except util.Abort: | 556 finally: |
557 # Invalidate the previous setparents | 557 release(dsguard) |
558 repo.dirstate.invalidate() | |
559 raise | |
560 | 558 |
561 def rebasenode(repo, rev, p1, base, state, collapse, target): | 559 def rebasenode(repo, rev, p1, base, state, collapse, target): |
562 'Rebase a single revision rev on top of p1 using base as merge ancestor' | 560 'Rebase a single revision rev on top of p1 using base as merge ancestor' |
563 # Merge phase | 561 # Merge phase |
564 # Update to target and merge it with local | 562 # Update to target and merge it with local |