Mercurial > hg-stable
changeset 4336:1cc5fc1d0994
Merge with crew-stable.
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Mon, 09 Apr 2007 04:57:25 -0300 |
parents | aa26759c6fb3 (current diff) 4f721e96f1de (diff) |
children | 35ad84669ca5 |
files | hgext/mq.py mercurial/dirstate.py mercurial/localrepo.py mercurial/util.py |
diffstat | 6 files changed, 91 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/mq.py Sat Apr 07 04:45:27 2007 -0300 +++ b/hgext/mq.py Mon Apr 09 04:57:25 2007 -0300 @@ -471,8 +471,16 @@ patcherr = not patcherr if merge and files: - # Mark as merged and update dirstate parent info - repo.dirstate.update(repo.dirstate.filterfiles(files.keys()), 'm') + # Mark as removed/merged and update dirstate parent info + removed = [] + merged = [] + for f in files: + if os.path.exists(repo.dirstate.wjoin(f)): + merged.append(f) + else: + removed.append(f) + repo.dirstate.update(repo.dirstate.filterfiles(removed), 'r') + repo.dirstate.update(repo.dirstate.filterfiles(merged), 'm') p1, p2 = repo.dirstate.parents() repo.dirstate.setparents(p1, merge) files = patch.updatedir(self.ui, repo, files, wlock=wlock)
--- a/mercurial/dirstate.py Sat Apr 07 04:45:27 2007 -0300 +++ b/mercurial/dirstate.py Mon Apr 09 04:57:25 2007 -0300 @@ -314,7 +314,7 @@ def write(self): if not self.dirty: return - st = self.opener("dirstate", "w", atomic=True) + st = self.opener("dirstate", "w", atomictemp=True) st.write("".join(self.pl)) for f, e in self.map.items(): c = self.copied(f) @@ -322,6 +322,7 @@ f = f + "\0" + c e = struct.pack(self.format, e[0], e[1], e[2], e[3], len(f)) st.write(e + f) + st.rename() self.dirty = 0 def filterfiles(self, files):
--- a/mercurial/localrepo.py Sat Apr 07 04:45:27 2007 -0300 +++ b/mercurial/localrepo.py Mon Apr 09 04:57:25 2007 -0300 @@ -417,10 +417,11 @@ def _writebranchcache(self, branches, tip, tiprev): try: - f = self.opener("branch.cache", "w") + f = self.opener("branch.cache", "w", atomictemp=True) f.write("%s %s\n" % (hex(tip), tiprev)) for label, node in branches.iteritems(): f.write("%s %s\n" % (hex(node), label)) + f.rename() except IOError: pass
--- a/mercurial/util.py Sat Apr 07 04:45:27 2007 -0300 +++ b/mercurial/util.py Mon Apr 09 04:57:25 2007 -0300 @@ -804,6 +804,9 @@ return lambda x: os.path.islink(os.path.join(path, x)) return fallback +_umask = os.umask(0) +os.umask(_umask) + # Platform specific variants if os.name == 'nt': import msvcrt @@ -930,8 +933,6 @@ else: nulldev = '/dev/null' - _umask = os.umask(0) - os.umask(_umask) def rcfiles(path): rcs = [os.path.join(path, 'hgrc')] @@ -1103,18 +1104,32 @@ p = base audit_p = audit - def mktempcopy(name): + def mktempcopy(name, emptyok=False): d, fn = os.path.split(name) fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d) os.close(fd) - ofp = posixfile(temp, "wb") + # Temporary files are created with mode 0600, which is usually not + # what we want. If the original file already exists, just copy + # its mode. Otherwise, manually obey umask. + try: + st_mode = os.lstat(name).st_mode + except OSError, inst: + if inst.errno != errno.ENOENT: + raise + st_mode = 0666 & ~_umask + os.chmod(temp, st_mode) + if emptyok: + return temp try: try: ifp = posixfile(name, "rb") except IOError, inst: + if inst.errno == errno.ENOENT: + return temp if not getattr(inst, 'filename', None): inst.filename = name raise + ofp = posixfile(temp, "wb") for chunk in filechunkiter(ifp): ofp.write(chunk) ifp.close() @@ -1123,15 +1138,13 @@ try: os.unlink(temp) except: pass raise - st = os.lstat(name) - os.chmod(temp, st.st_mode) return temp class atomictempfile(posixfile): """the file will only be copied when rename is called""" def __init__(self, name, mode): self.__name = name - self.temp = mktempcopy(name) + self.temp = mktempcopy(name, emptyok=('w' in mode)) posixfile.__init__(self, self.temp, mode) def rename(self): if not self.closed: @@ -1165,16 +1178,16 @@ try: nlink = nlinks(f) except OSError: + nlink = 0 d = os.path.dirname(f) if not os.path.isdir(d): os.makedirs(d) - else: - if atomic: - return atomicfile(f, mode) - elif atomictemp: - return atomictempfile(f, mode) - if nlink > 1: - rename(mktempcopy(f), f) + if atomic: + return atomicfile(f, mode) + elif atomictemp: + return atomictempfile(f, mode) + if nlink > 1: + rename(mktempcopy(f), f) return posixfile(f, mode) return o
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-mq-merge Mon Apr 09 04:57:25 2007 -0300 @@ -0,0 +1,39 @@ +#!/bin/sh + +# Test issue 529 - mq aborts when merging patch deleting files + +rewrite_path() +{ + sed -e 's:\\:/:g' -e 's:[^ ]*/t/::g' +} + +echo "[extensions]" >> $HGRCPATH +echo "hgext.mq=" >> $HGRCPATH + +# Commit two dummy files in "init" changeset +hg init t +cd t +echo a > a +echo b > b +hg ci -Am init +hg tag -l init + +# Create a patch removing a +hg qnew rm_a +hg rm a +hg qrefresh -m "rm a" + +# Save the patch queue so we can merge it later +hg qsave -c -e 2>&1 | rewrite_path + +# Update b and commit in an "update" changeset +hg up -C init +echo b >> b +hg st +hg ci -m update + +# Here, qpush used to abort with : +# The system cannot find the file specified => a +hg manifest +hg qpush -a -m 2>&1 | rewrite_path +hg manifest
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-mq-merge.out Mon Apr 09 04:57:25 2007 -0300 @@ -0,0 +1,11 @@ +adding a +adding b +copy .hg/patches to .hg/patches.1 +1 files updated, 0 files merged, 0 files removed, 0 files unresolved +M b +a +b +merging with queue at: .hg/patches.1 +applying rm_a +Now at: rm_a +b