##// END OF EJS Templates
Merge with stable
Matt Mackall -
r4335:f4a1eac5 merge default
parent child Browse files
Show More
@@ -0,0 +1,39
1 #!/bin/sh
2
3 # Test issue 529 - mq aborts when merging patch deleting files
4
5 rewrite_path()
6 {
7 sed -e 's:\\:/:g' -e 's:[^ ]*/t/::g'
8 }
9
10 echo "[extensions]" >> $HGRCPATH
11 echo "hgext.mq=" >> $HGRCPATH
12
13 # Commit two dummy files in "init" changeset
14 hg init t
15 cd t
16 echo a > a
17 echo b > b
18 hg ci -Am init
19 hg tag -l init
20
21 # Create a patch removing a
22 hg qnew rm_a
23 hg rm a
24 hg qrefresh -m "rm a"
25
26 # Save the patch queue so we can merge it later
27 hg qsave -c -e 2>&1 | rewrite_path
28
29 # Update b and commit in an "update" changeset
30 hg up -C init
31 echo b >> b
32 hg st
33 hg ci -m update
34
35 # Here, qpush used to abort with :
36 # The system cannot find the file specified => a
37 hg manifest
38 hg qpush -a -m 2>&1 | rewrite_path
39 hg manifest
@@ -0,0 +1,11
1 adding a
2 adding b
3 copy .hg/patches to .hg/patches.1
4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
5 M b
6 a
7 b
8 merging with queue at: .hg/patches.1
9 applying rm_a
10 Now at: rm_a
11 b
@@ -471,8 +471,16 class queue:
471 patcherr = not patcherr
471 patcherr = not patcherr
472
472
473 if merge and files:
473 if merge and files:
474 # Mark as merged and update dirstate parent info
474 # Mark as removed/merged and update dirstate parent info
475 repo.dirstate.update(repo.dirstate.filterfiles(files.keys()), 'm')
475 removed = []
476 merged = []
477 for f in files:
478 if os.path.exists(repo.dirstate.wjoin(f)):
479 merged.append(f)
480 else:
481 removed.append(f)
482 repo.dirstate.update(repo.dirstate.filterfiles(removed), 'r')
483 repo.dirstate.update(repo.dirstate.filterfiles(merged), 'm')
476 p1, p2 = repo.dirstate.parents()
484 p1, p2 = repo.dirstate.parents()
477 repo.dirstate.setparents(p1, merge)
485 repo.dirstate.setparents(p1, merge)
478 files = patch.updatedir(self.ui, repo, files, wlock=wlock)
486 files = patch.updatedir(self.ui, repo, files, wlock=wlock)
@@ -314,7 +314,7 class dirstate(object):
314 def write(self):
314 def write(self):
315 if not self.dirty:
315 if not self.dirty:
316 return
316 return
317 st = self.opener("dirstate", "w", atomic=True)
317 st = self.opener("dirstate", "w", atomictemp=True)
318 st.write("".join(self.pl))
318 st.write("".join(self.pl))
319 for f, e in self.map.items():
319 for f, e in self.map.items():
320 c = self.copied(f)
320 c = self.copied(f)
@@ -322,6 +322,7 class dirstate(object):
322 f = f + "\0" + c
322 f = f + "\0" + c
323 e = struct.pack(self.format, e[0], e[1], e[2], e[3], len(f))
323 e = struct.pack(self.format, e[0], e[1], e[2], e[3], len(f))
324 st.write(e + f)
324 st.write(e + f)
325 st.rename()
325 self.dirty = 0
326 self.dirty = 0
326
327
327 def filterfiles(self, files):
328 def filterfiles(self, files):
@@ -417,10 +417,11 class localrepository(repo.repository):
417
417
418 def _writebranchcache(self, branches, tip, tiprev):
418 def _writebranchcache(self, branches, tip, tiprev):
419 try:
419 try:
420 f = self.opener("branch.cache", "w")
420 f = self.opener("branch.cache", "w", atomictemp=True)
421 f.write("%s %s\n" % (hex(tip), tiprev))
421 f.write("%s %s\n" % (hex(tip), tiprev))
422 for label, node in branches.iteritems():
422 for label, node in branches.iteritems():
423 f.write("%s %s\n" % (hex(node), label))
423 f.write("%s %s\n" % (hex(node), label))
424 f.rename()
424 except IOError:
425 except IOError:
425 pass
426 pass
426
427
@@ -27,7 +27,7 class templater(object):
27 is treated as name of template file.
27 is treated as name of template file.
28
28
29 templater is asked to expand a key in map. it looks up key, and
29 templater is asked to expand a key in map. it looks up key, and
30 looks for atrings like this: {foo}. it expands {foo} by looking up
30 looks for strings like this: {foo}. it expands {foo} by looking up
31 foo in map, and substituting it. expansion is recursive: it stops
31 foo in map, and substituting it. expansion is recursive: it stops
32 when there is no more {foo} to replace.
32 when there is no more {foo} to replace.
33
33
@@ -766,6 +766,9 def checkfolding(path):
766 except:
766 except:
767 return True
767 return True
768
768
769 _umask = os.umask(0)
770 os.umask(_umask)
771
769 def checkexec(path):
772 def checkexec(path):
770 """
773 """
771 Check whether the given path is on a filesystem with UNIX-like exec flags
774 Check whether the given path is on a filesystem with UNIX-like exec flags
@@ -1103,18 +1106,32 def opener(base, audit=True):
1103 p = base
1106 p = base
1104 audit_p = audit
1107 audit_p = audit
1105
1108
1106 def mktempcopy(name):
1109 def mktempcopy(name, emptyok=False):
1107 d, fn = os.path.split(name)
1110 d, fn = os.path.split(name)
1108 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d)
1111 fd, temp = tempfile.mkstemp(prefix='.%s-' % fn, dir=d)
1109 os.close(fd)
1112 os.close(fd)
1110 ofp = posixfile(temp, "wb")
1113 # Temporary files are created with mode 0600, which is usually not
1114 # what we want. If the original file already exists, just copy
1115 # its mode. Otherwise, manually obey umask.
1116 try:
1117 st_mode = os.lstat(name).st_mode
1118 except OSError, inst:
1119 if inst.errno != errno.ENOENT:
1120 raise
1121 st_mode = 0666 & ~_umask
1122 os.chmod(temp, st_mode)
1123 if emptyok:
1124 return temp
1111 try:
1125 try:
1112 try:
1126 try:
1113 ifp = posixfile(name, "rb")
1127 ifp = posixfile(name, "rb")
1114 except IOError, inst:
1128 except IOError, inst:
1129 if inst.errno == errno.ENOENT:
1130 return temp
1115 if not getattr(inst, 'filename', None):
1131 if not getattr(inst, 'filename', None):
1116 inst.filename = name
1132 inst.filename = name
1117 raise
1133 raise
1134 ofp = posixfile(temp, "wb")
1118 for chunk in filechunkiter(ifp):
1135 for chunk in filechunkiter(ifp):
1119 ofp.write(chunk)
1136 ofp.write(chunk)
1120 ifp.close()
1137 ifp.close()
@@ -1123,15 +1140,13 def opener(base, audit=True):
1123 try: os.unlink(temp)
1140 try: os.unlink(temp)
1124 except: pass
1141 except: pass
1125 raise
1142 raise
1126 st = os.lstat(name)
1127 os.chmod(temp, st.st_mode)
1128 return temp
1143 return temp
1129
1144
1130 class atomictempfile(posixfile):
1145 class atomictempfile(posixfile):
1131 """the file will only be copied when rename is called"""
1146 """the file will only be copied when rename is called"""
1132 def __init__(self, name, mode):
1147 def __init__(self, name, mode):
1133 self.__name = name
1148 self.__name = name
1134 self.temp = mktempcopy(name)
1149 self.temp = mktempcopy(name, emptyok=('w' in mode))
1135 posixfile.__init__(self, self.temp, mode)
1150 posixfile.__init__(self, self.temp, mode)
1136 def rename(self):
1151 def rename(self):
1137 if not self.closed:
1152 if not self.closed:
@@ -1165,10 +1180,10 def opener(base, audit=True):
1165 try:
1180 try:
1166 nlink = nlinks(f)
1181 nlink = nlinks(f)
1167 except OSError:
1182 except OSError:
1183 nlink = 0
1168 d = os.path.dirname(f)
1184 d = os.path.dirname(f)
1169 if not os.path.isdir(d):
1185 if not os.path.isdir(d):
1170 os.makedirs(d)
1186 os.makedirs(d)
1171 else:
1172 if atomic:
1187 if atomic:
1173 return atomicfile(f, mode)
1188 return atomicfile(f, mode)
1174 elif atomictemp:
1189 elif atomictemp:
General Comments 0
You need to be logged in to leave comments. Login now