comparison hgext/convert/monotone.py @ 8099:3cdf4872941a

convert/mtn: handle new files in moved directories (issue1619) Reported and investigated by Paul Aurich <paul@darkrain42.org>
author Patrick Mezard <pmezard@gmail.com>
date Tue, 21 Apr 2009 14:17:29 +0200
parents 087cc65bebff
children 233f11b544f5 d8229670710f
comparison
equal deleted inserted replaced
8081:6c3b8132078e 8099:3cdf4872941a
106 value = value.replace(r'\"', '"') 106 value = value.replace(r'\"', '"')
107 value = value.replace(r'\\', '\\') 107 value = value.replace(r'\\', '\\')
108 certs[name] = value 108 certs[name] = value
109 return certs 109 return certs
110 110
111 def mtnrenamefiles(self, files, fromdir, todir):
112 renamed = {}
113 for tofile in files:
114 if tofile.startswith(todir + '/'):
115 renamed[tofile] = fromdir + tofile[len(todir):]
116 return renamed
117
118 # implement the converter_source interface: 111 # implement the converter_source interface:
119 112
120 def getheads(self): 113 def getheads(self):
121 if not self.rev: 114 if not self.rev:
122 return self.mtnrun("leaves").splitlines() 115 return self.mtnrun("leaves").splitlines()
125 118
126 def getchanges(self, rev): 119 def getchanges(self, rev):
127 #revision = self.mtncmd("get_revision %s" % rev).split("\n\n") 120 #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
128 revision = self.mtnrun("get_revision", rev).split("\n\n") 121 revision = self.mtnrun("get_revision", rev).split("\n\n")
129 files = {} 122 files = {}
123 addedfiles = {}
124 renameddirs = []
130 copies = {} 125 copies = {}
131 for e in revision: 126 for e in revision:
132 m = self.add_file_re.match(e) 127 m = self.add_file_re.match(e)
133 if m: 128 if m:
134 files[m.group(1)] = rev 129 files[m.group(1)] = rev
130 addedfiles[m.group(1)] = rev
135 m = self.patch_re.match(e) 131 m = self.patch_re.match(e)
136 if m: 132 if m:
137 files[m.group(1)] = rev 133 files[m.group(1)] = rev
138
139 # Delete/rename is handled later when the convert engine 134 # Delete/rename is handled later when the convert engine
140 # discovers an IOError exception from getfile, 135 # discovers an IOError exception from getfile,
141 # but only if we add the "from" file to the list of changes. 136 # but only if we add the "from" file to the list of changes.
142 m = self.delete_re.match(e) 137 m = self.delete_re.match(e)
143 if m: 138 if m:
148 fromname = m.group(1) 143 fromname = m.group(1)
149 if self.mtnisfile(toname, rev): 144 if self.mtnisfile(toname, rev):
150 copies[toname] = fromname 145 copies[toname] = fromname
151 files[toname] = rev 146 files[toname] = rev
152 files[fromname] = rev 147 files[fromname] = rev
153 if self.mtnisdir(toname, rev): 148 elif self.mtnisdir(toname, rev):
154 renamed = self.mtnrenamefiles(self.files, fromname, toname) 149 renameddirs.append((fromname, toname))
155 for tofile, fromfile in renamed.items(): 150
156 self.ui.debug (_("copying file in renamed dir from '%s' to '%s'") % (fromfile, tofile), '\n') 151 # Directory renames can be handled only once we have recorded
157 files[tofile] = rev 152 # all new files
158 copies[tofile] = fromfile 153 for fromdir, todir in renameddirs:
159 for fromfile in renamed.values(): 154 renamed = {}
160 files[fromfile] = rev 155 for tofile in self.files:
156 if tofile in addedfiles:
157 continue
158 if tofile.startswith(todir + '/'):
159 renamed[tofile] = fromdir + tofile[len(todir):]
160 for tofile, fromfile in renamed.items():
161 self.ui.debug (_("copying file in renamed dir from '%s' to '%s'")
162 % (fromfile, tofile), '\n')
163 files[tofile] = rev
164 copies[tofile] = fromfile
165 for fromfile in renamed.values():
166 files[fromfile] = rev
167
161 return (files.items(), copies) 168 return (files.items(), copies)
162 169
163 def getmode(self, name, rev): 170 def getmode(self, name, rev):
164 self.mtnloadmanifest(rev) 171 self.mtnloadmanifest(rev)
165 try: 172 try: