# HG changeset patch # User Stefano Tortarolo # Date 2009-03-30 16:26:32 # Node ID b969611064aea5b4867d513b428c6e7bfe032aad # Parent 8c6f823efcc93d8a6e6e2ec62c9fc41d91086d43 rebase: don't lose rename/copy data (Issue1423) diff --git a/hgext/rebase.py b/hgext/rebase.py --- a/hgext/rebase.py +++ b/hgext/rebase.py @@ -14,7 +14,7 @@ http://www.selenic.com/mercurial/wiki/in ''' from mercurial import util, repair, merge, cmdutil, commands, error -from mercurial import extensions, ancestor +from mercurial import extensions, ancestor, copies from mercurial.commands import templateopts from mercurial.node import nullrev from mercurial.i18n import _ @@ -210,7 +210,18 @@ def rebasenode(repo, rev, target, state, else: # we have an interrupted rebase repo.ui.debug(_('resuming interrupted rebase\n')) - + # Keep track of renamed files in the revision that is going to be rebased + # Here we simulate the copies and renames in the source changeset + cop, diver = copies.copies(repo, repo[rev], repo[target], repo[p2], True) + m1 = repo[rev].manifest() + m2 = repo[target].manifest() + for k, v in cop.iteritems(): + if k in m1: + if v in m1 or v in m2: + repo.dirstate.copy(v, k) + if v in m2 and v not in m1: + repo.dirstate.remove(v) + newrev = concludenode(repo, rev, p1, p2, state, collapse, extrafn=extrafn) diff --git a/tests/test-rebase-rename b/tests/test-rebase-rename new file mode 100755 --- /dev/null +++ b/tests/test-rebase-rename @@ -0,0 +1,59 @@ +#!/bin/sh + +echo "[extensions]" >> $HGRCPATH +echo "rebase=" >> $HGRCPATH +echo "[diff]" >> $HGRCPATH +echo "git=1" >> $HGRCPATH + +BASE=`pwd` + +cleanoutput () { + sed -e 's/\(Rebase status stored to\).*/\1/' \ + -e 's/\(Rebase status restored from\).*/\1/' \ + -e 's/\(saving bundle to \).*/\1/' +} + +hg init repo1 +cd repo1 +echo "a">a +hg commit -Am "A" --date '0 0' +echo "b"> b +hg commit -Am "B" --date '1 0' +hg up -C 0 +hg mv a a-renamed +hg commit -m 'rename A' --date '2 0' + +echo +echo '% Rename is tracked' +hg log -p -r tip --template '{rev}:{desc}\n' + +echo '% Rebase the revision containing the rename' +hg rebase -s 2 -d 1 --quiet 2>&1 | cleanoutput + +echo +echo '% Rename is not lost' +hg log -p -r tip --template '{rev}:{desc}\n' + +cd $BASE +rm -rf repo1 +hg init repo1 +cd repo1 +echo "a">a +hg commit -Am "A" --date '0 0' +echo "b"> b +hg commit -Am "B" --date '1 0' +hg up -C 0 +hg cp a a-copied +hg commit -m 'copy A' --date '2 0' + +echo +echo '% Copy is tracked' +hg log -p -r tip --template '{rev}:{desc}\n' + +echo '% Rebase the revision containing the copy' +hg rebase -s 2 -d 1 --quiet 2>&1 | cleanoutput + +echo +echo '% Copy is not lost' +hg log -p -r tip --template '{rev}:{desc}\n' + diff --git a/tests/test-rebase-rename.out b/tests/test-rebase-rename.out new file mode 100644 --- /dev/null +++ b/tests/test-rebase-rename.out @@ -0,0 +1,40 @@ +adding a +adding b +0 files updated, 0 files merged, 1 files removed, 0 files unresolved +created new head + +% Rename is tracked +2:rename A +diff --git a/a b/a-renamed +rename from a +rename to a-renamed + +% Rebase the revision containing the rename +saving bundle to + +% Rename is not lost +2:rename A +diff --git a/a b/a-renamed +rename from a +rename to a-renamed + +adding a +adding b +0 files updated, 0 files merged, 1 files removed, 0 files unresolved +created new head + +% Copy is tracked +2:copy A +diff --git a/a b/a-copied +copy from a +copy to a-copied + +% Rebase the revision containing the copy +saving bundle to + +% Copy is not lost +2:copy A +diff --git a/a b/a-copied +copy from a +copy to a-copied +