git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: git-cvsexportcommit fails for huge commits

From
Jeff King <peff@peff.net>
Date
Dec 12, 2007, 08:31 UTC
Message-ID
<20071212083154.GB7676@coredump.intra.peff.net>
In-Reply-To
<20071211200418.GA13815@mkl-desktop>
On Tue, Dec 11, 2007 at 09:04:18PM +0100, Markus Klinik wrote:
Show 11 quoted lines
> git-cvsexportcommit fails for huge commits, that is commits with lots
> of files.  To be exact, the problem arises if the generated 'cvs
> status' command exceeds the maximum length for commands.
> 
> Here is the error:
> 
> Can't exec "cvs": Argument list too long at
> /home/mkl/bin/git-cvsexportcommit line 334.  Argument list too long 0
> at /home/mkl/bin/git-cvsexportcommit line 334.  cvs status [snip:
> long, long list of files]  1792 at /home/mkl/bin/git-cvsexportcommit
> line 332.

Yuck. Unfortunately, CVS doesn't offer a more scalable interface, so we are stuck splitting the arguments across multiple invocations.

However, I think this should work. The output of "cvs status foo bar" is the same as "cvs status foo; cvs status bar". We will make our commits in two CVS invocations, but since CVS isn't atomic _anyway_, we shouldn't mind losing the atomicity.

Does the patch below clear up your problem?
---
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index 92e4162..20e432b 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -195,11 +195,11 @@ foreach my $f (@files) {
 my %cvsstat;
 if (@canstatusfiles) {
     if ($opt_u) {
-      my @updated = safe_pipe_capture(@cvs, 'update', @canstatusfiles);
+      my @updated = xargs_safe_pipe_capture([@cvs, 'update'], @canstatusfiles);
       print @updated;
     }
     my @cvsoutput;
-    @cvsoutput= safe_pipe_capture(@cvs, 'status', @canstatusfiles);
+    @cvsoutput = xargs_safe_pipe_capture([@cvs, 'status'], @canstatusfiles);
     my $matchcount = 0;
     foreach my $l (@cvsoutput) {
         chomp $l;
@@ -295,7 +295,7 @@ if ($dirtypatch) {
 
 if ($opt_c) {
     print "Autocommit\n  $cmd\n";
-    print safe_pipe_capture(@cvs, 'commit', '-F', '.msg', @files);
+    print xargs_safe_pipe_capture([@cvs, 'commit', '-F', '.msg'], @files);
     if ($?) {
 	die "Exiting: The commit did not succeed";
     }
@@ -335,6 +335,22 @@ sub safe_pipe_capture {
     return wantarray ? @output : join('',@output);
 }
 
+sub xargs_safe_pipe_capture {
+	my $MAX_ARG_LENGTH = 1024;
+	my $cmd = shift;
+	my @output;
+	while(@_) {
+		my @args;
+		my $length = 0;
+		while(@_ && $length < $MAX_ARG_LENGTH) {
+			push @args, shift;
+			$length += length($args[$#args]);
+		}
+		push @output, safe_pipe_capture(@$cmd, @args);
+	}
+	return @output;
+}
+
 sub safe_pipe_capture_blob {
     my $output;
     if (my $pid = open my $child, '-|') {
Previous: Markus KlinikNext: Junio C Hamano
Message 2 of 15 in “git-cvsexportcommit fails for huge commits”
  1. Markus KlinikDec 11, 2007
  2. Jeff KingDec 12, 2007
  3. Junio C HamanoDec 12, 2007
  4. Jeff KingDec 12, 2007
  5. Junio C HamanoDec 14, 2007
  6. Jeff KingDec 14, 2007
  7. Jeff KingDec 14, 2007
  8. Robin RosenbergDec 14, 2007
  9. Jeff KingDec 15, 2007
  10. Linus TorvaldsDec 12, 2007
  11. Jeff KingDec 12, 2007
  12. Martin LanghoffDec 12, 2007
  13. Jeff KingDec 13, 2007
  14. Markus KlinikDec 13, 2007
  15. Jeff KingDec 13, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.