Mercurial > hg
changeset 4335:f4a1eac52d43
Merge with stable
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Tue, 10 Apr 2007 14:05:15 -0500 |
parents | aa26759c6fb3 (current diff) 66a3fe30f9fc (diff) |
children | 8b4d4f84b739 ec64f263e49a |
files | hgext/mq.py mercurial/dirstate.py mercurial/localrepo.py mercurial/templater.py mercurial/util.py |
diffstat | 7 files changed, 92 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/mq.py Sat Apr 07 04:45:27 2007 -0300 +++ b/hgext/mq.py Tue Apr 10 14:05:15 2007 -0500 @@ -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 Tue Apr 10 14:05:15 2007 -0500 @@ -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 Tue Apr 10 14:05:15 2007 -0500 @@ -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/templater.py Sat Apr 07 04:45:27 2007 -0300 +++ b/mercurial/templater.py Tue Apr 10 14:05:15 2007 -0500 @@ -27,7 +27,7 @@ is treated as name of template file. templater is asked to expand a key in map. it looks up key, and - looks for atrings like this: {foo}. it expands {foo} by looking up + looks for strings like this: {foo}. it expands {foo} by looking up foo in map, and substituting it. expansion is recursive: it stops when there is no more {foo} to replace.
--- a/mercurial/util.py Sat Apr 07 04:45:27 2007 -0300 +++ b/mercurial/util.py Tue Apr 10 14:05:15 2007 -0500 @@ -766,6 +766,9 @@ except: return True +_umask = os.umask(0) +os.umask(_umask) + def checkexec(path): """ Check whether the given path is on a filesystem with UNIX-like exec flags @@ -1103,18 +1106,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 +1140,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 +1180,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 Tue Apr 10 14:05:15 2007 -0500 @@ -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 Tue Apr 10 14:05:15 2007 -0500 @@ -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