Merge branch 'aw/cvs'

* aw/cvs:
  cvsimport: add <remote>/HEAD reference in separate remotes more
  cvsimport: update documentation to include separate remotes option
  cvsimport: add support for new style remote layout
This commit is contained in:
Junio C Hamano 2007-06-12 21:04:52 -07:00
commit 9bfe9f80b1
2 changed files with 42 additions and 21 deletions

View file

@ -13,7 +13,7 @@ SYNOPSIS
[-A <author-conv-file>] [-p <options-for-cvsps>] [-P <file>] [-A <author-conv-file>] [-p <options-for-cvsps>] [-P <file>]
[-C <git_repository>] [-z <fuzz>] [-i] [-k] [-u] [-s <subst>] [-C <git_repository>] [-z <fuzz>] [-i] [-k] [-u] [-s <subst>]
[-a] [-m] [-M <regex>] [-S <regex>] [-L <commitlimit>] [-a] [-m] [-M <regex>] [-S <regex>] [-L <commitlimit>]
[<CVS_module>] [-r <remote>] [<CVS_module>]
DESCRIPTION DESCRIPTION
@ -25,10 +25,12 @@ Splitting the CVS log into patch sets is done by 'cvsps'.
At least version 2.1 is required. At least version 2.1 is required.
You should *never* do any work of your own on the branches that are You should *never* do any work of your own on the branches that are
created by git-cvsimport. The initial import will create and populate a created by git-cvsimport. By default initial import will create and populate a
"master" branch from the CVS repository's main branch which you're free "master" branch from the CVS repository's main branch which you're free
to work with; after that, you need to 'git merge' incremental imports, or to work with; after that, you need to 'git merge' incremental imports, or
any CVS branches, yourself. any CVS branches, yourself. It is advisable to specify a named remote via
-r to separate and protect the incoming branches.
OPTIONS OPTIONS
------- -------
@ -51,10 +53,19 @@ OPTIONS
The git repository to import to. If the directory doesn't The git repository to import to. If the directory doesn't
exist, it will be created. Default is the current directory. exist, it will be created. Default is the current directory.
-r <remote>::
The git remote to import this CVS repository into.
Moves all CVS branches into remotes/<remote>/<branch>
akin to the git-clone --use-separate-remote option.
-o <branch-for-HEAD>:: -o <branch-for-HEAD>::
The 'HEAD' branch from CVS is imported to the 'origin' branch within When no remote is specified (via -r) the 'HEAD' branch
the git repository, as 'HEAD' already has a special meaning for git. from CVS is imported to the 'origin' branch within the git
Use this option if you want to import into a different branch. repository, as 'HEAD' already has a special meaning for git.
When a remote is specified the 'HEAD' branch is named
remotes/<remote>/master mirroring git-clone behaviour.
Use this option if you want to import into a different
branch.
+ +
Use '-o master' for continuing an import that was initially done by Use '-o master' for continuing an import that was initially done by
the old cvs2git tool. the old cvs2git tool.

View file

