# HG changeset patch # User Patrick Mezard # Date 1288293953 -7200 # Node ID bb7bf43b72fb6e3485588ac4c121ac3408068e8b # Parent e1855dee28c164be291755af2e11b26efe77a64e patch: fix copies when patching over uncommitted changed (issue2459) diff -r e1855dee28c1 -r bb7bf43b72fb mercurial/cmdutil.py --- a/mercurial/cmdutil.py Wed Oct 27 16:54:46 2010 -0500 +++ b/mercurial/cmdutil.py Thu Oct 28 21:25:53 2010 +0200 @@ -348,7 +348,7 @@ wctx = repo[None] for src, dst in copies: - wctx.copy(src, dst) + dirstatecopy(ui, repo, wctx, src, dst, cwd=cwd) if (not similarity) and removes: wctx.remove(sorted(removes), True) @@ -367,6 +367,25 @@ files.extend([r for r in removes if r not in files]) return sorted(files) +def dirstatecopy(ui, repo, wctx, src, dst, dryrun=False, cwd=None): + """Update the dirstate to reflect the intent of copying src to dst. For + different reasons it might not end with dst being marked as copied from src. + """ + origsrc = repo.dirstate.copied(src) or src + if dst == origsrc: # copying back a copy? + if repo.dirstate[dst] not in 'mn' and not dryrun: + repo.dirstate.normallookup(dst) + else: + if repo.dirstate[origsrc] == 'a' and origsrc == src: + if not ui.quiet: + ui.warn(_("%s has not been committed yet, so no copy " + "data will be stored for %s.\n") + % (repo.pathto(origsrc, cwd), repo.pathto(dst, cwd))) + if repo.dirstate[dst] in '?r' and not dryrun: + wctx.add([dst]) + elif not dryrun: + wctx.copy(origsrc, dst) + def copy(ui, repo, pats, opts, rename=False): # called with the repo lock held # @@ -458,21 +477,7 @@ targets[abstarget] = abssrc # fix up dirstate - origsrc = repo.dirstate.copied(abssrc) or abssrc - if abstarget == origsrc: # copying back a copy? - if state not in 'mn' and not dryrun: - repo.dirstate.normallookup(abstarget) - else: - if repo.dirstate[origsrc] == 'a' and origsrc == abssrc: - if not ui.quiet: - ui.warn(_("%s has not been committed yet, so no copy " - "data will be stored for %s.\n") - % (repo.pathto(origsrc, cwd), reltarget)) - if repo.dirstate[abstarget] in '?r' and not dryrun: - wctx.add([abstarget]) - elif not dryrun: - wctx.copy(origsrc, abstarget) - + dirstatecopy(ui, repo, wctx, abssrc, abstarget, dryrun=dryrun, cwd=cwd) if rename and not dryrun: wctx.remove([abssrc], not after) diff -r e1855dee28c1 -r bb7bf43b72fb tests/test-git-import.t --- a/tests/test-git-import.t Wed Oct 27 16:54:46 2010 -0500 +++ b/tests/test-git-import.t Thu Oct 28 21:25:53 2010 +0200 @@ -361,4 +361,25 @@ A binary2 text2 R text2 + $ cd .. +Consecutive import with renames (issue2459) + + $ hg init issue2459 + $ cd issue2459 + $ hg import --no-commit --force - < diff --git a/a b/a + > new file mode 100644 + > EOF + applying patch from stdin + $ hg import --no-commit --force - < diff --git a/a b/b + > rename from a + > rename to b + > EOF + applying patch from stdin + a has not been committed yet, so no copy data will be stored for b. + $ hg debugstate + a 0 -1 unset b + $ hg ci -m done + $ cd ..