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

[PATCH 3/3] Make cvsexportcommit create parent directories as needed.

From
Yann Dirson <ydirson@altern.org>
Date
May 27, 2006, 16:39 UTC
Message-ID
<20060527163935.474.22794.stgit@gandelf.nowhere.earth>
In-Reply-To
<20060527163641.474.93575.stgit@gandelf.nowhere.earth>

This is a quick port of my initial patch for 1.0.7, that I had forgotten to post. Possibly needs some testing before applying to master.

Signed-off-by: Yann Dirson <ydirson@altern.org>
---
 git-cvsexportcommit.perl |   37 ++++++++++++++++++++++++++++++++-----
 1 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index 3e4e90b..57088c3 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -2,7 +2,6 @@ #!/usr/bin/perl -w
 
 # Known limitations:
 # - cannot add or remove binary files
-# - cannot add parent directories when needed
 # - does not propagate permissions
 # - tells "ready for commit" even when things could not be completed
 #   (eg addition of a binary file)
@@ -11,7 +10,7 @@ use strict;
 use Getopt::Std;
 use File::Temp qw(tempdir);
 use Data::Dumper;
-use File::Basename qw(basename);
+use File::Basename qw(basename dirname);
 
 unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
     die "GIT_DIR is not defined or is unreadable";
@@ -91,7 +90,7 @@ close MSG;
 `git-cat-file commit $commit | sed -e '1,/^\$/d' >> .msg`;
 $? && die "Error extracting the commit message";
 
-my (@afiles, @dfiles, @mfiles);
+my (@afiles, @dfiles, @mfiles, @dirs);
 my @files = safe_pipe_capture('git-diff-tree', '-r', $parent, $commit);
 #print @files;
 $? && die "Error in git-diff-tree";
@@ -99,7 +98,14 @@ foreach my $f (@files) {
     chomp $f;
     my @fields = split(m!\s+!, $f);
     if ($fields[4] eq 'A') {
-	push @afiles, $fields[5];
+        my $path = $fields[5];
+	push @afiles, $path;
+        # add any needed parent directories
+	$path = dirname $path;
+	while (!-d $path and ! grep { $_ eq $path } @dirs) {
+	    unshift @dirs, $path;
+	    $path = dirname $path;
+	}
     }
     if ($fields[4] eq 'M') {
 	push @mfiles, $fields[5];
@@ -114,13 +120,21 @@ undef @files; # don't need it anymore
 
 # check that the files are clean and up to date according to cvs
 my $dirty;
+foreach my $d (@dirs) {
+    if (-e $d) {
+	$dirty = 1;
+	warn "$d exists and is not a directory!\n";
+    }
+}
 foreach my $f (@afiles) {
     # This should return only one value
     my @status = grep(m/^File/,  safe_pipe_capture('cvs', '-q', 'status' ,$f));
     if (@status > 1) { warn 'Strange! cvs status returned more than one line?'};
-    unless ($status[0] =~ m/Status: Unknown$/) {
+    if (-d dirname $f and $status[0] !~ m/Status: Unknown$/
+	and $status[0] !~ m/^File: no file /) {
  	$dirty = 1;
 	warn "File $f is already known in your CVS checkout -- perhaps it has been added by another user. Or this may indicate that it exists on a different branch. If this is the case, use -f to force the merge.\n";
+	warn "Status was: $status\n";
     }
 }
 foreach my $f (@mfiles, @dfiles) {
@@ -146,6 +160,19 @@ ###       you MUST call cleanupcvs(@file
 ###
 
 
+print "Creating new directories\n";
+foreach my $d (@dirs) {
+    unless (mkdir $d) {
+        warn "Could not mkdir $d: $!";
+	$dirty = 1;
+    }
+    `cvs add $d`;
+    if ($?) {
+	$dirty = 1;
+	warn "Failed to cvs add directory $d -- you may need to do it manually";
+    }
+}
+
 print "'Patching' binary files\n";
 
 my @bfiles = grep(m/^Binary/, safe_pipe_capture('git-diff-tree', '-p', $parent, $commit));
Previous: Yann DirsonNext: Sven Verdoolaege
Message 5 of 6 in “Handful of cvsexportcommit patches”
  1. 0/3 Handful of cvsexportcommit patchesYann Dirson, May 27, 2006
  2. 1/3 Do not call 'cmp' with non-existant -q flag.Yann Dirson, May 27, 2006
  3. 2/3 Document current cvsps limitations.Yann Dirson, May 27, 2006
  4. Yann DirsonMay 27, 2006
  5. 3/3 Make cvsexportcommit create parent directories as needed.Yann Dirson, May 27, 2006
  6. git-cvsexportcommit.perl: fix typoSven Verdoolaege, Jun 17, 2006

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.