Merge with master changes.

This commit is contained in:
Junio C Hamano 2005-08-16 12:13:16 -07:00
commit 1f40c7c24d
7 changed files with 182 additions and 73 deletions

View File

@ -11,7 +11,7 @@ SYNOPSIS
--------
'git-cvsimport-script' [ -o <branch-for-HEAD> ] [ -h ] [ -v ]
[ -d <CVSROOT> ] [ -p <options-for-cvsps> ]
[ -C <GIT_repository> ] [ -i ] [ <CVS_module> ]
[ -C <GIT_repository> ] [ -i ] [ -k ] [ <CVS_module> ]
DESCRIPTION
@ -29,11 +29,20 @@ OPTIONS
currently, only the :local:, :ext: and :pserver: access methods
are supported.
-C <target-dir>::
The GIT repository to import to. If the directory doesn't
exist, it will be created. Default is the current directory.
-i::
Import-only: don't perform a checkout after importing. This option
ensures the working directory and cache remain untouched and will
not create them if they do not exist.
-k::
Kill keywords: will extract files with -kk from the CVS archive
to avoid noisy changesets. Highly recommended, but off by default
to preserve compatibility with early imported trees.
-o <branch-for-HEAD>::
The 'HEAD' branch from CVS is imported to the 'origin' branch within
the git repository, as 'HEAD' already has a special meaning for git.
@ -44,7 +53,7 @@ OPTIONS
-p <options-for-cvsps>::
Additional options for cvsps.
The options '-x' and '-A' are implicit and should not be used here.
The options '-u' and '-A' are implicit and should not be used here.
If you need to pass multiple options, separate them with a comma.
@ -57,6 +66,9 @@ OPTIONS
-h::
Print a short usage message and exit.
-z <fuzz>::
Pass the timestamp fuzz factor to cvsps.
OUTPUT
------
If '-v' is specified, the script reports what it is doing.

View File

@ -319,6 +319,8 @@ extern int get_ack(int fd, unsigned char *result_sha1);
extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match);
extern struct packed_git *parse_pack_index(unsigned char *sha1);
extern struct packed_git *parse_pack_index_file(unsigned char *sha1,
char *idx_path);
extern void prepare_packed_git(void);
extern void install_packed_git(struct packed_git *pack);

View File

