##// END OF EJS Templates
convert: add commandline.xargs(), use it in svn_sink class...
Maxim Dounin -
r5832:2192ed18 default
parent child Browse files
Show More
@@ -1,5 +1,6
1 # common code for the convert extension
1 # common code for the convert extension
2 import base64, errno
2 import base64, errno
3 import os
3 import cPickle as pickle
4 import cPickle as pickle
4 from mercurial import util
5 from mercurial import util
5 from mercurial.i18n import _
6 from mercurial.i18n import _
@@ -212,7 +213,7 class commandline(object):
212 def postrun(self):
213 def postrun(self):
213 pass
214 pass
214
215
215 def _run(self, cmd, *args, **kwargs):
216 def _cmdline(self, cmd, *args, **kwargs):
216 cmdline = [self.command, cmd] + list(args)
217 cmdline = [self.command, cmd] + list(args)
217 for k, v in kwargs.iteritems():
218 for k, v in kwargs.iteritems():
218 if len(k) == 1:
219 if len(k) == 1:
@@ -230,7 +231,10 class commandline(object):
230 cmdline += ['<', util.nulldev]
231 cmdline += ['<', util.nulldev]
231 cmdline = ' '.join(cmdline)
232 cmdline = ' '.join(cmdline)
232 self.ui.debug(cmdline, '\n')
233 self.ui.debug(cmdline, '\n')
234 return cmdline
233
235
236 def _run(self, cmd, *args, **kwargs):
237 cmdline = self._cmdline(cmd, *args, **kwargs)
234 self.prerun()
238 self.prerun()
235 try:
239 try:
236 return util.popen(cmdline)
240 return util.popen(cmdline)
@@ -256,6 +260,47 class commandline(object):
256 self.checkexit(status, output)
260 self.checkexit(status, output)
257 return output
261 return output
258
262
263 def getargmax(self):
264 if '_argmax' in self.__dict__:
265 return self._argmax
266
267 # POSIX requires at least 4096 bytes for ARG_MAX
268 self._argmax = 4096
269 try:
270 self._argmax = os.sysconf("SC_ARG_MAX")
271 except:
272 pass
273
274 # Windows shells impose their own limits on command line length,
275 # down to 2047 bytes for cmd.exe under Windows NT/2k and 2500 bytes
276 # for older 4nt.exe. See http://support.microsoft.com/kb/830473 for
277 # details about cmd.exe limitations.
278
279 # Since ARG_MAX is for command line _and_ environment, lower our limit
280 # (and make happy Windows shells while doing this).
281
282 self._argmax = self._argmax/2 - 1
283 return self._argmax
284
285 def limit_arglist(self, arglist, cmd, *args, **kwargs):
286 limit = self.getargmax() - len(self._cmdline(cmd, *args, **kwargs))
287 bytes = 0
288 fl = []
289 for fn in arglist:
290 b = len(fn) + 3
291 if bytes + b < limit or len(fl) == 0:
292 fl.append(fn)
293 bytes += b
294 else:
295 yield fl
296 fl = [fn]
297 bytes = b
298 if fl:
299 yield fl
300
301 def xargs(self, arglist, cmd, *args, **kwargs):
302 for l in self.limit_arglist(arglist, cmd, *args, **kwargs):
303 self.run0(cmd, *(list(args) + l), **kwargs)
259
304
260 class mapfile(dict):
305 class mapfile(dict):
261 def __init__(self, ui, path):
306 def __init__(self, ui, path):
@@ -707,27 +707,6 exit 1
707 class svn_sink(converter_sink, commandline):
707 class svn_sink(converter_sink, commandline):
708 commit_re = re.compile(r'Committed revision (\d+).', re.M)
708 commit_re = re.compile(r'Committed revision (\d+).', re.M)
709
709
710 # iterates sublist of given list for concatenated length is within limit
711 def limit_arglist(self, files):
712 if os.name != 'nt':
713 yield files
714 return
715 # When I tested on WinXP, limit = 2500 is NG, 2400 is OK
716 limit = 2000
717 bytes = 0
718 fl = []
719 for fn in files:
720 b = len(fn) + 1
721 if bytes + b < limit:
722 fl.append(fn)
723 bytes += b
724 else:
725 yield fl
726 fl = [fn]
727 bytes = b
728 if fl:
729 yield fl
730
731 def prerun(self):
710 def prerun(self):
732 if self.wc:
711 if self.wc:
733 os.chdir(self.wc)
712 os.chdir(self.wc)
@@ -866,14 +845,12 class svn_sink(converter_sink, commandli
866 if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
845 if not os.path.exists(self.wjoin(d, '.svn', 'entries'))]
867 if add_dirs:
846 if add_dirs:
868 add_dirs.sort()
847 add_dirs.sort()
869 for fl in self.limit_arglist(add_dirs):
848 self.xargs(add_dirs, 'add', non_recursive=True, quiet=True)
870 self.run('add', non_recursive=True, quiet=True, *fl)
871 return add_dirs
849 return add_dirs
872
850
873 def add_files(self, files):
851 def add_files(self, files):
874 if files:
852 if files:
875 for fl in self.limit_arglist(files):
853 self.xargs(files, 'add', quiet=True)
876 self.run('add', quiet=True, *fl)
877 return files
854 return files
878
855
879 def tidy_dirs(self, names):
856 def tidy_dirs(self, names):
@@ -907,18 +884,15 class svn_sink(converter_sink, commandli
907 self._copyfile(s, d)
884 self._copyfile(s, d)
908 self.copies = []
885 self.copies = []
909 if self.delete:
886 if self.delete:
910 for fl in self.limit_arglist(self.delete):
887 self.xargs(self.delete, 'delete')
911 self.run0('delete', *fl)
912 self.delete = []
888 self.delete = []
913 entries.update(self.add_files(files.difference(entries)))
889 entries.update(self.add_files(files.difference(entries)))
914 entries.update(self.tidy_dirs(entries))
890 entries.update(self.tidy_dirs(entries))
915 if self.delexec:
891 if self.delexec:
916 for fl in self.limit_arglist(self.delexec):
892 self.xargs(self.delexec, 'propdel', 'svn:executable')
917 self.run0('propdel', 'svn:executable', *fl)
918 self.delexec = []
893 self.delexec = []
919 if self.setexec:
894 if self.setexec:
920 for fl in self.limit_arglist(self.setexec):
895 self.xargs(self.setexec, 'propset', 'svn:executable', '*')
921 self.run0('propset', 'svn:executable', '*', *fl)
922 self.setexec = []
896 self.setexec = []
923
897
924 fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
898 fd, messagefile = tempfile.mkstemp(prefix='hg-convert-')
General Comments 0
You need to be logged in to leave comments. Login now