comparison hgext/convert/gnuarch.py @ 7585:075b7ef0f84d

convert/gnuarch: follow continuation-of revisions Built on top of previous patches: - continuation-of parsing - registered archives retrieval - use of fully qualified revisions This allows the converter scanning for more source revisions following the tree versions 'leaked' through the continuation-of informations. Coupled with the registered archives retrieval, this makes possible to decide to follow such a hint or stop scanning for more revisions. This also implies some changes in the retrieval of some base-0 revisions when they're continuation-of other revisions, in that case a 'replay' will work where a simple 'get' fails because the dir exists already. I found the code dealing with 'replay' quite good as it has already a fallback to 'get' in the error path.
author Edouard Gomez <ed.gomez@free.fr>
date Sun, 04 Jan 2009 02:36:48 +0100
parents 28563e94c471
children 489c2cfbdd71
comparison
equal deleted inserted replaced
7584:28563e94c471 7585:075b7ef0f84d
61 output = self.run0('tree-version', self.path) 61 output = self.run0('tree-version', self.path)
62 else: 62 else:
63 output = self.run0('tree-version', '-d', self.path) 63 output = self.run0('tree-version', '-d', self.path)
64 self.treeversion = output.strip() 64 self.treeversion = output.strip()
65 65
66 self.ui.status(_('analyzing tree version %s...\n') % self.treeversion)
67
68 # Get name of temporary directory 66 # Get name of temporary directory
69 version = self.treeversion.split('/') 67 version = self.treeversion.split('/')
70 self.tmppath = os.path.join(tempfile.gettempdir(), 68 self.tmppath = os.path.join(tempfile.gettempdir(),
71 'hg-%s' % version[1]) 69 'hg-%s' % version[1])
72 70
73 # Generate parents dictionary 71 # Generate parents dictionary
74 child = [] 72 self.parents[None] = []
75 output, status = self.runlines('revisions', '-f', self.treeversion) 73 treeversion = self.treeversion
76 self.checkexit(status, 'archive registered?') 74 child = None
77 for l in output: 75 while treeversion:
78 rev = l.strip() 76 self.ui.status(_('analyzing tree version %s...\n') % treeversion)
79 self.changes[rev] = self.gnuarch_rev(rev) 77
80 78 archive = treeversion.split('/')[0]
81 # Read author, date and summary 79 if archive not in self.archives:
82 catlog, status = self.run('cat-log', '-d', self.path, rev) 80 self.ui.status(_('tree analysis stopped because it points to an unregistered archive %s...\n') % archive)
83 if status:
84 catlog = self.run0('cat-archive-log', rev)
85 self._parsecatlog(catlog, rev)
86
87 self.parents[rev] = child
88 child = [rev]
89 if rev == self.rev:
90 break 81 break
91 self.parents[None] = child 82
83 # Get the complete list of revisions for that tree version
84 output, status = self.runlines('revisions', '-r', '-f', treeversion)
85 self.checkexit(status, 'failed retrieveing revisions for %s' % treeversion)
86
87 # No new iteration unless a revision has a continuation-of header
88 treeversion = None
89
90 for l in output:
91 rev = l.strip()
92 self.changes[rev] = self.gnuarch_rev(rev)
93 self.parents[rev] = []
94
95 # Read author, date and summary
96 catlog, status = self.run('cat-log', '-d', self.path, rev)
97 if status:
98 catlog = self.run0('cat-archive-log', rev)
99 self._parsecatlog(catlog, rev)
100
101 # Populate the parents map
102 self.parents[child].append(rev)
103
104 # Keep track of the current revision as the child of the next
105 # revision scanned
106 child = rev
107
108 # Check if we have to follow the usual incremental history
109 # or if we have to 'jump' to a different treeversion given
110 # by the continuation-of header.
111 if self.changes[rev].continuationof:
112 treeversion = '--'.join(self.changes[rev].continuationof.split('--')[:-1])
113 break
114
115 # If we reached a base-0 revision w/o any continuation-of
116 # header, it means the tree history ends here.
117 if rev[-6:] == 'base-0':
118 break
92 119
93 def after(self): 120 def after(self):
94 self.ui.debug(_('cleaning up %s\n') % self.tmppath) 121 self.ui.debug(_('cleaning up %s\n') % self.tmppath)
95 shutil.rmtree(self.tmppath, ignore_errors=True) 122 shutil.rmtree(self.tmppath, ignore_errors=True)
96 123
160 cmdline = util.quotecommand(' '.join(cmdline)) 187 cmdline = util.quotecommand(' '.join(cmdline))
161 self.ui.debug(cmdline, '\n') 188 self.ui.debug(cmdline, '\n')
162 return os.system(cmdline) 189 return os.system(cmdline)
163 190
164 def _update(self, rev): 191 def _update(self, rev):
165 if rev[-6:] == 'base-0': 192 self.ui.debug(_('applying revision %s...\n') % rev)
166 # Initialise 'base-0' revision 193 changeset, status = self.runlines('replay', '-d', self.tmppath,
194 rev)
195 if status:
196 # Something went wrong while merging (baz or tla
197 # issue?), get latest revision and try from there
198 shutil.rmtree(self.tmppath, ignore_errors=True)
167 self._obtainrevision(rev) 199 self._obtainrevision(rev)
168 else: 200 else:
169 self.ui.debug(_('applying revision %s...\n') % rev) 201 old_rev = self.parents[rev][0]
170 changeset, status = self.runlines('replay', '-d', self.tmppath, 202 self.ui.debug(_('computing changeset between %s and %s...\n')
171 rev) 203 % (old_rev, rev))
172 if status: 204 self._parsechangeset(changeset, rev)
173 # Something went wrong while merging (baz or tla
174 # issue?), get latest revision and try from there
175 shutil.rmtree(self.tmppath, ignore_errors=True)
176 self._obtainrevision(rev)
177 else:
178 old_rev = self.parents[rev][0]
179 self.ui.debug(_('computing changeset between %s and %s...\n')
180 % (old_rev, rev))
181 self._parsechangeset(changeset, rev)
182 205
183 def _getfile(self, name, rev): 206 def _getfile(self, name, rev):
184 mode = os.lstat(os.path.join(self.tmppath, name)).st_mode 207 mode = os.lstat(os.path.join(self.tmppath, name)).st_mode
185 if stat.S_ISLNK(mode): 208 if stat.S_ISLNK(mode):
186 data = os.readlink(os.path.join(self.tmppath, name)) 209 data = os.readlink(os.path.join(self.tmppath, name))