[PATCH 1 of 2] rebase: update branchcache before stripping (issue1951)

Stefano Tortarolo stefano.tortarolo at gmail.com
Fri Feb 12 08:39:42 CST 2010


# HG changeset patch
# User Stefano Tortarolo <stefano.tortarolo at gmail.com>
# Date 1265884017 -3600
# Node ID 4ecbf4018d6f473ad2a68f668f94731a4510cd82
# Parent  4cfd0d56be6dcbcfac90bf95e8f8750ab66fd9aa
rebase: update branchcache before stripping (issue1951)

In issue1951 rebase tries to strip the old revisions using an outdated
branchcache. This patch updates the branchcache removing references to
old named branches when revisions are moved to another named branch.

diff --git a/hgext/rebase.py b/hgext/rebase.py
--- a/hgext/rebase.py
+++ b/hgext/rebase.py
@@ -172,6 +172,8 @@
                     ui.warn(_("warning: new changesets detected on source branch, "
                                                             "not stripping\n"))
                 else:
+                    if not keepbranchesf:
+                        updatebranchcache(repo, state, rebased)
                     repair.strip(ui, repo, repo[min(rebased)].node(), "strip")
 
         clearstatus(repo)
@@ -183,6 +185,32 @@
     finally:
         release(lock, wlock)
 
+def updatebranchcache(repo, state, rebased):
+    """update repo's branchcache because after a rebasing the old branchcache
+    could still store references to revision moved to another branch. """
+    repo.ui.debug('updating branchcache\n')
+    branchmap = repo.branchmap()
+    # Remove rebased revisions from the old branchmap
+    for rev in rebased:
+        branch = repo[rev].branch()
+        if (branch in branchmap
+                and repo[rev].node() in branchmap[branch]):
+            repo.ui.debug('removing %d from branch %s\n' %
+                                (repo[rev].rev(), branch))
+            branchmap[branch].remove(repo[rev].node())
+    # Check whether the new branch's head should be the last nullmerged revision
+    nullmerged = set(state) - set(rebased)
+    if nullmerged:
+        newhead = repo[max(nullmerged)]
+        if not branchmap[newhead.branch()]:
+            branchmap[newhead.branch()].append(newhead.node())
+    # Remove references to empty branches
+    for branch in branchmap.keys():
+        if not branchmap[branch]:
+            repo.ui.note('removing empty branch %s\n' % branch)
+            del branchmap[branch]
+    repo.ui.debug('branchcache updated\n')
+
 def rebasemerge(repo, rev, first=False):
     'return the correct ancestor'
     oldancestor = ancestor.ancestor
diff --git a/tests/test-rebase-cache b/tests/test-rebase-cache
new file mode 100755
--- /dev/null
+++ b/tests/test-rebase-cache
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+createrepo() {
+    rm -rf repo
+    hg init repo
+    cd repo
+
+    echo "a" > a
+    hg commit -d '0 0' -A -m 'A'
+
+    hg branch branch1
+    hg commit -d '1 0' -m 'Branch1'
+
+    echo "b" > b
+    hg commit -A -d '2 0' -m 'B'
+
+    hg up 0
+    hg branch branch2
+    hg commit -d '3 0' -m 'Branch2'
+
+    echo "c" > C
+    hg commit -A -d '4 0' -m 'C'
+
+    hg up 2
+    hg branch -f branch2
+    echo "d" > d
+    hg commit -A -d '5 0' -m 'D'
+
+    echo "e" > e
+    hg commit -A -d '6 0' -m 'E'
+
+    hg update default
+
+    hg branch branch3
+    hg commit -d '7 0' -m 'Branch3'
+
+    echo "f" > f
+    hg commit -A -d '8 0' -m 'F'
+}
+
+echo
+createrepo > /dev/null 2>&1
+hg --config extensions.hgext.graphlog= glog --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+echo
+echo '% Branches'
+hg branches
+
+echo
+echo '% Heads'
+hg heads --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+echo
+echo '% Rebase part of branch2 (5-6) onto branch3 (8)'
+hg --config extensions.hgext.rebase= rebase --detach -s 5 -d 8 2>&1 | sed 's/\(saving bundle to \).*/\1/'
+
+echo
+echo '% Branches'
+hg branches
+
+echo
+echo '% Heads'
+hg heads --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+echo
+hg --config extensions.hgext.graphlog= glog --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+echo
+echo '% Rebase head of branch3 (8) onto branch2 (6)'
+createrepo > /dev/null 2>&1
+hg --config extensions.hgext.graphlog= glog --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+hg --config extensions.hgext.rebase= rebase --detach -s 8 -d 6 2>&1 | sed 's/\(saving bundle to \).*/\1/'
+
+echo
+echo '% Branches'
+hg branches
+
+echo
+echo '% Heads'
+hg heads --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+echo
+hg --config extensions.hgext.graphlog= glog --template '{rev}:{node|short} {desc} branch: {branches}\n'
+hg verify -q
+
+echo
+echo '% Rebase entire branch3 (7-8) onto branch2 (6)'
+createrepo > /dev/null 2>&1
+hg --config extensions.hgext.graphlog= glog --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+hg --config extensions.hgext.rebase= rebase --detach -s 7 -d 6 2>&1 | sed 's/\(saving bundle to \).*/\1/'
+
+echo
+echo '% Branches'
+hg branches
+
+echo
+echo '% Heads'
+hg heads --template '{rev}:{node|short} {desc} branch: {branches}\n'
+
+echo
+hg --config extensions.hgext.graphlog= glog --template '{rev}:{node|short} {desc} branch: {branches}\n'
+hg verify -q
diff --git a/tests/test-rebase-cache.out b/tests/test-rebase-cache.out
new file mode 100644
--- /dev/null
+++ b/tests/test-rebase-cache.out
@@ -0,0 +1,186 @@
+
+@  8:c11d5b3e9c00 F branch: branch3
+|
+o  7:33c9da881988 Branch3 branch: branch3
+|
+| o  6:0e4064ab11a3 E branch: branch2
+| |
+| o  5:5ac035cb5d8f D branch: branch2
+| |
+| | o  4:8e66061486ee C branch: branch2
+| | |
++---o  3:99567862abbe Branch2 branch: branch2
+| |
+| o  2:65a26a4d12f6 B branch: branch1
+| |
+| o  1:0f3f3010ee16 Branch1 branch: branch1
+|/
+o  0:1994f17a630e A branch:
+
+
+% Branches
+branch3                        8:c11d5b3e9c00
+branch2                        6:0e4064ab11a3
+branch1                        2:65a26a4d12f6 (inactive)
+default                        0:1994f17a630e (inactive)
+
+% Heads
+8:c11d5b3e9c00 F branch: branch3
+6:0e4064ab11a3 E branch: branch2
+4:8e66061486ee C branch: branch2
+2:65a26a4d12f6 B branch: branch1
+0:1994f17a630e A branch: 
+
+% Rebase part of branch2 (5-6) onto branch3 (8)
+saving bundle to 
+adding branch
+adding changesets
+adding manifests
+adding file changes
+added 4 changesets with 3 changes to 3 files (+1 heads)
+rebase completed
+
+% Branches
+branch3                        8:c9bfa9beb84e
+branch2                        4:8e66061486ee
+branch1                        2:65a26a4d12f6
+default                        0:1994f17a630e (inactive)
+
+% Heads
+8:c9bfa9beb84e E branch: branch3
+4:8e66061486ee C branch: branch2
+2:65a26a4d12f6 B branch: branch1
+0:1994f17a630e A branch: 
+
+@  8:c9bfa9beb84e E branch: branch3
+|
+o  7:bf9037384081 D branch: branch3
+|
+o  6:c11d5b3e9c00 F branch: branch3
+|
+o  5:33c9da881988 Branch3 branch: branch3
+|
+| o  4:8e66061486ee C branch: branch2
+| |
+| o  3:99567862abbe Branch2 branch: branch2
+|/
+| o  2:65a26a4d12f6 B branch: branch1
+| |
+| o  1:0f3f3010ee16 Branch1 branch: branch1
+|/
+o  0:1994f17a630e A branch:
+
+
+% Rebase head of branch3 (8) onto branch2 (6)
+@  8:c11d5b3e9c00 F branch: branch3
+|
+o  7:33c9da881988 Branch3 branch: branch3
+|
+| o  6:0e4064ab11a3 E branch: branch2
+| |
+| o  5:5ac035cb5d8f D branch: branch2
+| |
+| | o  4:8e66061486ee C branch: branch2
+| | |
++---o  3:99567862abbe Branch2 branch: branch2
+| |
+| o  2:65a26a4d12f6 B branch: branch1
+| |
+| o  1:0f3f3010ee16 Branch1 branch: branch1
+|/
+o  0:1994f17a630e A branch:
+
+saving bundle to 
+adding branch
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+rebase completed
+
+% Branches
+branch2                        8:b44d3024f247
+branch3                        7:33c9da881988
+branch1                        2:65a26a4d12f6 (inactive)
+default                        0:1994f17a630e (inactive)
+
+% Heads
+8:b44d3024f247 F branch: branch2
+7:33c9da881988 Branch3 branch: branch3
+4:8e66061486ee C branch: branch2
+2:65a26a4d12f6 B branch: branch1
+0:1994f17a630e A branch: 
+
+@  8:b44d3024f247 F branch: branch2
+|
+| o  7:33c9da881988 Branch3 branch: branch3
+| |
+o |  6:0e4064ab11a3 E branch: branch2
+| |
+o |  5:5ac035cb5d8f D branch: branch2
+| |
+| | o  4:8e66061486ee C branch: branch2
+| | |
+| | o  3:99567862abbe Branch2 branch: branch2
+| |/
+o |  2:65a26a4d12f6 B branch: branch1
+| |
+o |  1:0f3f3010ee16 Branch1 branch: branch1
+|/
+o  0:1994f17a630e A branch:
+
+
+% Rebase entire branch3 (7-8) onto branch2 (6)
+@  8:c11d5b3e9c00 F branch: branch3
+|
+o  7:33c9da881988 Branch3 branch: branch3
+|
+| o  6:0e4064ab11a3 E branch: branch2
+| |
+| o  5:5ac035cb5d8f D branch: branch2
+| |
+| | o  4:8e66061486ee C branch: branch2
+| | |
++---o  3:99567862abbe Branch2 branch: branch2
+| |
+| o  2:65a26a4d12f6 B branch: branch1
+| |
+| o  1:0f3f3010ee16 Branch1 branch: branch1
+|/
+o  0:1994f17a630e A branch:
+
+saving bundle to 
+adding branch
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+rebase completed
+
+% Branches
+branch2                        7:b44d3024f247
+branch1                        2:65a26a4d12f6 (inactive)
+default                        0:1994f17a630e (inactive)
+
+% Heads
+7:b44d3024f247 F branch: branch2
+4:8e66061486ee C branch: branch2
+2:65a26a4d12f6 B branch: branch1
+0:1994f17a630e A branch: 
+
+@  7:b44d3024f247 F branch: branch2
+|
+o  6:0e4064ab11a3 E branch: branch2
+|
+o  5:5ac035cb5d8f D branch: branch2
+|
+| o  4:8e66061486ee C branch: branch2
+| |
+| o  3:99567862abbe Branch2 branch: branch2
+| |
+o |  2:65a26a4d12f6 B branch: branch1
+| |
+o |  1:0f3f3010ee16 Branch1 branch: branch1
+|/
+o  0:1994f17a630e A branch:
+


More information about the Mercurial-devel mailing list