diff --git a/hgext/keyword.py b/hgext/keyword.py --- a/hgext/keyword.py +++ b/hgext/keyword.py @@ -86,7 +86,7 @@ from mercurial import commands, context, from mercurial import localrepo, match, patch, templatefilters, templater, util from mercurial.hgweb import webcommands from mercurial.i18n import _ -import re, shutil, tempfile +import os, re, shutil, tempfile commands.optionalrepo += ' kwdemo' @@ -555,17 +555,31 @@ def reposetup(ui, repo): def kw_copy(orig, ui, repo, pats, opts, rename=False): '''Wraps cmdutil.copy so that copy/rename destinations do not contain expanded keywords. - Note that the source may also be a symlink as: + Note that the source of a regular file destination may also be a + symlink: hg cp sym x -> x is symlink cp sym x; hg cp -A sym x -> x is file (maybe expanded keywords) - ''' + For the latter we have to follow the symlink to find out whether its + target is configured for expansion and we therefore must unexpand the + keywords in the destination.''' orig(ui, repo, pats, opts, rename) if opts.get('dry_run'): return wctx = repo[None] + cwd = repo.getcwd() + + def haskwsource(dest): + '''Returns true if dest is a regular file and configured for + expansion or a symlink which points to a file configured for + expansion. ''' + source = repo.dirstate.copied(dest) + if 'l' in wctx.flags(source): + source = util.canonpath(repo.root, cwd, + os.path.realpath(source)) + return kwt.match(source) + candidates = [f for f in repo.dirstate.copies() if - kwt.match(repo.dirstate.copied(f)) and - not 'l' in wctx.flags(f)] + not 'l' in wctx.flags(f) and haskwsource(f)] kwt.overwrite(wctx, candidates, False, False) def kw_dorecord(orig, ui, repo, commitfunc, *pats, **opts): diff --git a/tests/test-keyword.t b/tests/test-keyword.t --- a/tests/test-keyword.t +++ b/tests/test-keyword.t @@ -553,7 +553,8 @@ Copy ignored file to ignored file: no ov $ hg forget i $ rm i -cp symlink (becomes regular file), and hg copy after +cp symlink file; hg cp -A symlink file (part1) +- copied symlink points to kwfile: overwrite $ cp sym i $ ls -l i @@ -602,6 +603,26 @@ Status after rollback: $ hg update --clean 0 files updated, 0 files merged, 0 files removed, 0 files unresolved +cp symlink file; hg cp -A symlink file (part2) +- copied symlink points to kw ignored file: do not overwrite + + $ cat a > i + $ ln -s i symignored + $ hg commit -Am 'fake expansion in ignored and symlink' i symignored + $ cp symignored x + $ hg copy --after --verbose symignored x + copying symignored to x + $ head -n 1 x + expand $Id: a,v ef63ca68695b 1970/01/01 00:00:00 user $ + $ hg forget x + $ rm x + + $ hg rollback + rolling back to revision 1 (undo commit) + $ hg update --clean + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ rm i symignored + Custom keywordmaps as argument to kwdemo $ hg --quiet kwdemo "Xinfo = {author}: {desc}"