@ -29,7 +29,7 @@
$SIG{'PIPE'}="IGNORE"; $SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC"; $ENV{'TZ'}="UTC";
our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L, $opt_a); our ($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, $opt_s,$opt_m,$opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r);
my (%conv_author_name, %conv_author_email); my (%conv_author_name, %conv_author_email);
sub usage(;$) { sub usage(;$) {
@ -40,7 +40,7 @@ (;$)
[-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file] [-o branch-for-HEAD] [-h] [-v] [-d CVSROOT] [-A author-conv-file]
[-p opts-for-cvsps] [-P file] [-C GIT_repository] [-z fuzz] [-i] [-k] [-p opts-for-cvsps] [-P file] [-C GIT_repository] [-z fuzz] [-i] [-k]
[-u] [-s subst] [-a] [-m] [-M regex] [-S regex] [-L commitlimit] [-u] [-s subst] [-a] [-m] [-M regex] [-S regex] [-L commitlimit]
[CVS_module] [-r remote] [CVS_module]
END END
exit(1); exit(1);
} }
@ -114,7 +114,7 @@ sub read_repo_config {
} }
} }
my $opts = "haivmkuo:d:p:C:z:s:M:P:A:S:L:"; my $opts = "haivmkuo:d:p:r:C:z:s:M:P:A:S:L:";
read_repo_config($opts); read_repo_config($opts);
getopts($opts) or usage(); getopts($opts) or usage();
usage if $opt_h; usage if $opt_h;
@ -134,13 +134,21 @@ sub read_repo_config {
} else { } else {
usage("CVSROOT needs to be set"); usage("CVSROOT needs to be set");
} }
$opt_o ||= "origin";
$opt_s ||= "-"; $opt_s ||= "-";
$opt_a ||= 0; $opt_a ||= 0;
my $git_tree = $opt_C; my $git_tree = $opt_C;
$git_tree ||= "."; $git_tree ||= ".";
my $remote;
if (defined $opt_r) {
$remote = 'refs/remotes/' . $opt_r;
$opt_o ||= "master";
} else {
$opt_o ||= "origin";
$remote = 'refs/heads';
}
my $cvs_tree; my $cvs_tree;
if ($#ARGV == 0) { if ($#ARGV == 0) {
$cvs_tree = $ARGV[0]; $cvs_tree = $ARGV[0];
@ -522,7 +530,7 @@ ($$)
my $name = shift; my $name = shift;
my $git_dir = shift; my $git_dir = shift;
my $f = "$git_dir/refs/heads/$name"; my $f = "$git_dir/$remote/$name";
if (open(my $fh, $f)) { if (open(my $fh, $f)) {
chomp(my $r = <$fh>); chomp(my $r = <$fh>);
is_sha1($r) or die "Cannot get head id for $name ($r): $!"; is_sha1($r) or die "Cannot get head id for $name ($r): $!";
@ -573,12 +581,12 @@ ($$)
# Get the last import timestamps # Get the last import timestamps
my $fmt = '($ref, $author) = (%(refname), %(author));'; my $fmt = '($ref, $author) = (%(refname), %(author));';
open(H, "git-for-each-ref --perl --format='$fmt' refs/heads |") or open(H, "git-for-each-ref --perl --format='$fmt' $remote |") or
die "Cannot run git-for-each-ref: $!\n"; die "Cannot run git-for-each-ref: $!\n";
while (defined(my $entry = <H>)) { while (defined(my $entry = <H>)) {
my ($ref, $author); my ($ref, $author);
eval($entry) || die "cannot eval refs list: $@"; eval($entry) || die "cannot eval refs list: $@";
my ($head) = ($ref =~ m|^refs/heads/(.*)|); my ($head) = ($ref =~ m|^$remote/(.*)|);
$author =~ /^.*\s(\d+)\s[-+]\d{4}$/; $author =~ /^.*\s(\d+)\s[-+]\d{4}$/;
$branch_date{$head} = $1; $branch_date{$head} = $1;
} }
@ -701,9 +709,9 @@ sub commit {
$index{$branch} = tmpnam(); $index{$branch} = tmpnam();
$ENV{GIT_INDEX_FILE} = $index{$branch}; $ENV{GIT_INDEX_FILE} = $index{$branch};
if ($ancestor) { if ($ancestor) {
system("git-read-tree", $ancestor); system("git-read-tree", "$remote/$ancestor");
} else { } else {
system("git-read-tree", $branch); system("git-read-tree", "$remote/$branch");
} }
die "read-tree failed: $?\n" if $?; die "read-tree failed: $?\n" if $?;
} }
@ -762,7 +770,7 @@ sub commit {
waitpid($pid,0); waitpid($pid,0);
die "Error running git-commit-tree: $?\n" if $?; die "Error running git-commit-tree: $?\n" if $?;
system("git-update-ref refs/heads/$branch $cid") == 0 system("git-update-ref $remote/$branch $cid") == 0
or die "Cannot write branch $branch for update: $!\n"; or die "Cannot write branch $branch for update: $!\n";
if ($tag) { if ($tag) {
@ -861,12 +869,12 @@ sub commit {
print STDERR "Branch $branch erroneously stems from itself -- changed ancestor to $opt_o\n"; print STDERR "Branch $branch erroneously stems from itself -- changed ancestor to $opt_o\n";
$ancestor = $opt_o; $ancestor = $opt_o;
} }
if (-f "$git_dir/refs/heads/$branch") { if (-f "$git_dir/$remote/$branch") {
print STDERR "Branch $branch already exists!\n"; print STDERR "Branch $branch already exists!\n";
$state=11; $state=11;
next; next;
} }
unless (open(H,"$git_dir/refs/heads/$ancestor")) { unless (open(H,"$git_dir/$remote/$ancestor")) {
print STDERR "Branch $ancestor does not exist!\n"; print STDERR "Branch $ancestor does not exist!\n";
$ignorebranch{$branch} = 1; $ignorebranch{$branch} = 1;
$state=11; $state=11;
@ -874,7 +882,7 @@ sub commit {
} }
chomp(my $id = <H>); chomp(my $id = <H>);
close(H); close(H);
unless (open(H,"> $git_dir/refs/heads/$branch")) { unless (open(H,"> $git_dir/$remote/$branch")) {
print STDERR "Could not create branch $branch: $!\n"; print STDERR "Could not create branch $branch: $!\n";
$ignorebranch{$branch} = 1; $ignorebranch{$branch} = 1;
$state=11; $state=11;
@ -988,14 +996,16 @@ sub commit {
die "Fast-forward update failed: $?\n" if $?; die "Fast-forward update failed: $?\n" if $?;
} }
else { else {
system(qw(git-merge cvsimport HEAD), "refs/heads/$opt_o"); system(qw(git-merge cvsimport HEAD), "$remote/$opt_o");
die "Could not merge $opt_o into the current branch.\n" if $?; die "Could not merge $opt_o into the current branch.\n" if $?;
} }
} else { } else {
$orig_branch = "master"; $orig_branch = "master";
print "DONE; creating $orig_branch branch\n" if $opt_v; print "DONE; creating $orig_branch branch\n" if $opt_v;
system("git-update-ref", "refs/heads/master", "refs/heads/$opt_o") system("git-update-ref", "refs/heads/master", "$remote/$opt_o")
unless -f "$git_dir/refs/heads/master"; unless -f "$git_dir/refs/heads/master";
system("git-symbolic-ref", "$remote/HEAD", "$remote/$opt_o")
if ($opt_r && $opt_o ne 'HEAD');
system('git-update-ref', 'HEAD', "$orig_branch"); system('git-update-ref', 'HEAD', "$orig_branch");
unless ($opt_i) { unless ($opt_i) {
system('git checkout'); system('git checkout');