Merge branch 'master' into next
* master: Add git-quiltimport to .gitignore. cvsimport: introduce _fetchfile() method and used a 1M buffer to read() cvsimport: cleanup commit function cvsimport: use git-update-index --index-info git status: skip empty directories, and add -u to show all untracked files cvsimport: repack every kilo-commits. cvsimport: introduce -L<imit> option to workaround memory leaks
This commit is contained in:
commit
646881a156
1
.gitignore
vendored
1
.gitignore
vendored
@ -77,6 +77,7 @@ git-prune
|
|||||||
git-prune-packed
|
git-prune-packed
|
||||||
git-pull
|
git-pull
|
||||||
git-push
|
git-push
|
||||||
|
git-quiltimport
|
||||||
git-read-tree
|
git-read-tree
|
||||||
git-rebase
|
git-rebase
|
||||||
git-receive-pack
|
git-receive-pack
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# Copyright (c) 2005 Linus Torvalds
|
# Copyright (c) 2005 Linus Torvalds
|
||||||
# Copyright (c) 2006 Junio C Hamano
|
# Copyright (c) 2006 Junio C Hamano
|
||||||
|
|
||||||
USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>) [--amend] [-e] [--author <author>] [[-i | -o] <path>...]'
|
USAGE='[-a] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit>] [-u] [--amend] [-e] [--author <author>] [[-i | -o] <path>...]'
|
||||||
SUBDIRECTORY_OK=Yes
|
SUBDIRECTORY_OK=Yes
|
||||||
. git-sh-setup
|
. git-sh-setup
|
||||||
|
|
||||||
@ -134,13 +134,17 @@ run_status () {
|
|||||||
report "Changed but not updated" \
|
report "Changed but not updated" \
|
||||||
"use git-update-index to mark for commit"
|
"use git-update-index to mark for commit"
|
||||||
|
|
||||||
|
option=""
|
||||||
|
if test -z "$untracked_files"; then
|
||||||
|
option="--directory --no-empty-directory"
|
||||||
|
fi
|
||||||
if test -f "$GIT_DIR/info/exclude"
|
if test -f "$GIT_DIR/info/exclude"
|
||||||
then
|
then
|
||||||
git-ls-files -z --others --directory \
|
git-ls-files -z --others $option \
|
||||||
--exclude-from="$GIT_DIR/info/exclude" \
|
--exclude-from="$GIT_DIR/info/exclude" \
|
||||||
--exclude-per-directory=.gitignore
|
--exclude-per-directory=.gitignore
|
||||||
else
|
else
|
||||||
git-ls-files -z --others --directory \
|
git-ls-files -z --others $option \
|
||||||
--exclude-per-directory=.gitignore
|
--exclude-per-directory=.gitignore
|
||||||
fi |
|
fi |
|
||||||
perl -e '$/ = "\0";
|
perl -e '$/ = "\0";
|
||||||
@ -203,6 +207,7 @@ verbose=
|
|||||||
signoff=
|
signoff=
|
||||||
force_author=
|
force_author=
|
||||||
only_include_assumed=
|
only_include_assumed=
|
||||||
|
untracked_files=
|
||||||
while case "$#" in 0) break;; esac
|
while case "$#" in 0) break;; esac
|
||||||
do
|
do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -340,6 +345,12 @@ do
|
|||||||
verbose=t
|
verbose=t
|
||||||
shift
|
shift
|
||||||
;;
|
;;
|
||||||
|
-u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|--untracked|\
|
||||||
|
--untracked-|--untracked-f|--untracked-fi|--untracked-fil|--untracked-file|\
|
||||||
|
--untracked-files)
|
||||||
|
untracked_files=t
|
||||||
|
shift
|
||||||
|
;;
|
||||||
--)
|
--)
|
||||||
shift
|
shift
|
||||||
break
|
break
|
||||||
|
@ -23,13 +23,13 @@ use File::Basename qw(basename dirname);
|
|||||||
use Time::Local;
|
use Time::Local;
|
||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
use IO::Pipe;
|
use IO::Pipe;
|
||||||
use POSIX qw(strftime dup2);
|
use POSIX qw(strftime dup2 :errno_h);
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
|
||||||
$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);
|
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);
|
||||||
my (%conv_author_name, %conv_author_email);
|
my (%conv_author_name, %conv_author_email);
|
||||||
|
|
||||||
sub usage() {
|
sub usage() {
|
||||||
@ -85,7 +85,7 @@ sub write_author_info($) {
|
|||||||
close ($f);
|
close ($f);
|
||||||
}
|
}
|
||||||
|
|
||||||
getopts("hivmkuo:d:p:C:z:s:M:P:A:S:") or usage();
|
getopts("hivmkuo:d:p:C:z:s:M:P:A:S:L:") or usage();
|
||||||
usage if $opt_h;
|
usage if $opt_h;
|
||||||
|
|
||||||
@ARGV <= 1 or usage();
|
@ARGV <= 1 or usage();
|
||||||
@ -315,15 +315,7 @@ sub _line {
|
|||||||
chomp $cnt;
|
chomp $cnt;
|
||||||
die "Duh: Filesize $cnt" if $cnt !~ /^\d+$/;
|
die "Duh: Filesize $cnt" if $cnt !~ /^\d+$/;
|
||||||
$line="";
|
$line="";
|
||||||
$res=0;
|
$res = $self->_fetchfile($fh, $cnt);
|
||||||
while($cnt) {
|
|
||||||
my $buf;
|
|
||||||
my $num = $self->{'socketi'}->read($buf,$cnt);
|
|
||||||
die "Server: Filesize $cnt: $num: $!\n" if not defined $num or $num<=0;
|
|
||||||
print $fh $buf;
|
|
||||||
$res += $num;
|
|
||||||
$cnt -= $num;
|
|
||||||
}
|
|
||||||
} elsif($line =~ s/^ //) {
|
} elsif($line =~ s/^ //) {
|
||||||
print $fh $line;
|
print $fh $line;
|
||||||
$res += length($line);
|
$res += length($line);
|
||||||
@ -335,14 +327,7 @@ sub _line {
|
|||||||
chomp $cnt;
|
chomp $cnt;
|
||||||
die "Duh: Mbinary $cnt" if $cnt !~ /^\d+$/ or $cnt<1;
|
die "Duh: Mbinary $cnt" if $cnt !~ /^\d+$/ or $cnt<1;
|
||||||
$line="";
|
$line="";
|
||||||
while($cnt) {
|
$res += $self->_fetchfile($fh, $cnt);
|
||||||
my $buf;
|
|
||||||
my $num = $self->{'socketi'}->read($buf,$cnt);
|
|
||||||
die "S: Mbinary $cnt: $num: $!\n" if not defined $num or $num<=0;
|
|
||||||
print $fh $buf;
|
|
||||||
$res += $num;
|
|
||||||
$cnt -= $num;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
chomp $line;
|
chomp $line;
|
||||||
if($line eq "ok") {
|
if($line eq "ok") {
|
||||||
@ -384,6 +369,23 @@ sub file {
|
|||||||
|
|
||||||
return ($name, $res);
|
return ($name, $res);
|
||||||
}
|
}
|
||||||
|
sub _fetchfile {
|
||||||
|
my ($self, $fh, $cnt) = @_;
|
||||||
|
my $res;
|
||||||
|
my $bufsize = 1024 * 1024;
|
||||||
|
while($cnt) {
|
||||||
|
if ($bufsize > $cnt) {
|
||||||
|
$bufsize = $cnt;
|
||||||
|
}
|
||||||
|
my $buf;
|
||||||
|
my $num = $self->{'socketi'}->read($buf,$bufsize);
|
||||||
|
die "Server: Filesize $cnt: $num: $!\n" if not defined $num or $num<=0;
|
||||||
|
print $fh $buf;
|
||||||
|
$res += $num;
|
||||||
|
$cnt -= $num;
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
package main;
|
package main;
|
||||||
@ -429,21 +431,24 @@ sub getwd() {
|
|||||||
return $pwd;
|
return $pwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub is_sha1 {
|
||||||
sub get_headref($$) {
|
my $s = shift;
|
||||||
my $name = shift;
|
return $s =~ /^[a-f0-9]{40}$/;
|
||||||
my $git_dir = shift;
|
|
||||||
my $sha;
|
|
||||||
|
|
||||||
if (open(C,"$git_dir/refs/heads/$name")) {
|
|
||||||
chomp($sha = <C>);
|
|
||||||
close(C);
|
|
||||||
length($sha) == 40
|
|
||||||
or die "Cannot get head id for $name ($sha): $!\n";
|
|
||||||
}
|
|
||||||
return $sha;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_headref ($$) {
|
||||||
|
my $name = shift;
|
||||||
|
my $git_dir = shift;
|
||||||
|
|
||||||
|
my $f = "$git_dir/refs/heads/$name";
|
||||||
|
if(open(my $fh, $f)) {
|
||||||
|
chomp(my $r = <$fh>);
|
||||||
|
is_sha1($r) or die "Cannot get head id for $name ($r): $!";
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
die "unable to open $f: $!" unless $! == POSIX::ENOENT;
|
||||||
|
return undef;
|
||||||
|
}
|
||||||
|
|
||||||
-d $git_tree
|
-d $git_tree
|
||||||
or mkdir($git_tree,0777)
|
or mkdir($git_tree,0777)
|
||||||
@ -561,100 +566,67 @@ unless($pid) {
|
|||||||
|
|
||||||
my $state = 0;
|
my $state = 0;
|
||||||
|
|
||||||
|
sub update_index (\@\@) {
|
||||||
|
my $old = shift;
|
||||||
|
my $new = shift;
|
||||||
|
open(my $fh, '|-', qw(git-update-index -z --index-info))
|
||||||
|
or die "unable to open git-update-index: $!";
|
||||||
|
print $fh
|
||||||
|
(map { "0 0000000000000000000000000000000000000000\t$_\0" }
|
||||||
|
@$old),
|
||||||
|
(map { '100' . sprintf('%o', $_->[0]) . " $_->[1]\t$_->[2]\0" }
|
||||||
|
@$new)
|
||||||
|
or die "unable to write to git-update-index: $!";
|
||||||
|
close $fh
|
||||||
|
or die "unable to write to git-update-index: $!";
|
||||||
|
$? and die "git-update-index reported error: $?";
|
||||||
|
}
|
||||||
|
|
||||||
|
sub write_tree () {
|
||||||
|
open(my $fh, '-|', qw(git-write-tree))
|
||||||
|
or die "unable to open git-write-tree: $!";
|
||||||
|
chomp(my $tree = <$fh>);
|
||||||
|
is_sha1($tree)
|
||||||
|
or die "Cannot get tree id ($tree): $!";
|
||||||
|
close($fh)
|
||||||
|
or die "Error running git-write-tree: $?\n";
|
||||||
|
print "Tree ID $tree\n" if $opt_v;
|
||||||
|
return $tree;
|
||||||
|
}
|
||||||
|
|
||||||
my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
|
my($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
|
||||||
my(@old,@new,@skipped);
|
my(@old,@new,@skipped);
|
||||||
sub commit {
|
sub commit {
|
||||||
my $pid;
|
update_index(@old, @new);
|
||||||
while(@old) {
|
@old = @new = ();
|
||||||
my @o2;
|
my $tree = write_tree();
|
||||||
if(@old > 55) {
|
my $parent = get_headref($last_branch, $git_dir);
|
||||||
@o2 = splice(@old,0,50);
|
print "Parent ID " . ($parent ? $parent : "(empty)") . "\n" if $opt_v;
|
||||||
} else {
|
|
||||||
@o2 = @old;
|
my @commit_args;
|
||||||
@old = ();
|
push @commit_args, ("-p", $parent) if $parent;
|
||||||
|
|
||||||
|
# loose detection of merges
|
||||||
|
# based on the commit msg
|
||||||
|
foreach my $rx (@mergerx) {
|
||||||
|
next unless $logmsg =~ $rx && $1;
|
||||||
|
my $mparent = $1 eq 'HEAD' ? $opt_o : $1;
|
||||||
|
if(my $sha1 = get_headref($mparent, $git_dir)) {
|
||||||
|
push @commit_args, '-p', $mparent;
|
||||||
|
print "Merge parent branch: $mparent\n" if $opt_v;
|
||||||
}
|
}
|
||||||
system("git-update-index","--force-remove","--",@o2);
|
|
||||||
die "Cannot remove files: $?\n" if $?;
|
|
||||||
}
|
|
||||||
while(@new) {
|
|
||||||
my @n2;
|
|
||||||
if(@new > 12) {
|
|
||||||
@n2 = splice(@new,0,10);
|
|
||||||
} else {
|
|
||||||
@n2 = @new;
|
|
||||||
@new = ();
|
|
||||||
}
|
|
||||||
system("git-update-index","--add",
|
|
||||||
(map { ('--cacheinfo', @$_) } @n2));
|
|
||||||
die "Cannot add files: $?\n" if $?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$pid = open(C,"-|");
|
my $commit_date = strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date));
|
||||||
die "Cannot fork: $!" unless defined $pid;
|
my $pid = open2(my $commit_read, my $commit_write,
|
||||||
unless($pid) {
|
'env',
|
||||||
exec("git-write-tree");
|
"GIT_AUTHOR_NAME=$author_name",
|
||||||
die "Cannot exec git-write-tree: $!\n";
|
"GIT_AUTHOR_EMAIL=$author_email",
|
||||||
}
|
"GIT_AUTHOR_DATE=$commit_date",
|
||||||
chomp(my $tree = <C>);
|
"GIT_COMMITTER_NAME=$author_name",
|
||||||
length($tree) == 40
|
"GIT_COMMITTER_EMAIL=$author_email",
|
||||||
or die "Cannot get tree id ($tree): $!\n";
|
"GIT_COMMITTER_DATE=$commit_date",
|
||||||
close(C)
|
'git-commit-tree', $tree, @commit_args);
|
||||||
or die "Error running git-write-tree: $?\n";
|
|
||||||
print "Tree ID $tree\n" if $opt_v;
|
|
||||||
|
|
||||||
my $parent = "";
|
|
||||||
if(open(C,"$git_dir/refs/heads/$last_branch")) {
|
|
||||||
chomp($parent = <C>);
|
|
||||||
close(C);
|
|
||||||
length($parent) == 40
|
|
||||||
or die "Cannot get parent id ($parent): $!\n";
|
|
||||||
print "Parent ID $parent\n" if $opt_v;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $pr = IO::Pipe->new() or die "Cannot open pipe: $!\n";
|
|
||||||
my $pw = IO::Pipe->new() or die "Cannot open pipe: $!\n";
|
|
||||||
$pid = fork();
|
|
||||||
die "Fork: $!\n" unless defined $pid;
|
|
||||||
unless($pid) {
|
|
||||||
$pr->writer();
|
|
||||||
$pw->reader();
|
|
||||||
open(OUT,">&STDOUT");
|
|
||||||
dup2($pw->fileno(),0);
|
|
||||||
dup2($pr->fileno(),1);
|
|
||||||
$pr->close();
|
|
||||||
$pw->close();
|
|
||||||
|
|
||||||
my @par = ();
|
|
||||||
@par = ("-p",$parent) if $parent;
|
|
||||||
|
|
||||||
# loose detection of merges
|
|
||||||
# based on the commit msg
|
|
||||||
foreach my $rx (@mergerx) {
|
|
||||||
if ($logmsg =~ $rx) {
|
|
||||||
my $mparent = $1;
|
|
||||||
if ($mparent eq 'HEAD') { $mparent = $opt_o };
|
|
||||||
if ( -e "$git_dir/refs/heads/$mparent") {
|
|
||||||
$mparent = get_headref($mparent, $git_dir);
|
|
||||||
push @par, '-p', $mparent;
|
|
||||||
print OUT "Merge parent branch: $mparent\n" if $opt_v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exec("env",
|
|
||||||
"GIT_AUTHOR_NAME=$author_name",
|
|
||||||
"GIT_AUTHOR_EMAIL=$author_email",
|
|
||||||
"GIT_AUTHOR_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
|
|
||||||
"GIT_COMMITTER_NAME=$author_name",
|
|
||||||
"GIT_COMMITTER_EMAIL=$author_email",
|
|
||||||
"GIT_COMMITTER_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
|
|
||||||
"git-commit-tree", $tree,@par);
|
|
||||||
die "Cannot exec git-commit-tree: $!\n";
|
|
||||||
|
|
||||||
close OUT;
|
|
||||||
}
|
|
||||||
$pw->writer();
|
|
||||||
$pr->reader();
|
|
||||||
|
|
||||||
# compatibility with git2cvs
|
# compatibility with git2cvs
|
||||||
substr($logmsg,32767) = "" if length($logmsg) > 32767;
|
substr($logmsg,32767) = "" if length($logmsg) > 32767;
|
||||||
@ -666,16 +638,14 @@ sub commit {
|
|||||||
@skipped = ();
|
@skipped = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
print $pw "$logmsg\n"
|
print($commit_write "$logmsg\n") && close($commit_write)
|
||||||
or die "Error writing to git-commit-tree: $!\n";
|
or die "Error writing to git-commit-tree: $!\n";
|
||||||
$pw->close();
|
|
||||||
|
|
||||||
print "Committed patch $patchset ($branch ".strftime("%Y-%m-%d %H:%M:%S",gmtime($date)).")\n" if $opt_v;
|
print "Committed patch $patchset ($branch $commit_date)\n" if $opt_v;
|
||||||
chomp(my $cid = <$pr>);
|
chomp(my $cid = <$commit_read>);
|
||||||
length($cid) == 40
|
is_sha1($cid) or die "Cannot get commit id ($cid): $!\n";
|
||||||
or die "Cannot get commit id ($cid): $!\n";
|
|
||||||
print "Commit ID $cid\n" if $opt_v;
|
print "Commit ID $cid\n" if $opt_v;
|
||||||
$pr->close();
|
close($commit_read);
|
||||||
|
|
||||||
waitpid($pid,0);
|
waitpid($pid,0);
|
||||||
die "Error running git-commit-tree: $?\n" if $?;
|
die "Error running git-commit-tree: $?\n" if $?;
|
||||||
@ -719,6 +689,7 @@ sub commit {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
my $commitcount = 1;
|
||||||
while(<CVS>) {
|
while(<CVS>) {
|
||||||
chomp;
|
chomp;
|
||||||
if($state == 0 and /^-+$/) {
|
if($state == 0 and /^-+$/) {
|
||||||
@ -852,7 +823,14 @@ while(<CVS>) {
|
|||||||
} elsif($state == 9 and /^\s*$/) {
|
} elsif($state == 9 and /^\s*$/) {
|
||||||
$state = 10;
|
$state = 10;
|
||||||
} elsif(($state == 9 or $state == 10) and /^-+$/) {
|
} elsif(($state == 9 or $state == 10) and /^-+$/) {
|
||||||
|
$commitcount++;
|
||||||
|
if ($opt_L && $commitcount > $opt_L) {
|
||||||
|
last;
|
||||||
|
}
|
||||||
commit();
|
commit();
|
||||||
|
if (($commitcount & 1023) == 0) {
|
||||||
|
system("git repack -a -d");
|
||||||
|
}
|
||||||
$state = 1;
|
$state = 1;
|
||||||
} elsif($state == 11 and /^-+$/) {
|
} elsif($state == 11 and /^-+$/) {
|
||||||
$state = 1;
|
$state = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user