128 def close(self): |
128 def close(self): |
129 if self._stdout: |
129 if self._stdout: |
130 self._stdout.close() |
130 self._stdout.close() |
131 self._stdout = None |
131 self._stdout = None |
132 |
132 |
133 def get_log(url, paths, start, end, limit=0, discover_changed_paths=True, |
|
134 strict_node_history=False): |
|
135 args = [url, paths, start, end, limit, discover_changed_paths, |
|
136 strict_node_history] |
|
137 arg = encodeargs(args) |
|
138 hgexe = util.hgexecutable() |
|
139 cmd = '%s debugsvnlog' % util.shellquote(hgexe) |
|
140 stdin, stdout = os.popen2(cmd, 'b') |
|
141 stdin.write(arg) |
|
142 stdin.close() |
|
143 return logstream(stdout) |
|
144 |
|
145 # SVN conversion code stolen from bzr-svn and tailor |
133 # SVN conversion code stolen from bzr-svn and tailor |
146 # |
134 # |
147 # Subversion looks like a versioned filesystem, branches structures |
135 # Subversion looks like a versioned filesystem, branches structures |
148 # are defined by conventions and not enforced by the tool. First, |
136 # are defined by conventions and not enforced by the tool. First, |
149 # we define the potential branches (modules) as "trunk" and "branches" |
137 # we define the potential branches (modules) as "trunk" and "branches" |
392 # change in the future. |
380 # change in the future. |
393 pendings = [] |
381 pendings = [] |
394 tagspath = self.tags |
382 tagspath = self.tags |
395 start = svn.ra.get_latest_revnum(self.ra) |
383 start = svn.ra.get_latest_revnum(self.ra) |
396 try: |
384 try: |
397 for entry in get_log(self.url, [self.tags], start, self.startrev): |
385 for entry in self._getlog([self.tags], start, self.startrev): |
398 origpaths, revnum, author, date, message = entry |
386 origpaths, revnum, author, date, message = entry |
399 copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e |
387 copies = [(e.copyfrom_path, e.copyfrom_rev, p) for p, e |
400 in origpaths.iteritems() if e.copyfrom_path] |
388 in origpaths.iteritems() if e.copyfrom_path] |
401 copies.sort() |
389 copies.sort() |
402 # Apply moves/copies from more specific to general |
390 # Apply moves/copies from more specific to general |
488 raise util.Abort('%s not found up to revision %d' % (path, stop)) |
476 raise util.Abort('%s not found up to revision %d' % (path, stop)) |
489 |
477 |
490 # stat() gives us the previous revision on this line of development, but |
478 # stat() gives us the previous revision on this line of development, but |
491 # it might be in *another module*. Fetch the log and detect renames down |
479 # it might be in *another module*. Fetch the log and detect renames down |
492 # to the latest revision. |
480 # to the latest revision. |
493 stream = get_log(self.url, [path], stop, dirent.created_rev) |
481 stream = self._getlog([path], stop, dirent.created_rev) |
494 try: |
482 try: |
495 for entry in stream: |
483 for entry in stream: |
496 paths, revnum, author, date, message = entry |
484 paths, revnum, author, date, message = entry |
497 if revnum <= dirent.created_rev: |
485 if revnum <= dirent.created_rev: |
498 break |
486 break |
812 (self.module, from_revnum, to_revnum)) |
800 (self.module, from_revnum, to_revnum)) |
813 |
801 |
814 try: |
802 try: |
815 firstcset = None |
803 firstcset = None |
816 lastonbranch = False |
804 lastonbranch = False |
817 stream = get_log(self.url, [self.module], from_revnum, to_revnum) |
805 stream = self._getlog([self.module], from_revnum, to_revnum) |
818 try: |
806 try: |
819 for entry in stream: |
807 for entry in stream: |
820 paths, revnum, author, date, message = entry |
808 paths, revnum, author, date, message = entry |
821 if revnum < self.startrev: |
809 if revnum < self.startrev: |
822 lastonbranch = True |
810 lastonbranch = True |
909 |
897 |
910 def _checkpath(self, path, revnum): |
898 def _checkpath(self, path, revnum): |
911 # ra.check_path does not like leading slashes very much, it leads |
899 # ra.check_path does not like leading slashes very much, it leads |
912 # to PROPFIND subversion errors |
900 # to PROPFIND subversion errors |
913 return svn.ra.check_path(self.ra, path.strip('/'), revnum) |
901 return svn.ra.check_path(self.ra, path.strip('/'), revnum) |
|
902 |
|
903 def _getlog(self, paths, start, end, limit=0, discover_changed_paths=True, |
|
904 strict_node_history=False): |
|
905 # Normalize path names, svn >= 1.5 only wants paths relative to |
|
906 # supplied URL |
|
907 relpaths = [] |
|
908 for p in paths: |
|
909 if not p.startswith('/'): |
|
910 p = self.module + '/' + p |
|
911 relpaths.append(p.strip('/')) |
|
912 args = [self.base, relpaths, start, end, limit, discover_changed_paths, |
|
913 strict_node_history] |
|
914 arg = encodeargs(args) |
|
915 hgexe = util.hgexecutable() |
|
916 cmd = '%s debugsvnlog' % util.shellquote(hgexe) |
|
917 stdin, stdout = os.popen2(cmd, 'b') |
|
918 stdin.write(arg) |
|
919 stdin.close() |
|
920 return logstream(stdout) |
914 |
921 |
915 pre_revprop_change = '''#!/bin/sh |
922 pre_revprop_change = '''#!/bin/sh |
916 |
923 |
917 REPOS="$1" |
924 REPOS="$1" |
918 REV="$2" |
925 REV="$2" |