annotate hgsubversion/editor.py @ 1347:759cafce6bec stable 1.8.3

editor: cope with slightly out-of-order editor drives As of Subversion 1.8, ra_serf replaces ra_neon as the only http remote access method. ra_serf does lots of clever network things, but as a side effect violates some of the legacy editor API. It turns out we were only barely using those guarantees, so it was straightforward to relax our constraints and work with serf. Prior to this change, attempting to use ra_serf would almost certainly result in an exception due to an out-of-order editor drive. See https://svn.apache.org/repos/asf/subversion/trunk/notes/api-errata/1.7/ra001.txt for more details of the Subversion change.
author Augie Fackler <raf@durin42.com>
date Sat, 26 Sep 2015 10:49:57 -0400
parents 6b15eeb78c1a
children 57d65269d30c b9530c171050
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
633
37b2adc64fb3 editor: convert two assertions in apply_textdelta() into raising an IOError
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 601
diff changeset
1 import errno
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
2 import sys
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
3 import tempfile
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
4 import shutil
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
5 import os
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
6
250
79349fd04836 utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents: 237
diff changeset
7 from mercurial import util as hgutil
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
8 from mercurial import revlog
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
9 from mercurial import node
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
10
601
0fe490ce2fbb isolate all imports of Subversion modules in svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 591
diff changeset
11 import svnwrap
250
79349fd04836 utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents: 237
diff changeset
12 import util
792
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
13 import svnexternals
34
50d55c3e0d85 Some refactors of the previous change, including transparent upgrade of old-style pickled dictionaries.
Augie Fackler <durin42@gmail.com>
parents: 33
diff changeset
14
945
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
15 class EditingError(Exception):
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
16 pass
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
17
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
18 class FileStore(object):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
19 def __init__(self, maxsize=None):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
20 self._tempdir = None
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
21 self._files = {}
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
22 self._created = 0
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
23 self._maxsize = maxsize
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
24 if self._maxsize is None:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
25 self._maxsize = 100*(2**20)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
26 self._size = 0
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
27 self._data = {}
945
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
28 self._popped = set()
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
29
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
30 def setfile(self, fname, data):
945
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
31 if fname in self._popped:
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
32 raise EditingError('trying to set a popped file %s' % fname)
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
33
1233
0d0132cba155 editor: fix edge case with in memory file-store size limit
David Schleimer <dschleimer@fb.com>
parents: 1232
diff changeset
34 if fname in self._data:
0d0132cba155 editor: fix edge case with in memory file-store size limit
David Schleimer <dschleimer@fb.com>
parents: 1232
diff changeset
35 self._size -= len(self._data[fname])
0d0132cba155 editor: fix edge case with in memory file-store size limit
David Schleimer <dschleimer@fb.com>
parents: 1232
diff changeset
36 del self._data[fname]
0d0132cba155 editor: fix edge case with in memory file-store size limit
David Schleimer <dschleimer@fb.com>
parents: 1232
diff changeset
37
0d0132cba155 editor: fix edge case with in memory file-store size limit
David Schleimer <dschleimer@fb.com>
parents: 1232
diff changeset
38 if fname in self._files:
0d0132cba155 editor: fix edge case with in memory file-store size limit
David Schleimer <dschleimer@fb.com>
parents: 1232
diff changeset
39 del self._files[fname]
0d0132cba155 editor: fix edge case with in memory file-store size limit
David Schleimer <dschleimer@fb.com>
parents: 1232
diff changeset
40
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
41 if self._maxsize < 0 or (len(data) + self._size) <= self._maxsize:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
42 self._data[fname] = data
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
43 self._size += len(data)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
44 else:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
45 if self._tempdir is None:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
46 self._tempdir = tempfile.mkdtemp(prefix='hg-subversion-')
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
47 # Avoid filename issues with these simple names
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
48 fn = str(self._created)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
49 fp = hgutil.posixfile(os.path.join(self._tempdir, fn), 'wb')
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
50 try:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
51 fp.write(data)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
52 finally:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
53 fp.close()
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
54 self._created += 1
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
55 self._files[fname] = fn
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
56
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
57 def delfile(self, fname):
945
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
58 if fname in self._popped:
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
59 raise EditingError('trying to delete a popped file %s' % fname)
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
60
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
61 if fname in self._data:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
62 del self._data[fname]
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
63 elif fname in self._files:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
64 path = os.path.join(self._tempdir, self._files.pop(fname))
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
65 os.unlink(path)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
66
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
67 def getfile(self, fname):
945
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
68 if fname in self._popped:
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
69 raise EditingError('trying to get a popped file %s' % fname)
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
70
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
71 if fname in self._data:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
72 return self._data[fname]
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
73 if self._tempdir is None or fname not in self._files:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
74 raise IOError
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
75 path = os.path.join(self._tempdir, self._files[fname])
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
76 fp = hgutil.posixfile(path, 'rb')
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
77 try:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
78 return fp.read()
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
79 finally:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
80 fp.close()
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
81
945
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
82 def popfile(self, fname):
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
83 self.delfile(fname)
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
84 self._popped.add(fname)
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
85
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
86 def files(self):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
87 return list(self._files) + list(self._data)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
88
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
89 def close(self):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
90 if self._tempdir is not None:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
91 tempdir, self._tempdir = self._tempdir, None
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
92 shutil.rmtree(tempdir)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
93 self._files = None
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
94 self._data = None
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
95
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
96 class RevisionData(object):
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
97
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
98 __slots__ = [
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
99 'file', 'added', 'deleted', 'rev', 'execfiles', 'symlinks',
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
100 'copies', 'emptybranches', 'base', 'externals', 'ui',
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
101 'exception', 'store',
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
102 ]
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
103
433
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
104 def __init__(self, ui):
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
105 self.ui = ui
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
106 self.clear()
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
107
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
108 def clear(self):
944
d6db289f1548 pull: add hgsubversion.filestoresize to control memory consumption
Patrick Mezard <patrick@mezard.eu>
parents: 943
diff changeset
109 self.store = FileStore(util.getfilestoresize(self.ui))
901
bd12a4da0f35 replay: workaround svn not telling us about x/l flags (issue346)
Bryan O'Sullivan <bryano@fb.com>
parents: 891
diff changeset
110 self.added = set()
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
111 self.deleted = {}
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
112 self.rev = None
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
113 self.execfiles = {}
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
114 self.symlinks = {}
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
115 # Map fully qualified destination file paths to module source path
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
116 self.copies = {}
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
117 self.emptybranches = {}
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
118 self.externals = {}
434
3e2259fe3c93 editor: move exception data into RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 433
diff changeset
119 self.exception = None
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
120
942
4d9e80f6ba43 editor: do not touch RevisionData copies from the editor
Patrick Mezard <patrick@mezard.eu>
parents: 941
diff changeset
121 def set(self, path, data, isexec=False, islink=False, copypath=None):
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
122 self.store.setfile(path, data)
433
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
123 self.execfiles[path] = isexec
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
124 self.symlinks[path] = islink
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
125 if path in self.deleted:
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
126 del self.deleted[path]
942
4d9e80f6ba43 editor: do not touch RevisionData copies from the editor
Patrick Mezard <patrick@mezard.eu>
parents: 941
diff changeset
127 if copypath is not None:
4d9e80f6ba43 editor: do not touch RevisionData copies from the editor
Patrick Mezard <patrick@mezard.eu>
parents: 941
diff changeset
128 self.copies[path] = copypath
433
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
129
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
130 def get(self, path):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
131 if path in self.deleted:
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
132 raise IOError(errno.ENOENT, '%s is deleted' % path)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
133 data = self.store.getfile(path)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
134 isexec = self.execfiles.get(path)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
135 islink = self.symlinks.get(path)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
136 copied = self.copies.get(path)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
137 return data, isexec, islink, copied
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
138
945
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
139 def pop(self, path):
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
140 ret = self.get(path)
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
141 self.store.popfile(path)
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
142 return ret
bfbfc9be3faa editor: add a pop() method to RevisionMeta to reduce resource usage
Patrick Mezard <patrick@mezard.eu>
parents: 944
diff changeset
143
433
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
144 def delete(self, path):
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
145 self.deleted[path] = True
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
146 self.store.delfile(path)
433
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
147 self.execfiles[path] = False
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
148 self.symlinks[path] = False
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
149 self.ui.note('D %s\n' % path)
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
150
943
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
151 def files(self):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
152 """Return a sorted list of changed files."""
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
153 files = set(self.store.files())
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
154 for g in (self.symlinks, self.execfiles, self.deleted):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
155 files.update(g)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
156 return sorted(files)
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
157
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
158 def close(self):
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
159 self.store.close()
c49c3c418f9d editor: move RevisionData on the filesystem over a given threshold
Patrick Mezard <patrick@mezard.eu>
parents: 942
diff changeset
160
940
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
161 class CopiedFile(object):
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
162 def __init__(self, node, path, copypath):
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
163 self.node = node
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
164 self.path = path
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
165 self.copypath = copypath
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
166
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
167 def resolve(self, getctxfn, ctx=None):
940
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
168 if ctx is None:
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
169 ctx = getctxfn(self.node)
940
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
170 fctx = ctx[self.path]
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
171 data = fctx.data()
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
172 flags = fctx.flags()
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
173 islink = 'l' in flags
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
174 if islink:
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
175 data = 'link ' + data
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
176 return data, 'x' in flags, islink, self.copypath
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
177
601
0fe490ce2fbb isolate all imports of Subversion modules in svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 591
diff changeset
178 class HgEditor(svnwrap.Editor):
33
a9c15cae50e5 Faster append-only revmap implementation.
Andreas Hartmetz <ahartmetz@gmail.com>
parents: 23
diff changeset
179
416
cd6317fe70be invert the svnmeta/editor relationship
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 415
diff changeset
180 def __init__(self, meta):
cd6317fe70be invert the svnmeta/editor relationship
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 415
diff changeset
181 self.meta = meta
cd6317fe70be invert the svnmeta/editor relationship
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 415
diff changeset
182 self.ui = meta.ui
cd6317fe70be invert the svnmeta/editor relationship
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 415
diff changeset
183 self.repo = meta.repo
433
a2a15fa7afb1 editor: move set_file() and delete_file() methods to RevisionData class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 432
diff changeset
184 self.current = RevisionData(meta.ui)
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
185 self._clear()
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
186
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
187 def setsvn(self, svn):
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
188 self._svn = svn
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
189
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
190 def _clear(self):
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
191 self._filecounter = 0
940
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
192 # A mapping of svn paths to CopiedFile entries
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
193 self._svncopies = {}
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
194 # A mapping of batons to (path, data, isexec, islink, copypath) tuples
948
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
195 # data is a SimpleStringIO if the file was edited, a string
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
196 # otherwise.
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
197 self._openfiles = {}
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
198 # A mapping of file paths to batons
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
199 self._openpaths = {}
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
200 self._deleted = set()
1039
3df6ed4e7561 drop support for pre-2.0 versions of Mercurial
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 977
diff changeset
201 self._getctx = hgutil.lrucachefunc(self.repo.changectx)
1347
759cafce6bec editor: cope with slightly out-of-order editor drives
Augie Fackler <raf@durin42.com>
parents: 1235
diff changeset
202 # A map from directory baton to path
759cafce6bec editor: cope with slightly out-of-order editor drives
Augie Fackler <raf@durin42.com>
parents: 1235
diff changeset
203 self._opendirs = {}
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
204 self._missing = set()
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
205
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
206 def _openfile(self, path, data, isexec, islink, copypath, create=False):
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
207 if path in self._openpaths:
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
208 raise EditingError('trying to open an already opened file %s'
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
209 % path)
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
210 if not create and path in self._deleted:
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
211 raise EditingError('trying to open a deleted file %s' % path)
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
212 if path in self._deleted:
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
213 self._deleted.remove(path)
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
214 self._filecounter += 1
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
215 baton = 'f%d-%s' % (self._filecounter, path)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
216 self._openfiles[baton] = (path, data, isexec, islink, copypath)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
217 self._openpaths[path] = baton
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
218 return baton
413
ac0cc3c9ea63 sort HgChangeReceiver methods and properties
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 411
diff changeset
219
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
220 def _opendir(self, path):
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
221 self._filecounter += 1
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
222 baton = 'f%d-%s' % (self._filecounter, path)
1347
759cafce6bec editor: cope with slightly out-of-order editor drives
Augie Fackler <raf@durin42.com>
parents: 1235
diff changeset
223 self._opendirs[baton] = path
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
224 return baton
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
225
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
226 def _checkparentdir(self, baton):
1347
759cafce6bec editor: cope with slightly out-of-order editor drives
Augie Fackler <raf@durin42.com>
parents: 1235
diff changeset
227 if not self._opendirs or baton not in self._opendirs:
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
228 raise EditingError('trying to operate on an already closed '
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
229 'directory: %s' % baton)
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
230
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
231 def _deletefile(self, path):
963
64d961130a07 editor: do not record invalid path deletion
Patrick Mezard <patrick@mezard.eu>
parents: 962
diff changeset
232 if self.meta.is_path_valid(path):
64d961130a07 editor: do not record invalid path deletion
Patrick Mezard <patrick@mezard.eu>
parents: 962
diff changeset
233 self._deleted.add(path)
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
234 if path in self._svncopies:
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
235 del self._svncopies[path]
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
236 self._missing.discard(path)
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
237
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
238 def addmissing(self, path, isdir=False):
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
239 svn = self._svn
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
240 root = svn.subdir and svn.subdir[1:] or ''
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
241 if not isdir:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
242 self._missing.add(path[len(root):])
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
243 else:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
244 # Resolve missing directories content immediately so the
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
245 # missing files maybe processed by delete actions.
1232
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
246 # we remove the missing directory entries to deal with the case
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
247 # where a directory is replaced from e.g. a closed branch
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
248 # this will show up as a delete and then a copy
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
249 # we process deletes after missing, so we can handle a directory
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
250 # copy plus delete of file in that directory. This means that we
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
251 # need to be sure that only things whose final disposition is
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
252 # deletion remain in self._deleted at the end of the editing process.
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
253 rev = self.current.rev.revnum
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
254 path = path + '/'
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
255 parentdir = path[len(root):]
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
256 for f, k in svn.list_files(parentdir, rev):
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
257 if k != 'f':
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
258 continue
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
259 f = parentdir + f
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
260 if not self.meta.is_path_valid(f, False):
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
261 continue
1232
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
262 self._deleted.discard(f)
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
263 self._missing.add(f)
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
264
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
265 @svnwrap.ieditor
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
266 def delete_entry(self, path, revision_bogus, parent_baton, pool=None):
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
267 self._checkparentdir(parent_baton)
545
ebd8fb1a05e4 clean up trailing whitespace
Augie Fackler <durin42@gmail.com>
parents: 540
diff changeset
268 br_path, branch = self.meta.split_branch_path(path)[:2]
133
2242dd1163c6 hg_delta_editor: fix bad parent revision calculation in the case of a branch
Augie Fackler <durin42@gmail.com>
parents: 131
diff changeset
269 if br_path == '':
540
8dc759dc9ca9 svnmeta: remove split_branch_tag() exacttag argument
Patrick Mezard <pmezard@gmail.com>
parents: 534
diff changeset
270 if self.meta.get_path_tag(path):
8dc759dc9ca9 svnmeta: remove split_branch_tag() exacttag argument
Patrick Mezard <pmezard@gmail.com>
parents: 534
diff changeset
271 # Tag deletion is not handled as branched deletion
8dc759dc9ca9 svnmeta: remove split_branch_tag() exacttag argument
Patrick Mezard <pmezard@gmail.com>
parents: 534
diff changeset
272 return
414
343da842dbe6 split parts of HgChangeReceiver out into an SVNMeta class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 413
diff changeset
273 self.meta.closebranches.add(branch)
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
274
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
275 # Delete copied entries, no need to check they exist in hg
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
276 # parent revision.
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
277 if path in self._svncopies:
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
278 del self._svncopies[path]
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
279 prefix = path + '/'
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
280 for f in list(self._svncopies):
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
281 if f.startswith(prefix):
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
282 self._deletefile(f)
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
283 if path in self._missing:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
284 self._missing.remove(path)
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
285 else:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
286 for f in list(self._missing):
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
287 if f.startswith(prefix):
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
288 self._missing.remove(f)
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
289
116
30580c05dccc hg_delta_editor: merge _is_path_valid() and _path_and_branch_from_path()
Patrick Mezard <pmezard@gmail.com>
parents: 111
diff changeset
290 if br_path is not None:
414
343da842dbe6 split parts of HgChangeReceiver out into an SVNMeta class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 413
diff changeset
291 ha = self.meta.get_parent_revision(self.current.rev.revnum, branch)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
292 if ha == revlog.nullid:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
293 return
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
294 ctx = self._getctx(ha)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
295 if br_path not in ctx:
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
296 br_path2 = ''
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
297 if br_path != '':
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
298 br_path2 = br_path + '/'
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
299 # assuming it is a directory
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
300 self.current.externals[path] = None
250
79349fd04836 utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents: 237
diff changeset
301 for f in ctx.walk(util.PrefixMatch(br_path2)):
39
b3c7b844b782 Some more fixes of cases discovered in the melange repo. If anyone knows how I can reproduce a "replaced" state in Subversion, I'd love to be able to make a real test case for this code.
Augie Fackler <durin42@gmail.com>
parents: 38
diff changeset
302 f_p = '%s/%s' % (path, f[len(br_path2):])
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
303 self._deletefile(f_p)
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
304 self._deletefile(path)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
305
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
306 @svnwrap.ieditor
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
307 def open_file(self, path, parent_baton, base_revision, p=None):
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
308 self._checkparentdir(parent_baton)
960
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
309 if not self.meta.is_path_valid(path):
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
310 return None
960
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
311 fpath, branch = self.meta.split_branch_path(path)[:2]
378
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
312
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
313 self.ui.note('M %s\n' % path)
378
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
314
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
315 if path in self._svncopies:
940
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
316 copy = self._svncopies.pop(path)
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
317 base, isexec, islink, copypath = copy.resolve(self._getctx)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
318 return self._openfile(path, base, isexec, islink, copypath)
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
319
378
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
320 baserev = base_revision
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
321 if baserev is None or baserev == -1:
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
322 baserev = self.current.rev.revnum - 1
586
704d2ce1d906 editor: fix open_file() on replaced branch
Patrick Mezard <pmezard@gmail.com>
parents: 585
diff changeset
323 # Use exact=True because during replacements ('R' action) we select
704d2ce1d906 editor: fix open_file() on replaced branch
Patrick Mezard <pmezard@gmail.com>
parents: 585
diff changeset
324 # replacing branch as parent, but svn delta editor provides delta
704d2ce1d906 editor: fix open_file() on replaced branch
Patrick Mezard <pmezard@gmail.com>
parents: 585
diff changeset
325 # agains replaced branch.
704d2ce1d906 editor: fix open_file() on replaced branch
Patrick Mezard <pmezard@gmail.com>
parents: 585
diff changeset
326 parent = self.meta.get_parent_revision(baserev + 1, branch, True)
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
327 ctx = self._getctx(parent)
378
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
328 if fpath not in ctx:
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
329 self.addmissing(path)
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
330 return None
378
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
331
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
332 fctx = ctx.filectx(fpath)
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
333 base = fctx.data()
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
334 flags = fctx.flags()
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
335 if 'l' in flags:
378
eeefbe104087 Inline HgChangeReceiver.load_base_from_ctx().
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 377
diff changeset
336 base = 'link ' + base
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
337 return self._openfile(path, base, 'x' in flags, 'l' in flags, None)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
338
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
339 @svnwrap.ieditor
300
4aba7542f6a9 Various cleanups, cosmetics and removal of superfluous assertions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 299
diff changeset
340 def add_file(self, path, parent_baton=None, copyfrom_path=None,
4aba7542f6a9 Various cleanups, cosmetics and removal of superfluous assertions.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 299
diff changeset
341 copyfrom_revision=None, file_pool=None):
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
342 self._checkparentdir(parent_baton)
960
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
343 # Use existing=False because we use the fact a file is being
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
344 # added here to populate the branchmap which is used with
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
345 # existing=True.
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
346 fpath, branch = self.meta.split_branch_path(path, existing=False)[:2]
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
347 if not fpath or fpath not in self.meta.filemap:
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
348 return None
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
349 if path in self._svncopies:
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
350 raise EditingError('trying to replace copied file %s' % path)
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
351 if path in self._deleted:
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
352 self._deleted.remove(path)
447
0d3b5acb1d51 tags: handle edits to tags as gracefully as possible
Augie Fackler <durin42@gmail.com>
parents: 436
diff changeset
353 if (branch not in self.meta.branches and
517
ef288fb7f2fe svnmeta: is_path_tag() is really get_path_tag()
Patrick Mezard <pmezard@gmail.com>
parents: 499
diff changeset
354 not self.meta.get_path_tag(self.meta.remotename(branch))):
960
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
355 # we know this branch will exist now, because it has at
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
356 # least one file. Rock.
414
343da842dbe6 split parts of HgChangeReceiver out into an SVNMeta class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 413
diff changeset
357 self.meta.branches[branch] = None, 0, self.current.rev.revnum
67
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
358 if not copyfrom_path:
186
6266ba36ee15 Create patch to make normal output much less verbose…
Dan Villiom Podlaski Christiansen <danchr@cs.au.dk>
parents: 181
diff changeset
359 self.ui.note('A %s\n' % path)
901
bd12a4da0f35 replay: workaround svn not telling us about x/l flags (issue346)
Bryan O'Sullivan <bryano@fb.com>
parents: 891
diff changeset
360 self.current.added.add(path)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
361 return self._openfile(path, '', False, False, None, create=True)
186
6266ba36ee15 Create patch to make normal output much less verbose…
Dan Villiom Podlaski Christiansen <danchr@cs.au.dk>
parents: 181
diff changeset
362 self.ui.note('A+ %s\n' % path)
67
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
363 (from_file,
420
59e19c73b0df svnmeta: eliminate unneeded path_and_branch_for_path() method
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 418
diff changeset
364 from_branch) = self.meta.split_branch_path(copyfrom_path)[:2]
67
e319c9168910 hg_delta_editor: register svn file copies
Patrick Mezard <pmezard@gmail.com>
parents: 59
diff changeset
365 if not from_file:
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
366 self.addmissing(path)
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
367 return None
585
c3ba4ca81d16 editor: fix replaced files content in replay mode
Patrick Mezard <pmezard@gmail.com>
parents: 582
diff changeset
368 # Use exact=True because during replacements ('R' action) we select
c3ba4ca81d16 editor: fix replaced files content in replay mode
Patrick Mezard <pmezard@gmail.com>
parents: 582
diff changeset
369 # replacing branch as parent, but svn delta editor provides delta
c3ba4ca81d16 editor: fix replaced files content in replay mode
Patrick Mezard <pmezard@gmail.com>
parents: 582
diff changeset
370 # agains replaced branch.
414
343da842dbe6 split parts of HgChangeReceiver out into an SVNMeta class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 413
diff changeset
371 ha = self.meta.get_parent_revision(copyfrom_revision + 1,
585
c3ba4ca81d16 editor: fix replaced files content in replay mode
Patrick Mezard <pmezard@gmail.com>
parents: 582
diff changeset
372 from_branch, True)
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
373 ctx = self._getctx(ha)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
374 if from_file not in ctx:
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
375 self.addmissing(path)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
376 return None
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
377
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
378 fctx = ctx.filectx(from_file)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
379 flags = fctx.flags()
1235
6b15eeb78c1a editor: fix replay handling for copied + modified symlinks
David Schleimer <dschleimer@fb.com>
parents: 1234
diff changeset
380 base = fctx.data()
6b15eeb78c1a editor: fix replay handling for copied + modified symlinks
David Schleimer <dschleimer@fb.com>
parents: 1234
diff changeset
381 if 'l' in flags:
6b15eeb78c1a editor: fix replay handling for copied + modified symlinks
David Schleimer <dschleimer@fb.com>
parents: 1234
diff changeset
382 base = 'link ' + base
6b15eeb78c1a editor: fix replay handling for copied + modified symlinks
David Schleimer <dschleimer@fb.com>
parents: 1234
diff changeset
383 self.current.set(path, base, 'x' in flags, 'l' in flags)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
384 copypath = None
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
385 if from_branch == branch:
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
386 parentid = self.meta.get_parent_revision(
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
387 self.current.rev.revnum, branch)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
388 if parentid != revlog.nullid:
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
389 parentctx = self._getctx(parentid)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
390 if util.issamefile(parentctx, ctx, from_file):
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
391 copypath = from_file
1235
6b15eeb78c1a editor: fix replay handling for copied + modified symlinks
David Schleimer <dschleimer@fb.com>
parents: 1234
diff changeset
392 return self._openfile(path, base, 'x' in flags, 'l' in flags,
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
393 copypath, create=True)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
394
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
395 @svnwrap.ieditor
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
396 def close_file(self, file_baton, checksum, pool=None):
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
397 if file_baton is None:
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
398 return
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
399 if file_baton not in self._openfiles:
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
400 raise EditingError('trying to close a non-open file %s'
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
401 % file_baton)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
402 path, data, isexec, islink, copypath = self._openfiles.pop(file_baton)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
403 del self._openpaths[path]
948
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
404 if not isinstance(data, basestring):
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
405 # Files can be opened, properties changed and apply_text
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
406 # never called, in which case data is still a string.
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
407 data = data.getvalue()
942
4d9e80f6ba43 editor: do not touch RevisionData copies from the editor
Patrick Mezard <patrick@mezard.eu>
parents: 941
diff changeset
408 self.current.set(path, data, isexec, islink, copypath)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
409
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
410 @svnwrap.ieditor
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
411 def add_directory(self, path, parent_baton, copyfrom_path,
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
412 copyfrom_revision, dir_pool=None):
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
413 self._checkparentdir(parent_baton)
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
414 baton = self._opendir(path)
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
415
420
59e19c73b0df svnmeta: eliminate unneeded path_and_branch_for_path() method
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 418
diff changeset
416 br_path, branch = self.meta.split_branch_path(path)[:2]
116
30580c05dccc hg_delta_editor: merge _is_path_valid() and _path_and_branch_from_path()
Patrick Mezard <pmezard@gmail.com>
parents: 111
diff changeset
417 if br_path is not None:
30580c05dccc hg_delta_editor: merge _is_path_valid() and _path_and_branch_from_path()
Patrick Mezard <pmezard@gmail.com>
parents: 111
diff changeset
418 if not copyfrom_path and not br_path:
1099
c6f7a8cfeca9 pull: correctly handle replacing the root of a branch with a non-copied directory
David Schleimer <dschleimer@fb.com>
parents: 1039
diff changeset
419 # This handles the case where a branch root is
c6f7a8cfeca9 pull: correctly handle replacing the root of a branch with a non-copied directory
David Schleimer <dschleimer@fb.com>
parents: 1039
diff changeset
420 # replaced without copy info. It will show up as a
c6f7a8cfeca9 pull: correctly handle replacing the root of a branch with a non-copied directory
David Schleimer <dschleimer@fb.com>
parents: 1039
diff changeset
421 # deletion and then an add.
c6f7a8cfeca9 pull: correctly handle replacing the root of a branch with a non-copied directory
David Schleimer <dschleimer@fb.com>
parents: 1039
diff changeset
422 self.meta.closebranches.discard(branch)
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
423 self.current.emptybranches[branch] = True
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
424 else:
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
425 self.current.emptybranches[branch] = False
116
30580c05dccc hg_delta_editor: merge _is_path_valid() and _path_and_branch_from_path()
Patrick Mezard <pmezard@gmail.com>
parents: 111
diff changeset
426 if br_path is None or not copyfrom_path:
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
427 return baton
521
839734dfb5c7 Handle tag subdirectory as tag in replay mode (issue119)
Patrick Mezard <pmezard@gmail.com>
parents: 518
diff changeset
428 if self.meta.get_path_tag(path):
839734dfb5c7 Handle tag subdirectory as tag in replay mode (issue119)
Patrick Mezard <pmezard@gmail.com>
parents: 518
diff changeset
429 del self.current.emptybranches[branch]
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
430 return baton
518
e37738d95b27 editor: remove useless test
Patrick Mezard <pmezard@gmail.com>
parents: 517
diff changeset
431 tag = self.meta.get_path_tag(copyfrom_path)
e37738d95b27 editor: remove useless test
Patrick Mezard <pmezard@gmail.com>
parents: 517
diff changeset
432 if tag not in self.meta.tags:
e37738d95b27 editor: remove useless test
Patrick Mezard <pmezard@gmail.com>
parents: 517
diff changeset
433 tag = None
950
a80b01ceb1fc editor: relax copyfrom dir checks to avoid extra missing entries
Patrick Mezard <patrick@mezard.eu>
parents: 949
diff changeset
434 if not self.meta.is_path_valid(copyfrom_path, existing=False):
a80b01ceb1fc editor: relax copyfrom dir checks to avoid extra missing entries
Patrick Mezard <patrick@mezard.eu>
parents: 949
diff changeset
435 # The source path only exists at copyfrom_revision, use
a80b01ceb1fc editor: relax copyfrom dir checks to avoid extra missing entries
Patrick Mezard <patrick@mezard.eu>
parents: 949
diff changeset
436 # existing=False to guess a possible branch location and
a80b01ceb1fc editor: relax copyfrom dir checks to avoid extra missing entries
Patrick Mezard <patrick@mezard.eu>
parents: 949
diff changeset
437 # test it against the filemap. The actual path and
a80b01ceb1fc editor: relax copyfrom dir checks to avoid extra missing entries
Patrick Mezard <patrick@mezard.eu>
parents: 949
diff changeset
438 # revision will be resolved below if necessary.
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
439 self.addmissing(path, isdir=True)
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
440 return baton
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
441 if tag:
534
e38f110e7088 svnmeta: make it easier to get converted revision info
Patrick Mezard <pmezard@gmail.com>
parents: 528
diff changeset
442 changeid = self.meta.tags[tag]
e38f110e7088 svnmeta: make it easier to get converted revision info
Patrick Mezard <pmezard@gmail.com>
parents: 528
diff changeset
443 source_rev, source_branch = self.meta.get_source_rev(changeid)[:2]
790
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
444 frompath = ''
59
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
445 else:
430af23bef4a Performance fix for branches-from-tags in real replay, which is tied up with
Augie Fackler <durin42@gmail.com>
parents: 55
diff changeset
446 source_rev = copyfrom_revision
790
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
447 frompath, source_branch = self.meta.split_branch_path(copyfrom_path)[:2]
587
c06f59441f8e editor: fix replaced directory copies
Patrick Mezard <pmezard@gmail.com>
parents: 586
diff changeset
448 new_hash = self.meta.get_parent_revision(source_rev + 1, source_branch, True)
1232
ba8485b9fee0 editor: correctly import copies of directories from non-tracked or closed branches
David Schleimer <dschleimer@fb.com>
parents: 1099
diff changeset
449 if frompath is None or new_hash == node.nullid:
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
450 self.addmissing(path, isdir=True)
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
451 return baton
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
452 fromctx = self._getctx(new_hash)
790
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
453 if frompath != '/' and frompath != '':
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
454 frompath = '%s/' % frompath
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
455 else:
790
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
456 frompath = ''
947
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
457
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
458 copyfromparent = False
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
459 if frompath == '' and br_path == '':
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
460 pnode = self.meta.get_parent_revision(
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
461 self.current.rev.revnum, branch)
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
462 if pnode == new_hash:
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
463 # Data parent is topological parent and relative paths
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
464 # are the same, not need to do anything but restore
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
465 # files marked as deleted.
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
466 copyfromparent = True
952
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
467 # Get the parent which would have been used for this branch
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
468 # without the replace action.
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
469 oldpnode = self.meta.get_parent_revision(
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
470 self.current.rev.revnum, branch, exact=True)
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
471 if (oldpnode != revlog.nullid
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
472 and util.isancestor(self._getctx(oldpnode), fromctx)):
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
473 # Branch-wide replacement, unmark the branch as deleted
9c3b4f59e7e6 stupid: do not close branch upon branch-wide revert
Patrick Mezard <patrick@mezard.eu>
parents: 951
diff changeset
474 self.meta.closebranches.discard(branch)
947
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
475
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
476 svncopies = {}
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
477 copies = {}
790
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
478 for f in fromctx:
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
479 if not f.startswith(frompath):
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
480 continue
791
05ee7d5351de editor: simplify add_directory() a bit more
Patrick Mezard <pmezard@gmail.com>
parents: 790
diff changeset
481 dest = path + '/' + f[len(frompath):]
960
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
482 if not self.meta.is_path_valid(dest):
502613f6b583 editor: ignore added or copied files excluded by a filemap
Patrick Mezard <patrick@mezard.eu>
parents: 958
diff changeset
483 continue
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
484 if dest in self._deleted:
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
485 self._deleted.remove(dest)
947
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
486 if copyfromparent:
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
487 continue
e1cb98792cf4 editor: do not reread all data upon branching
Patrick Mezard <patrick@mezard.eu>
parents: 945
diff changeset
488 svncopies[dest] = CopiedFile(new_hash, f, None)
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
489 if branch == source_branch:
791
05ee7d5351de editor: simplify add_directory() a bit more
Patrick Mezard <pmezard@gmail.com>
parents: 790
diff changeset
490 copies[dest] = f
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
491 if copies:
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
492 # Preserve the directory copy records if no file was changed between
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
493 # the source and destination revisions, or discard it completely.
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
494 parentid = self.meta.get_parent_revision(
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
495 self.current.rev.revnum, branch)
69
63ece4ea25c9 hg_delta_editor: register copies only if files are unchanged between source and dest
Patrick Mezard <pmezard@gmail.com>
parents: 67
diff changeset
496 if parentid != revlog.nullid:
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
497 parentctx = self._getctx(parentid)
496
5e0dfe59d4c3 copies: fix under-reporting of copies in hg
Augie Fackler <durin42@gmail.com>
parents: 448
diff changeset
498 for k, v in copies.iteritems():
790
3173f418079c editor: rename add_directory() cp_f* variable into from*
Patrick Mezard <pmezard@gmail.com>
parents: 741
diff changeset
499 if util.issamefile(parentctx, fromctx, v):
940
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
500 svncopies[k].copypath = v
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
501 self._svncopies.update(svncopies)
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
502
792
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
503 # Copy the externals definitions of copied directories
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
504 fromext = svnexternals.parse(self.ui, fromctx)
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
505 for p, v in fromext.iteritems():
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
506 pp = p and (p + '/') or ''
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
507 if pp.startswith(frompath):
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
508 dest = (path + '/' + pp[len(frompath):]).rstrip('/')
ba65c0b01d4f replay: copy copied directories externals
Patrick Mezard <pmezard@gmail.com>
parents: 791
diff changeset
509 self.current.externals[dest] = v
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
510 return baton
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
511
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
512 @svnwrap.ieditor
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
513 def change_file_prop(self, file_baton, name, value, pool=None):
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
514 if file_baton is None:
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
515 return
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
516 path, data, isexec, islink, copypath = self._openfiles[file_baton]
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
517 changed = False
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
518 if name == 'svn:executable':
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
519 changed = True
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
520 isexec = bool(value is not None)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
521 elif name == 'svn:special':
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
522 changed = True
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
523 islink = bool(value is not None)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
524 if changed:
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
525 self._openfiles[file_baton] = (path, data, isexec, islink, copypath)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
526
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
527 @svnwrap.ieditor
174
f80132c5fea5 Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents: 168
diff changeset
528 def change_dir_prop(self, dir_baton, name, value, pool=None):
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
529 self._checkparentdir(dir_baton)
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
530 if len(self._opendirs) == 1:
174
f80132c5fea5 Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents: 168
diff changeset
531 return
1347
759cafce6bec editor: cope with slightly out-of-order editor drives
Augie Fackler <raf@durin42.com>
parents: 1235
diff changeset
532 path = self._opendirs[dir_baton]
174
f80132c5fea5 Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents: 168
diff changeset
533 if name == 'svn:externals':
411
d71972428fce editor: move current revision state into a separate class
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 410
diff changeset
534 self.current.externals[path] = value
174
f80132c5fea5 Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents: 168
diff changeset
535
935
1de83496df4e subvertpy_wrapper: fix files and directories batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 934
diff changeset
536 @svnwrap.ieditor
1de83496df4e subvertpy_wrapper: fix files and directories batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 934
diff changeset
537 def open_root(self, edit_baton, base_revision, dir_pool=None):
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
538 # We should not have to reset these, unfortunately the editor is
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
539 # reused for different revisions.
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
540 self._clear()
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
541 return self._opendir('')
935
1de83496df4e subvertpy_wrapper: fix files and directories batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 934
diff changeset
542
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
543 @svnwrap.ieditor
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
544 def open_directory(self, path, parent_baton, base_revision, dir_pool=None):
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
545 self._checkparentdir(parent_baton)
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
546 baton = self._opendir(path)
420
59e19c73b0df svnmeta: eliminate unneeded path_and_branch_for_path() method
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 418
diff changeset
547 p_, branch = self.meta.split_branch_path(path)[:2]
499
1fd3cfa47c5e Support for single-directory clones.
Augie Fackler <durin42@gmail.com>
parents: 498
diff changeset
548 if p_ == '' or (self.meta.layout == 'single' and p_):
540
8dc759dc9ca9 svnmeta: remove split_branch_tag() exacttag argument
Patrick Mezard <pmezard@gmail.com>
parents: 534
diff changeset
549 if not self.meta.get_path_tag(path):
8dc759dc9ca9 svnmeta: remove split_branch_tag() exacttag argument
Patrick Mezard <pmezard@gmail.com>
parents: 534
diff changeset
550 self.current.emptybranches[branch] = False
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
551 return baton
174
f80132c5fea5 Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents: 168
diff changeset
552
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
553 @svnwrap.ieditor
174
f80132c5fea5 Convert svn:externals properties into a .hgsvnexternals file
Patrick Mezard <pmezard@gmail.com>
parents: 168
diff changeset
554 def close_directory(self, dir_baton, dir_pool=None):
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
555 self._checkparentdir(dir_baton)
1347
759cafce6bec editor: cope with slightly out-of-order editor drives
Augie Fackler <raf@durin42.com>
parents: 1235
diff changeset
556 del self._opendirs[dir_baton]
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
557
673
32089d080ff8 editor: move ieditor decorator into svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 633
diff changeset
558 @svnwrap.ieditor
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
559 def apply_textdelta(self, file_baton, base_checksum, pool=None):
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
560 if file_baton is None:
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
561 return lambda x: None
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
562 if file_baton not in self._openfiles:
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
563 raise EditingError('trying to patch a closed file %s' % file_baton)
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
564 path, base, isexec, islink, copypath = self._openfiles[file_baton]
948
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
565 if not isinstance(base, basestring):
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
566 raise EditingError('trying to edit a file again: %s' % path)
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
567 if not self.meta.is_path_valid(path):
211
05243ec295e1 fetch: Fix a bug that caused plaintexts to be interpreted as missing more often than they should be.
Augie Fackler <durin42@gmail.com>
parents: 207
diff changeset
568 return lambda x: None
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
569
948
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
570 target = svnwrap.SimpleStringIO(closing=False)
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
571 self.stream = target
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
572
601
0fe490ce2fbb isolate all imports of Subversion modules in svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 591
diff changeset
573 handler = svnwrap.apply_txdelta(base, target)
837
805ef27fbcbe hgsubversion/*.py: add space after comment symbol #
Yonggang Luo <luoyonggang@gmail.com>
parents: 832
diff changeset
574 if not callable(handler): # pragma: no cover
250
79349fd04836 utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents: 237
diff changeset
575 raise hgutil.Abort('Error in Subversion bindings: '
79349fd04836 utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents: 237
diff changeset
576 'cannot call handler!')
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
577 def txdelt_window(window):
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
578 try:
937
fb6f6b7fa5a5 editor: implement file batons
Patrick Mezard <patrick@mezard.eu>
parents: 935
diff changeset
579 if not self.meta.is_path_valid(path):
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
580 return
932
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
581 try:
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
582 handler(window)
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
583 except AssertionError, e: # pragma: no cover
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
584 # Enhance the exception message
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
585 msg, others = e.args[0], e.args[1:]
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
586
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
587 if msg:
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
588 msg += '\n'
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
589
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
590 msg += _TXDELT_WINDOW_HANDLER_FAILURE_MSG
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
591 e.args = (msg,) + others
977
f3d900d320b9 editor: ensure that we propagate full stacktraces in a few places
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 963
diff changeset
592
f3d900d320b9 editor: ensure that we propagate full stacktraces in a few places
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 963
diff changeset
593 # re-raising ensures that we show the full stack trace
f3d900d320b9 editor: ensure that we propagate full stacktraces in a few places
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 963
diff changeset
594 raise
932
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
595
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
596 # window being None means commit this file
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
597 if not window:
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
598 self._openfiles[file_baton] = (
948
e2090fabc1a9 editor: use SimpleStringIO in apply_text()
Patrick Mezard <patrick@mezard.eu>
parents: 947
diff changeset
599 path, target, isexec, islink, copypath)
837
805ef27fbcbe hgsubversion/*.py: add space after comment symbol #
Yonggang Luo <luoyonggang@gmail.com>
parents: 832
diff changeset
600 except svnwrap.SubversionException, e: # pragma: no cover
977
f3d900d320b9 editor: ensure that we propagate full stacktraces in a few places
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 963
diff changeset
601 self.ui.traceback()
601
0fe490ce2fbb isolate all imports of Subversion modules in svnwrap.
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 591
diff changeset
602 if e.args[1] == svnwrap.ERR_INCOMPLETE_DATA:
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
603 self.addmissing(path)
837
805ef27fbcbe hgsubversion/*.py: add space after comment symbol #
Yonggang Luo <luoyonggang@gmail.com>
parents: 832
diff changeset
604 else: # pragma: no cover
250
79349fd04836 utils: standardizing imported name to hgutil, our_util to util
Daniel Tang <dytang@cs.purdue.edu>
parents: 237
diff changeset
605 raise hgutil.Abort(*e.args)
837
805ef27fbcbe hgsubversion/*.py: add space after comment symbol #
Yonggang Luo <luoyonggang@gmail.com>
parents: 832
diff changeset
606 except: # pragma: no cover
0
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
607 self._exception_info = sys.exc_info()
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
608 raise
f2636cfed115 Initial import of hgsubversion into a public repository.
Augie Fackler <durin42@gmail.com>
parents:
diff changeset
609 return txdelt_window
932
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
610
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
611 def close(self):
939
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
612 if self._openfiles:
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
613 for e in self._openfiles.itervalues():
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
614 self.ui.debug('error: %s was not closed\n' % e[0])
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
615 raise EditingError('%d edited files were not closed'
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
616 % len(self._openfiles))
997de286ba0c editor: add close_file(), enforce file batons semantics
Patrick Mezard <patrick@mezard.eu>
parents: 938
diff changeset
617
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
618 if self._opendirs:
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
619 raise EditingError('directory %s was not closed'
1347
759cafce6bec editor: cope with slightly out-of-order editor drives
Augie Fackler <raf@durin42.com>
parents: 1235
diff changeset
620 % self._opendirs.keys()[-1])
958
506dcb241cef editor: tidy up directory batons handling
Patrick Mezard <patrick@mezard.eu>
parents: 957
diff changeset
621
940
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
622 # Resolve by changelog entries to avoid extra reads
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
623 nodes = {}
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
624 for path, copy in self._svncopies.iteritems():
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
625 nodes.setdefault(copy.node, []).append((path, copy))
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
626 for node, copies in nodes.iteritems():
34a1217b8218 editor: resolve files copied by directory copy on-demand
Patrick Mezard <patrick@mezard.eu>
parents: 939
diff changeset
627 for path, copy in copies:
951
bd9c292665fd editor: add a small changectx cache
Patrick Mezard <patrick@mezard.eu>
parents: 950
diff changeset
628 data, isexec, islink, copied = copy.resolve(self._getctx)
942
4d9e80f6ba43 editor: do not touch RevisionData copies from the editor
Patrick Mezard <patrick@mezard.eu>
parents: 941
diff changeset
629 self.current.set(path, data, isexec, islink, copied)
938
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
630 self._svncopies.clear()
f9014e28721b editor: start separating svn copies from open files
Patrick Mezard <patrick@mezard.eu>
parents: 937
diff changeset
631
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
632 # Resolve missing files
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
633 if self._missing:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
634 missing = sorted(self._missing)
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
635 self.ui.debug('fetching %s files that could not use replay.\n'
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
636 % len(missing))
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
637 if self.ui.configbool('hgsubversion', 'failonmissing', False):
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
638 raise EditingError('missing entry: %s' % missing[0])
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
639
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
640 svn = self._svn
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
641 rev = self.current.rev.revnum
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
642 root = svn.subdir and svn.subdir[1:] or ''
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
643 i = 1
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
644 for f in missing:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
645 if self.ui.debugflag:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
646 self.ui.debug('fetching %s\n' % f)
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
647 else:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
648 self.ui.note('.')
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
649 self.ui.flush()
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
650 if i % 50 == 0:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
651 svn.init_ra_and_client()
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
652 i += 1
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
653 data, mode = svn.get_file(f, rev)
1234
d3c79072bc6a editor: correctly import symlink copy+modify with non-empty prefix
David Schleimer <dschleimer@fb.com>
parents: 1233
diff changeset
654 self.current.set(root + f, data, 'x' in mode, 'l' in mode)
962
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
655 if not self.ui.debugflag:
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
656 self.ui.note('\n')
8648ccfb8325 editor: process missing files with regular files
Patrick Mezard <patrick@mezard.eu>
parents: 960
diff changeset
657
941
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
658 for f in self._deleted:
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
659 self.current.delete(f)
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
660 self._deleted.clear()
febca88dd261 editor: handle deleted files in editor
Patrick Mezard <patrick@mezard.eu>
parents: 940
diff changeset
661
932
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
662 _TXDELT_WINDOW_HANDLER_FAILURE_MSG = (
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
663 "Your SVN repository may not be supplying correct replay deltas."
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
664 " It is strongly"
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
665 "\nadvised that you repull the entire SVN repository using"
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
666 " hg pull --stupid."
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
667 "\nAlternatively, re-pull just this revision using --stupid and verify"
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
668 " that the"
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
669 "\nchangeset is correct."
dfb3afa6c619 stupid: Fail over to full revision when a PatchError is thrown (issue294)
Tim Delaney <timothy.c.delaney@gmail.com>
parents: 901
diff changeset
670 )