threads / patch / 9535

patchMake git-cvsexportcommit "status" each file in turn

Subject: [PATCH] Make git-cvsexportcommit "status" each file in turn

## tl;dr

5 messages between Aug 15, 2007 and Aug 15, 2007. Diffs are folded; open one to read it.

replies: 4people: 3as markdown or json

Alex Bennee· Aug 15, 2007, 13:27 UTC · lore
Hi,

It turns out CVS doesn't always give the status output in the order requested. According to my local CVS gurus this is a known CVS issue.

The attached patch just makes the script check each file in turn. It's slower but correct.

I also slightly formatted the warn output when it detects problems as multiple line wraps with long file paths where making my eyes bleed :-)

-- 
Alex, homepage: http://www.bennee.com/~alex/
Absence makes the heart go wander.
Peter Baumann· Aug 15, 2007, 14:04 UTC · re: Alex Bennee · lore

Re: [PATCH] Make git-cvsexportcommit "status" each file in turn

On Wed, Aug 15, 2007 at 02:27:28PM +0100, Alex Bennee wrote:
Show 11 quoted lines
> Hi,
> 
> It turns out CVS doesn't always give the status output in the order
> requested. According to my local CVS gurus this is a known CVS issue.
> 
> The attached patch just makes the script check each file in turn. It's
> slower but correct.
> 
> I also slightly formatted the warn output when it detects problems as
> multiple line wraps with long file paths where making my eyes bleed :-)
> 

I inlined the patch for easier commenting. Please inline further patches.

Show 39 quoted lines
> ---
>  git-cvsexportcommit.perl |   30 ++++++++++++++++++++----------
>  1 files changed, 20 insertions(+), 10 deletions(-)
> 
> diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
> index e9832d2..ee02c56 100755
> --- a/git-cvsexportcommit.perl
> +++ b/git-cvsexportcommit.perl
> @@ -182,15 +182,21 @@ if (@canstatusfiles) {
>        my @updated = safe_pipe_capture(@cvs, 'update', @canstatusfiles);
>        print @updated;
>      }
> -    my @cvsoutput;
> -    @cvsoutput= safe_pipe_capture(@cvs, 'status', @canstatusfiles);
> -    my $matchcount = 0;
> -    foreach my $l (@cvsoutput) {
> -        chomp $l;
> -        if ( $l =~ /^File:/ and  $l =~ /Status: (.*)$/ ) {
> -            $cvsstat{$canstatusfiles[$matchcount]} = $1;
> -            $matchcount++;
> -        }
> +
> +    # We can't status all the files at once as CVS doesn't gaurentee
> +    # that it will output the status bits in the order requested.
> +
> +    foreach my $f (@canstatusfiles)
> +    {
> +	my $cvscmd = join(' ', @cvs)." status $f";
> +	my $cvsoutput = `$cvscmd`;
> +
> +	# slurp out the status out of the result
> +	my ($status) = $cvsoutput =~ m/.*Status: (\S*)/;
> +
> +	$opt_v && print "Status of $f is $status\n";
> +
> +	$cvsstat{$f} = $status;
>      }
>  }
> 

This is extremly wastefull, because it will spawn a CVS process for each file. A better fix would be to parse the filename from the output of 'cvs status' and use that as input for $cvsstat.

(And/or you could use an hash instead of an array for 'cvsoutput', so you could double check that you only get the status for those files you asked for.)