@ -28,19 +28,19 @@ use POSIX qw(strftime dup2);
$SIG{'PIPE'}="IGNORE";
$ENV{'TZ'}="UTC";
our($opt_h,$opt_o,$opt_v,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i);
our($opt_h,$opt_o,$opt_v,$opt_k,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i);
sub usage() {
print STDERR <<END;
Usage: ${\basename $0} # fetch/update GIT from CVS
[ -o branch-for-HEAD ] [ -h ] [ -v ] [ -d CVSROOT ]
[ -p opts-for-cvsps ] [ -C GIT_repository ] [ -z fuzz ]
[ -i ] [ CVS_module ]
[ -i ] [ -k ] [ CVS_module ]
END
exit(1);
}
getopts("hivo:d:p:C:z:") or usage();
getopts("hivko:d:p:C:z:") or usage();
usage if $opt_h;
@ARGV <= 1 or usage();
@ -190,7 +190,7 @@ sub conn {
$self->{'socketo'}->write("Root $repo\n");
# Trial and error says that this probably is the minimum set
$self->{'socketo'}->write("Valid-responses ok error Valid-requests Mode M Mbinary E F Checked-in Created Updated Merged Removed\n");
$self->{'socketo'}->write("Valid-responses ok error Valid-requests Mode M Mbinary E Checked-in Created Updated Merged Removed\n");
$self->{'socketo'}->write("valid-requests\n");
$self->{'socketo'}->flush();
@ -218,8 +218,10 @@ sub _file {
my($self,$fn,$rev) = @_;
$self->{'socketo'}->write("Argument -N\n") or return undef;
$self->{'socketo'}->write("Argument -P\n") or return undef;
# $self->{'socketo'}->write("Argument -ko\n") or return undef;
# -ko: Linus' version doesn't use it
# -kk: Linus' version doesn't use it - defaults to off
if ($opt_k) {
$self->{'socketo'}->write("Argument -kk\n") or return undef;
}
$self->{'socketo'}->write("Argument -r\n") or return undef;
$self->{'socketo'}->write("Argument $rev\n") or return undef;
$self->{'socketo'}->write("Argument --\n") or return undef;
@ -294,6 +296,12 @@ sub _line {
return $res;
} elsif($line =~ s/^E //) {
# print STDERR "S: $line\n";
} elsif($line =~ /^Remove-entry /i) {
$line = $self->readline(); # filename
$line = $self->readline(); # OK
chomp $line;
die "Unknown: $line" if $line ne "ok";
return -1;
} else {
die "Unknown: $line\n";
}
@ -561,7 +569,7 @@ my $commit = sub {
or die "Error writing to git-commit-tree: $!\n";
$pw->close();
print "Committed patch $patchset ($branch)\n" if $opt_v;
print "Committed patch $patchset ($branch ".strftime("%Y-%m-%d %H:%M:%S",gmtime($date)).")\n" if $opt_v;
chomp(my $cid = <$pr>);
length($cid) == 40
or die "Cannot get commit id ($cid): $!\n";
@ -675,26 +683,32 @@ while(<CVS>) {
$state = 9;
} elsif($state == 8) {
$logmsg .= "$_\n";
} elsif($state == 9 and /^\s+(\S+):(INITIAL|\d+(?:\.\d+)+)->(\d+(?:\.\d+)+)\s*$/) {
} elsif($state == 9 and /^\s+(.+?):(INITIAL|\d+(?:\.\d+)+)->(\d+(?:\.\d+)+)\s*$/) {
# VERSION:1.96->1.96.2.1
my $init = ($2 eq "INITIAL");
my $fn = $1;
my $rev = $3;
$fn =~ s#^/+##;
my ($tmpname, $size) = $cvs->file($fn,$rev);
print "".($init ? "New" : "Update")." $fn: $size bytes.\n" if $opt_v;
open my $F, '-|', "git-hash-object -w $tmpname"
or die "Cannot create object: $!\n";
my $sha = <$F>;
chomp $sha;
close $F;
if($size == -1) {
push(@old,$fn);
print "Drop $fn\n" if $opt_v;
} else {
print "".($init ? "New" : "Update")." $fn: $size bytes\n" if $opt_v;
open my $F, '-|', "git-hash-object -w $tmpname"
or die "Cannot create object: $!\n";
my $sha = <$F>;
chomp $sha;
close $F;
my $mode = pmode($cvs->{'mode'});
push(@new,[$mode, $sha, $fn]); # may be resurrected!
}
unlink($tmpname);
my $mode = pmode($cvs->{'mode'});
push(@new,[$mode, $sha, $fn]); # may be resurrected!
} elsif($state == 9 and /^\s+(\S+):\d(?:\.\d+)+->(\d(?:\.\d+)+)\(DEAD\)\s*$/) {
} elsif($state == 9 and /^\s+(.+?):\d+(?:\.\d+)+->(\d+(?:\.\d+)+)\(DEAD\)\s*$/) {
my $fn = $1;
$fn =~ s#^/+##;
push(@old,$fn);
print "Delete $fn\n" if $opt_v;
} elsif($state == 9 and /^\s*$/) {
$state = 10;
} elsif(($state == 9 or $state == 10) and /^-+$/) {

View File

@ -6,7 +6,7 @@
. git-sh-setup-script || die "Not a git archive."
usage () {
echo >&2 "usage: $0"' [-n] [-o dir] [--mbox] [--check] [--sign] [-<diff options>...] upstream [ our-head ]
echo >&2 "usage: $0"' [-n] [-o dir] [--mbox] [--check] [--signoff] [-<diff options>...] upstream [ our-head ]
Prepare each commit with its patch since our-head forked from upstream,
one file per patch, for e-mail submission. Each output file is
@ -46,7 +46,7 @@ do
date=t author=t mbox=t ;;
-n|--n|--nu|--num|--numb|--numbe|--number|--numbere|--numbered)
numbered=t ;;
-s|--s|--si|--sig|--sign)
-s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
signoff=t ;;
-o=*|--o=*|--ou=*|--out=*|--outp=*|--outpu=*|--output=*|--output-=*|\
--output-d=*|--output-di=*|--output-dir=*|--output-dire=*|\
@ -179,9 +179,12 @@ Date: '"$ad"
test "$signoff" = "t" && {
offsigner=`git-var GIT_COMMITTER_IDENT | sed -e 's/>.*/>/'`
echo
echo "Signed-off-by: $offsigner"
echo
line="Signed-off-by: $offsigner"
grep -q "^$line\$" $commsg || {
echo
echo "$line"
echo
}
}
echo '---'

View File

@ -15,14 +15,124 @@ void prefetch(unsigned char *sha1)
{
}
int fetch(unsigned char *sha1)
static struct packed_git *packs = NULL;
void setup_index(unsigned char *sha1)
{
struct packed_git *new_pack;
char filename[PATH_MAX];
strcpy(filename, path);
strcat(filename, "/objects/pack/pack-");
strcat(filename, sha1_to_hex(sha1));
strcat(filename, ".idx");
new_pack = parse_pack_index_file(sha1, filename);
new_pack->next = packs;
packs = new_pack;
}
int setup_indices()
{
DIR *dir;
struct dirent *de;
char filename[PATH_MAX];
unsigned char sha1[20];
sprintf(filename, "%s/objects/pack/", path);
dir = opendir(filename);
while ((de = readdir(dir)) != NULL) {
int namelen = strlen(de->d_name);
if (namelen != 50 ||
strcmp(de->d_name + namelen - 5, ".pack"))
continue;
get_sha1_hex(de->d_name + 5, sha1);
setup_index(sha1);
}
return 0;
}
int copy_file(const char *source, const char *dest, const char *hex)
{
if (use_link) {
if (!link(source, dest)) {
pull_say("link %s\n", hex);
return 0;
}
/* If we got ENOENT there is no point continuing. */
if (errno == ENOENT) {
fprintf(stderr, "does not exist %s\n", source);
return -1;
}
}
if (use_symlink && !symlink(source, dest)) {
pull_say("symlink %s\n", hex);
return 0;
}
if (use_filecopy) {
int ifd, ofd, status;
struct stat st;
void *map;
ifd = open(source, O_RDONLY);
if (ifd < 0 || fstat(ifd, &st) < 0) {
close(ifd);
fprintf(stderr, "cannot open %s\n", source);
return -1;
}
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, ifd, 0);
close(ifd);
if (map == MAP_FAILED) {
fprintf(stderr, "cannot mmap %s\n", source);
return -1;
}
ofd = open(dest, O_WRONLY | O_CREAT | O_EXCL, 0666);
status = ((ofd < 0) ||
(write(ofd, map, st.st_size) != st.st_size));
munmap(map, st.st_size);
close(ofd);
if (status)
fprintf(stderr, "cannot write %s\n", dest);
else
pull_say("copy %s\n", hex);
return status;
}
fprintf(stderr, "failed to copy %s with given copy methods.\n", hex);
return -1;
}
int fetch_pack(unsigned char *sha1)
{
struct packed_git *target;
char filename[PATH_MAX];
if (setup_indices())
return -1;
target = find_sha1_pack(sha1, packs);
if (!target)
return error("Couldn't find %s: not separate or in any pack",
sha1_to_hex(sha1));
if (get_verbosely) {
fprintf(stderr, "Getting pack %s\n",
sha1_to_hex(target->sha1));
fprintf(stderr, " which contains %s\n",
sha1_to_hex(sha1));
}
sprintf(filename, "%s/objects/pack/pack-%s.pack",
path, sha1_to_hex(target->sha1));
copy_file(filename, sha1_pack_name(target->sha1),
sha1_to_hex(target->sha1));
sprintf(filename, "%s/objects/pack/pack-%s.idx",
path, sha1_to_hex(target->sha1));
copy_file(filename, sha1_pack_index_name(target->sha1),
sha1_to_hex(target->sha1));
install_packed_git(target);
return 0;
}
int fetch_file(unsigned char *sha1)
{
static int object_name_start = -1;
static char filename[PATH_MAX];
char *hex = sha1_to_hex(sha1);
const char *dest_filename = sha1_file_name(sha1);
if (object_name_start < 0) {
if (object_name_start < 0) {
strcpy(filename, path); /* e.g. git.git */
strcat(filename, "/objects/");
object_name_start = strlen(filename);
@ -31,50 +141,12 @@ int fetch(unsigned char *sha1)
filename[object_name_start+1] = hex[1];
filename[object_name_start+2] = '/';
strcpy(filename + object_name_start + 3, hex + 2);
if (use_link) {
if (!link(filename, dest_filename)) {
pull_say("link %s\n", hex);
return 0;
}
/* If we got ENOENT there is no point continuing. */
if (errno == ENOENT) {
fprintf(stderr, "does not exist %s\n", filename);
return -1;
}
}
if (use_symlink && !symlink(filename, dest_filename)) {
pull_say("symlink %s\n", hex);
return 0;
}
if (use_filecopy) {
int ifd, ofd, status;
struct stat st;
void *map;
ifd = open(filename, O_RDONLY);
if (ifd < 0 || fstat(ifd, &st) < 0) {
close(ifd);
fprintf(stderr, "cannot open %s\n", filename);
return -1;
}
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, ifd, 0);
close(ifd);
if (map == MAP_FAILED) {
fprintf(stderr, "cannot mmap %s\n", filename);
return -1;
}
ofd = open(dest_filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
status = ((ofd < 0) ||
(write(ofd, map, st.st_size) != st.st_size));
munmap(map, st.st_size);
close(ofd);
if (status)
fprintf(stderr, "cannot write %s\n", dest_filename);
else
pull_say("copy %s\n", hex);
return status;
}
fprintf(stderr, "failed to copy %s with given copy methods.\n", hex);
return -1;
return copy_file(filename, dest_filename, hex);
}
int fetch(unsigned char *sha1)
{
return fetch_file(sha1) && fetch_pack(sha1);
}
int fetch_ref(char *ref, unsigned char *sha1)

View File

@ -475,13 +475,19 @@ struct packed_git *add_packed_git(char *path, int path_len)
}
struct packed_git *parse_pack_index(unsigned char *sha1)
{
char *path = sha1_pack_index_name(sha1);
return parse_pack_index_file(sha1, path);
}
struct packed_git *parse_pack_index_file(unsigned char *sha1, char *idx_path)
{
struct packed_git *p;
unsigned long idx_size;
void *idx_map;
char *path = sha1_pack_index_name(sha1);
char *path;
if (check_packed_git_idx(path, &idx_size, &idx_map))
if (check_packed_git_idx(idx_path, &idx_size, &idx_map))
return NULL;
path = sha1_pack_name(sha1);

View File

@ -18,7 +18,7 @@ git-%: %.c
all: $(PROGRAMS)
install: $(PROGRAMS) $(SCRIPTS)
$(INSTALL) -m755 -d $(dest)$(bindir)
$(INSTALL) -m755 -d $(DESTDIR)$(bindir)
$(INSTALL) $(PROGRAMS) $(SCRIPTS) $(DESTDIR)$(bindir)
clean: