diff --git a/builtin-apply.c b/builtin-apply.c index bdf44733a0..0bdcf63904 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -1783,8 +1783,6 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch) { const char *name = patch->old_name ? patch->old_name : patch->new_name; unsigned char sha1[20]; - unsigned char hdr[50]; - int hdrlen; /* For safety, we require patch index line to contain * full 40-byte textual SHA1 for old and new, at least for now. @@ -1800,8 +1798,7 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch) /* See if the old one matches what the patch * applies to. */ - write_sha1_file_prepare(desc->buffer, desc->size, - blob_type, sha1, hdr, &hdrlen); + hash_sha1_file(desc->buffer, desc->size, blob_type, sha1); if (strcmp(sha1_to_hex(sha1), patch->old_sha1_prefix)) return error("the patch applies to '%s' (%s), " "which does not match the " @@ -1846,8 +1843,7 @@ static int apply_binary(struct buffer_desc *desc, struct patch *patch) name); /* verify that the result matches */ - write_sha1_file_prepare(desc->buffer, desc->size, blob_type, - sha1, hdr, &hdrlen); + hash_sha1_file(desc->buffer, desc->size, blob_type, sha1); if (strcmp(sha1_to_hex(sha1), patch->new_sha1_prefix)) return error("binary patch to '%s' creates incorrect result (expecting %s, got %s)", name, patch->new_sha1_prefix, sha1_to_hex(sha1)); } diff --git a/cache-tree.c b/cache-tree.c index 323c68a670..d388848dd2 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -344,12 +344,8 @@ static int update_one(struct cache_tree *it, #endif } - if (dryrun) { - unsigned char hdr[200]; - int hdrlen; - write_sha1_file_prepare(buffer, offset, tree_type, it->sha1, - hdr, &hdrlen); - } + if (dryrun) + hash_sha1_file(buffer, offset, tree_type, it->sha1); else write_sha1_file(buffer, offset, tree_type, it->sha1); free(buffer); diff --git a/cache.h b/cache.h index 4e01a74160..a36052811b 100644 --- a/cache.h +++ b/cache.h @@ -246,13 +246,8 @@ char *enter_repo(char *path, int strict); extern int sha1_object_info(const unsigned char *, char *, unsigned long *); extern void * unpack_sha1_file(void *map, unsigned long mapsize, char *type, unsigned long *size); extern void * read_sha1_file(const unsigned char *sha1, char *type, unsigned long *size); +extern int hash_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *sha1); extern int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *return_sha1); -extern char *write_sha1_file_prepare(void *buf, - unsigned long len, - const char *type, - unsigned char *sha1, - unsigned char *hdr, - int *hdrlen); extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type); diff --git a/git-clone.sh b/git-clone.sh index 3998c55cef..bf54a11508 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -312,7 +312,7 @@ yes,yes) fi ;; *) - cd "$D" && case "$upload_pack" in + case "$upload_pack" in '') git-fetch-pack --all -k $quiet "$repo" ;; *) git-fetch-pack --all -k $quiet "$upload_pack" "$repo" ;; esac >"$GIT_DIR/CLONE_HEAD" || { diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 2130d57020..08ad831a39 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -275,7 +275,7 @@ sub req_Directory $state->{directory} = "" if ( $state->{directory} eq "." ); $state->{directory} .= "/" if ( $state->{directory} =~ /\S/ ); - if ( not defined($state->{prependdir}) and $state->{localdir} eq "." and $state->{path} =~ /\S/ ) + if ( (not defined($state->{prependdir}) or $state->{prependdir} eq '') and $state->{localdir} eq "." and $state->{path} =~ /\S/ ) { $log->info("Setting prepend to '$state->{path}'"); $state->{prependdir} = $state->{path}; @@ -805,7 +805,14 @@ sub req_update $meta = $updater->getmeta($filename); } - next unless ( $meta->{revision} ); + if ( ! defined $meta ) + { + $meta = { + name => $filename, + revision => 0, + filehash => 'added' + }; + } my $oldmeta = $meta; @@ -835,7 +842,7 @@ sub req_update and not exists ( $state->{opt}{C} ) ) { $log->info("Tell the client the file is modified"); - print "MT text U\n"; + print "MT text M \n"; print "MT fname $filename\n"; print "MT newline\n"; next; @@ -855,15 +862,36 @@ sub req_update } } elsif ( not defined ( $state->{entries}{$filename}{modified_hash} ) - or $state->{entries}{$filename}{modified_hash} eq $oldmeta->{filehash} ) + or $state->{entries}{$filename}{modified_hash} eq $oldmeta->{filehash} + or $meta->{filehash} eq 'added' ) { - $log->info("Updating '$filename'"); - # normal update, just send the new revision (either U=Update, or A=Add, or R=Remove) - print "MT +updated\n"; - print "MT text U\n"; - print "MT fname $filename\n"; - print "MT newline\n"; - print "MT -updated\n"; + # normal update, just send the new revision (either U=Update, + # or A=Add, or R=Remove) + if ( defined($wrev) && $wrev < 0 ) + { + $log->info("Tell the client the file is scheduled for removal"); + print "MT text R \n"; + print "MT fname $filename\n"; + print "MT newline\n"; + next; + } + elsif ( !defined($wrev) || $wrev == 0 ) + { + $log->info("Tell the client the file will be added"); + print "MT text A \n"; + print "MT fname $filename\n"; + print "MT newline\n"; + next; + + } + else { + $log->info("Updating '$filename' $wrev"); + print "MT +updated\n"; + print "MT text U \n"; + print "MT fname $filename\n"; + print "MT newline\n"; + print "MT -updated\n"; + } my ( $filepart, $dirpart ) = filenamesplit($filename,1); @@ -1709,6 +1737,17 @@ sub argsfromdir return if ( scalar ( @{$state->{args}} ) > 1 ); + my @gethead = @{$updater->gethead}; + + # push added files + foreach my $file (keys %{$state->{entries}}) { + if ( exists $state->{entries}{$file}{revision} && + $state->{entries}{$file}{revision} == 0 ) + { + push @gethead, { name => $file, filehash => 'added' }; + } + } + if ( scalar(@{$state->{args}}) == 1 ) { my $arg = $state->{args}[0]; @@ -1716,7 +1755,7 @@ sub argsfromdir $log->info("Only one arg specified, checking for directory expansion on '$arg'"); - foreach my $file ( @{$updater->gethead} ) + foreach my $file ( @gethead ) { next if ( $file->{filehash} eq "deleted" and not defined ( $state->{entries}{$file->{name}} ) ); next unless ( $file->{name} =~ /^$arg\// or $file->{name} eq $arg ); @@ -1729,7 +1768,7 @@ sub argsfromdir $state->{args} = []; - foreach my $file ( @{$updater->gethead} ) + foreach my $file ( @gethead ) { next if ( $file->{filehash} eq "deleted" and not defined ( $state->{entries}{$file->{name}} ) ); next unless ( $file->{name} =~ s/^$state->{prependdir}// ); diff --git a/git-svn.perl b/git-svn.perl index a128d90fc0..54d2356933 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -536,7 +536,7 @@ sub commit_lib { $SVN = libsvn_connect($repo); my $ed = SVN::Git::Editor->new( { r => $r_last, - ra => $SVN, + ra => $SVN_LOG, c => $c, svn_path => $SVN_PATH }, @@ -832,7 +832,7 @@ sub commit_diff { $SVN ||= libsvn_connect($repo); my @lock = $SVN::Core::VERSION ge '1.2.0' ? (undef, 0) : (); my $ed = SVN::Git::Editor->new({ r => $SVN->get_latest_revnum, - ra => $SVN, c => $tb, + ra => $SVN_LOG, c => $tb, svn_path => $SVN_PATH }, $SVN->get_commit_editor($_message, @@ -3354,9 +3354,11 @@ sub chg_file { seek $fh, 0, 0 or croak $!; my $exp = $md5->hexdigest; - my $atd = $self->apply_textdelta($fbat, undef, $self->{pool}); - my $got = SVN::TxDelta::send_stream($fh, @$atd, $self->{pool}); + my $pool = SVN::Pool->new; + my $atd = $self->apply_textdelta($fbat, undef, $pool); + my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool); die "Checksum mismatch\nexpected: $exp\ngot: $got\n" if ($got ne $exp); + $pool->clear; close $fh or croak $!; } diff --git a/merge-recursive.c b/merge-recursive.c index 611cd95cf5..2ba43ae84b 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1235,13 +1235,10 @@ int merge(struct commit *h1, if (merged_common_ancestors == NULL) { /* if there is no common ancestor, make an empty tree */ struct tree *tree = xcalloc(1, sizeof(struct tree)); - unsigned char hdr[40]; - int hdrlen; tree->object.parsed = 1; tree->object.type = OBJ_TREE; - write_sha1_file_prepare(NULL, 0, tree_type, tree->object.sha1, - hdr, &hdrlen); + hash_sha1_file(NULL, 0, tree_type, tree->object.sha1); merged_common_ancestors = make_virtual_commit(tree, "ancestor"); } diff --git a/sha1_file.c b/sha1_file.c index 18c2f88112..1a246f5f93 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1364,12 +1364,9 @@ void *read_object_with_reference(const unsigned char *sha1, } } -char *write_sha1_file_prepare(void *buf, - unsigned long len, - const char *type, - unsigned char *sha1, - unsigned char *hdr, - int *hdrlen) +static char *write_sha1_file_prepare(void *buf, unsigned long len, + const char *type, unsigned char *sha1, + unsigned char *hdr, int *hdrlen) { SHA_CTX c; @@ -1518,6 +1515,15 @@ static void setup_object_header(z_stream *stream, const char *type, unsigned lon stream->avail_out -= hdr; } +int hash_sha1_file(void *buf, unsigned long len, const char *type, + unsigned char *sha1) +{ + unsigned char hdr[50]; + int hdrlen; + write_sha1_file_prepare(buf, len, type, sha1, hdr, &hdrlen); + return 0; +} + int write_sha1_file(void *buf, unsigned long len, const char *type, unsigned char *returnsha1) { int size; @@ -1801,8 +1807,6 @@ int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object) unsigned long size = 4096; char *buf = xmalloc(size); int ret; - unsigned char hdr[50]; - int hdrlen; if (read_pipe(fd, &buf, &size)) { free(buf); @@ -1813,10 +1817,8 @@ int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object) type = blob_type; if (write_object) ret = write_sha1_file(buf, size, type, sha1); - else { - write_sha1_file_prepare(buf, size, type, sha1, hdr, &hdrlen); - ret = 0; - } + else + ret = hash_sha1_file(buf, size, type, sha1); free(buf); return ret; } @@ -1826,8 +1828,6 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, con unsigned long size = st->st_size; void *buf; int ret; - unsigned char hdr[50]; - int hdrlen; buf = ""; if (size) @@ -1840,10 +1840,8 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, con type = blob_type; if (write_object) ret = write_sha1_file(buf, size, type, sha1); - else { - write_sha1_file_prepare(buf, size, type, sha1, hdr, &hdrlen); - ret = 0; - } + else + ret = hash_sha1_file(buf, size, type, sha1); if (size) munmap(buf, size); return ret; @@ -1872,12 +1870,9 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write return error("readlink(\"%s\"): %s", path, errstr); } - if (!write_object) { - unsigned char hdr[50]; - int hdrlen; - write_sha1_file_prepare(target, st->st_size, blob_type, - sha1, hdr, &hdrlen); - } else if (write_sha1_file(target, st->st_size, blob_type, sha1)) + if (!write_object) + hash_sha1_file(target, st->st_size, blob_type, sha1); + else if (write_sha1_file(target, st->st_size, blob_type, sha1)) return error("%s: failed to insert into database", path); free(target); diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh index 0c6a363be9..041be04f5c 100755 --- a/t/t5600-clone-fail-cleanup.sh +++ b/t/t5600-clone-fail-cleanup.sh @@ -25,6 +25,12 @@ test_create_repo foo # clone doesn't like it if there is no HEAD. Is that a bug? (cd foo && touch file && git add file && git commit -m 'add file' >/dev/null 2>&1) +# source repository given to git-clone should be relative to the +# current path not to the target dir +test_expect_failure \ + 'clone of non-existent (relative to $PWD) source should fail' \ + 'git-clone ../foo baz' + test_expect_success \ 'clone should work now that source exists' \ 'git-clone foo bar' diff --git a/trace.c b/trace.c index f9efc918b8..495e5ed92a 100644 --- a/trace.c +++ b/trace.c @@ -55,7 +55,8 @@ static int get_trace_fd(int *need_close) { char *trace = getenv("GIT_TRACE"); - if (!trace || !strcmp(trace, "0") || !strcasecmp(trace, "false")) + if (!trace || !strcmp(trace, "") || + !strcmp(trace, "0") || !strcasecmp(trace, "false")) return 0; if (!strcmp(trace, "1") || !strcasecmp(trace, "true")) return STDERR_FILENO;