Show 21 quoted lines
> 
>  
> @@ -198,10 +204,14 @@ if (@canstatusfiles) {
>  foreach my $f (@afiles) {
>      if (defined ($cvsstat{$f}) and $cvsstat{$f} ne "Unknown") {
>  	$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 "File $f is already known in your CVS checkout.\n"
> +	warn "  Perhaps it has been added by another user.\n"
> +	warn "  Or this may indicate that it exists on a different branch.\n"
> +	warn "  If this is the case, use -f to force the merge.\n";
>  	warn "Status was: $cvsstat{$f}\n";
>      }
>  }
> +
>  # ... validate known files.
>  foreach my $f (@files) {
>      next if grep { $_ eq $f } @afiles;
> -- 
> 1.5.2.3
> 
-Peter
Alex Bennee· Aug 15, 2007, 16:25 UTC · re: Peter Baumann · lore

Re: [PATCH] Make git-cvsexportcommit "status" each file in turn

On Wed, 2007-08-15 at 16:04 +0200, Peter Baumann wrote:
Show 8 quoted lines
> On Wed, Aug 15, 2007 at 02:27:28PM +0100, Alex Bennee wrote:
> > Hi,
> > 
> > It turns out CVS doesn't always give the status output in the order
> > requested. According to my local CVS gurus this is a known CVS issue.
> <snip>
> I inlined the patch for easier commenting. Please inline further
> patches.
Will do. I assumed Evolution would do something sensible. My mistake :-(
Show 14 quoted lines
> 
> > ---
> >  git-cvsexportcommit.perl |   30 ++++++++++++++++++++----------
> >  1 files changed, 20 insertions(+), 10 deletions(-)
> > 
> > diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
> <snip>
> This is extremly wastefull, because it will spawn a CVS process for each file.
> A better fix would be to parse the filename from the output of
> 'cvs status' and use that as input for $cvsstat.
> 
> (And/or you could use an hash instead of an array for 'cvsoutput', so
> you could double check that you only get the status for those files you
> asked for.)

I agree it's wasteful and could be done better however I'm no perl hacker so I just went for something that was correct and worked.

The path that is echoed later in the status output is however the CVS file path which may not be directly related to the actual path in your source tree. For example I have one status reported as:

$ cvs status src/proj_version
===================================================================
File: proj_version      Status: Up-to-date
   Working revision:    1.1.380.1
   Repository revision: 1.1.380.1       /export/cvsroot/project/src/Attic/proj_version,v
   Sticky Tag:          ATAG (branch: 1.1.380)
   Sticky Date:         (none)
   Sticky Options:      (none)
This makes the matching more than a little problematic.
It depends on how much people that use this script care about performance?

For my part it's a fire and forget script once I've finished my hacking in a git tree so I don't mind it taking some time. I'm not particularly minded to dig further in perl to make it faster unless there is a real clamour - or perhaps someone with a bigger itch and more perl foo can tackle it.

In the meantime it does fix a bug in the script so I would say it's applying.

-- 
Alex, homepage: http://www.bennee.com/~alex/
Blessed is he who has reached the point of no return and knows it, for
he shall enjoy living. -- W. C. Bennett
Robin Rosenberg· Aug 15, 2007, 19:40 UTC · re: Alex Bennee · lore

Re: [PATCH] Make git-cvsexportcommit "status" each file in turn

onsdag 15 augusti 2007 skrev Alex Bennee:
Show 20 quoted lines
> On Wed, 2007-08-15 at 16:04 +0200, Peter Baumann wrote:
> > On Wed, Aug 15, 2007 at 02:27:28PM +0100, Alex Bennee wrote:
> > > Hi,
> > > 
> > > It turns out CVS doesn't always give the status output in the order
> > > requested. According to my local CVS gurus this is a known CVS issue.
> > <snip>
> > I inlined the patch for easier commenting. Please inline further
> > patches.
> 
> Will do. I assumed Evolution would do something sensible. My mistake :-(
> 
> > 
> > > ---
> > >  git-cvsexportcommit.perl |   30 ++++++++++++++++++++----------
> > >  1 files changed, 20 insertions(+), 10 deletions(-)
> > > 
> > > diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
> > <snip>
> > This is extremly wastefull, because it will spawn a CVS process for each 
file.
Show 20 quoted lines
> > A better fix would be to parse the filename from the output of
> > 'cvs status' and use that as input for $cvsstat.
> > 
> > (And/or you could use an hash instead of an array for 'cvsoutput', so
> > you could double check that you only get the status for those files you
> > asked for.)
> 
> I agree it's wasteful and could be done better however I'm no perl
> hacker so I just went for something that was correct and worked. 
> 
> The path that is echoed later in the status output is however the CVS
> file path which may not be directly related to the actual path in your
> source tree. For example I have one status reported as:
> 
> $ cvs status src/proj_version
> ===================================================================
> File: proj_version      Status: Up-to-date
> 
>    Working revision:    1.1.380.1
>    Repository revision: 
1.1.380.1       /export/cvsroot/project/src/Attic/proj_version,v
Show 5 quoted lines
>    Sticky Tag:          ATAG (branch: 1.1.380)
>    Sticky Date:         (none)
>    Sticky Options:      (none)
> 
> This makes the matching more than a little problematic.

CVS/Root contains the first part of the path. Just use the one found at the top of the CVS checkout. Using CVS may be insane, but mixing different repos in the same checkout is absolute madness.

Then drop /Attic/ if present and the ,v at the end of the file name. Not rocket science I'd say.

> It depends on how much people that use this script care about performance?

We do although I rarely commit big patches so cvsexportcommit usually does it's job in seconds for me. I also use the -u option and don't do any work in the CVS checkout so performing status if just overhead for me. We might drop it completely with a switch.

Show 5 quoted lines
> For my part it's a fire and forget script once I've finished my hacking
> in a git tree so I don't mind it taking some time. I'm not particularly
> minded to dig further in perl to make it faster unless there is a real
> clamour - or perhaps someone with a bigger itch and more perl foo can
> tackle it. 
> 
> In the meantime it does fix a bug in the script so I would say it's
> applying.
> 
I suggest Junio wait a few days in case a real fix materializes.
-- robin
Alex Bennee· Aug 15, 2007, 15:47 UTC · re: Alex Bennee · lore

Re: [PATCH] Make git-cvsexportcommit "status" each file in turn

On Wed, 2007-08-15 at 14:27 +0100, Alex Bennee wrote:
> Hi,
> 
<snip>
> I also slightly formatted the warn output when it detects problems as
> multiple line wraps with long file paths where making my eyes bleed :-)
Which I seem to have missed a bunch of crucial ;'s from
Show changes to git-cvsexportcommit.perl +3 −3
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index ee02c56..65c12b2 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -204,9 +204,9 @@ if (@canstatusfiles) {
 foreach my $f (@afiles) {
     if (defined ($cvsstat{$f}) and $cvsstat{$f} ne "Unknown") {
        $dirty = 1;
-       warn "File $f is already known in your CVS checkout.\n"
-       warn "  Perhaps it has been added by another user.\n"
-       warn "  Or this may indicate that it exists on a different
branch.\n"
+       warn "File $f is already known in your CVS checkout.\n";
+       warn "  Perhaps it has been added by another user.\n";
+       warn "  Or this may indicate that it exists on a different
branch.\n";
        warn "  If this is the case, use -f to force the merge.\n";
        warn "Status was: $cvsstat{$f}\n";
     }
-- 
Alex, homepage: http://www.bennee.com/~alex/
Love may laugh at locksmiths, but he has a profound respect for money
bags. -- Sidney Paternoster, "The Folly of the Wise"

← back to recent threads