diff --git a/hgext/convert/gnuarch.py b/hgext/convert/gnuarch.py --- a/hgext/convert/gnuarch.py +++ b/hgext/convert/gnuarch.py @@ -138,7 +138,7 @@ class gnuarch_source(converter_source, c raise util.Abort(_('internal calling inconsistency')) # Raise IOError if necessary (i.e. deleted files). - if not os.path.exists(os.path.join(self.tmppath, name)): + if not os.path.lexists(os.path.join(self.tmppath, name)): raise IOError return self._getfile(name, rev) diff --git a/hgext/convert/subversion.py b/hgext/convert/subversion.py --- a/hgext/convert/subversion.py +++ b/hgext/convert/subversion.py @@ -1037,7 +1037,7 @@ class svn_sink(converter_sink, commandli # our copyfile method expects to record a copy that has # already occurred. Cross the semantic gap. wdest = self.wjoin(dest) - exists = os.path.exists(wdest) + exists = os.path.lexists(wdest) if exists: fd, tempname = tempfile.mkstemp( prefix='hg-copy-', dir=os.path.dirname(wdest)) diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -674,7 +674,7 @@ class queue(object): removed = [] merged = [] for f in files: - if os.path.exists(repo.wjoin(f)): + if os.path.lexists(repo.wjoin(f)): merged.append(f) else: removed.append(f) diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -422,7 +422,7 @@ def copy(ui, repo, pats, opts, rename=Fa return # check for overwrites - exists = os.path.exists(target) + exists = os.path.lexists(target) if not after and exists or after and state in 'mn': if not opts['force']: ui.warn(_('%s: not overwriting - file exists\n') % diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -825,7 +825,7 @@ class workingctx(changectx): wlock = self._repo.wlock() try: for f in list: - if unlink and os.path.exists(self._repo.wjoin(f)): + if unlink and os.path.lexists(self._repo.wjoin(f)): self._repo.ui.warn(_("%s still exists!\n") % f) elif self._repo.dirstate[f] == 'a': self._repo.dirstate.forget(f) @@ -853,7 +853,7 @@ class workingctx(changectx): def copy(self, source, dest): p = self._repo.wjoin(dest) - if not (os.path.exists(p) or os.path.islink(p)): + if not os.path.lexists(p): self._repo.ui.warn(_("%s does not exist!\n") % dest) elif not (os.path.isfile(p) or os.path.islink(p)): self._repo.ui.warn(_("copy failed: %s is not a file or a " diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py --- a/mercurial/dirstate.py +++ b/mercurial/dirstate.py @@ -362,7 +362,7 @@ class dirstate(object): norm_path = os.path.normcase(path) fold_path = self._foldmap.get(norm_path, None) if fold_path is None: - if knownpath or not os.path.exists(os.path.join(self._root, path)): + if knownpath or not os.path.lexists(os.path.join(self._root, path)): fold_path = path else: fold_path = self._foldmap.setdefault(norm_path, diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -25,7 +25,7 @@ class NoHunks(PatchError): def copyfile(src, dst, basedir): abssrc, absdst = [util.canonpath(basedir, basedir, x) for x in [src, dst]] - if os.path.exists(absdst): + if os.path.lexists(absdst): raise util.Abort(_("cannot create %s: destination already exists") % dst) @@ -923,7 +923,7 @@ def selectfile(afile_orig, bfile_orig, h if afile == bfile: goodb = gooda else: - goodb = not nullb and os.path.exists(bfile) + goodb = not nullb and os.path.lexists(bfile) createfunc = hunk.createfile missing = not goodb and not gooda and not createfunc() diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -644,7 +644,7 @@ def fspath(name, root): l = l + 1 name = name[l:] - if not os.path.exists(os.path.join(root, name)): + if not os.path.lexists(os.path.join(root, name)): return None seps = os.sep diff --git a/tests/test-convert-svn-sink b/tests/test-convert-svn-sink --- a/tests/test-convert-svn-sink +++ b/tests/test-convert-svn-sink @@ -29,6 +29,7 @@ hg init a echo a > a/a mkdir -p a/d1/d2 echo b > a/d1/d2/b +ln -s a/missing a/link echo % add hg --cwd a ci -d '0 0' -A -m 'add a file' @@ -43,6 +44,7 @@ ls a a-hg-wc cmp a/a a-hg-wc/a && echo same || echo different hg --cwd a mv a b +hg --cwd a mv link newlink echo % rename hg --cwd a ci -d '2 0' -m 'rename a file' hg --cwd a tip -q diff --git a/tests/test-convert-svn-sink.out b/tests/test-convert-svn-sink.out --- a/tests/test-convert-svn-sink.out +++ b/tests/test-convert-svn-sink.out @@ -1,8 +1,9 @@ % add adding a adding d1/d2/b +adding link % modify -1:e0e2b8a9156b +1:8231f652da37 assuming destination a-hg initializing svn repository 'a-hg' initializing svn working copy 'a-hg-wc' @@ -17,6 +18,7 @@ At revision 2. 2 1 test d1 2 1 test d1/d2 2 1 test d1/d2/b + 2 1 test link /d1/d2 /d1/d2/b +/link add a file @@ -49,13 +53,15 @@ At revision 2. a: a d1 +link a-hg-wc: a d1 +link same % rename -2:eb5169441d43 +2:a67e26ccec09 assuming destination a-hg initializing svn working copy 'a-hg-wc' scanning source... @@ -68,6 +74,7 @@ At revision 3. 3 1 test d1 3 1 test d1/d2 3 1 test d1/d2/b + 3 3 test newlink /b +/newlink +/link rename a file @@ -88,12 +101,14 @@ At revision 3. a: b d1 +newlink a-hg-wc: b d1 +newlink % copy -3:60effef6ab48 +3:0cf087b9ab02 assuming destination a-hg initializing svn working copy 'a-hg-wc' scanning source... @@ -107,6 +122,7 @@ At revision 4. 4 1 test d1 4 1 test d1/d2 4 1 test d1/d2/b + 4 3 test newlink linkb + +check patch does not overwrite untracked symlinks + + $ hg qpop + popping movelink + now at: link + $ ln -s linkbb linkb + $ hg qpush + applying movelink + patch failed, unable to continue (try -v) + patch failed, rejects left in working dir + errors during apply, please fix and refresh movelink + [2] diff --git a/tests/test-rename.t b/tests/test-rename.t --- a/tests/test-rename.t +++ b/tests/test-rename.t @@ -372,6 +372,17 @@ forced overwrite of an existing file 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ rm d1/ca +attempt to overwrite an existing broken symlink + + $ ln -s ba d1/ca + $ hg rename --traceback d1/ba d1/ca + d1/ca: not overwriting - file exists + $ hg status -C + ? d1/ca + $ hg update -C + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ rm d1/ca + replace a symlink with a file $ ln -s ba d1/ca