diff options
-rw-r--r-- | Documentation/git-rev-list.txt | 5 | ||||
-rwxr-xr-x | GIT-VERSION-GEN | 10 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | builtin-grep.c | 35 | ||||
-rw-r--r-- | builtin-log.c | 2 | ||||
-rw-r--r-- | builtin-mv.c | 3 | ||||
-rw-r--r-- | builtin-tar-tree.c | 6 | ||||
-rwxr-xr-x | git-annotate.perl | 128 | ||||
-rwxr-xr-x | git-clone.sh | 2 | ||||
-rw-r--r-- | git-compat-util.h | 3 | ||||
-rw-r--r-- | git.c | 2 | ||||
-rw-r--r-- | http-fetch.c | 1 | ||||
-rw-r--r-- | local-fetch.c | 1 | ||||
-rw-r--r-- | log-tree.c | 2 | ||||
-rw-r--r-- | setup.c | 2 | ||||
-rw-r--r-- | ssh-fetch.c | 1 | ||||
-rwxr-xr-x | t/t7002-grep.sh | 85 |
17 files changed, 264 insertions, 26 deletions
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt index f60eacd93..dd9fff16d 100644 --- a/Documentation/git-rev-list.txt +++ b/Documentation/git-rev-list.txt @@ -22,6 +22,7 @@ SYNOPSIS [ [\--objects | \--objects-edge] [ \--unpacked ] ] [ \--pretty | \--header ] [ \--bisect ] + [ \--merge ] <commit>... [ \-- <paths>... ] DESCRIPTION @@ -123,6 +124,10 @@ OPTIONS topological order (i.e. descendant commits are shown before their parents). +--merge:: + After a failed merge, show refs that touch files having a + conflict and don't exist on all heads to merge. + Author ------ Written by Linus Torvalds <torvalds@osdl.org> diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 1ce217dd7..14923c973 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -3,9 +3,17 @@ GVF=GIT-VERSION-FILE DEF_VER=v1.4.2.GIT +LF=' +' + # First try git-describe, then see if there is a version file # (included in release tarballs), then default -if VN=$(git describe --abbrev=4 HEAD 2>/dev/null); then +if VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && + case "$VN" in + *$LF*) (exit 1) ;; + v[0-9]*) : happy ;; + esac +then VN=$(echo "$VN" | sed -e 's/-/./g'); elif test -f version then @@ -334,9 +334,9 @@ ifeq ($(uname_O),Cygwin) NO_D_TYPE_IN_DIRENT = YesPlease NO_D_INO_IN_DIRENT = YesPlease NO_STRCASESTR = YesPlease - NO_STRLCPY = YesPlease NO_SYMLINK_HEAD = YesPlease NEEDS_LIBICONV = YesPlease + NO_C99_FORMAT = YesPlease # There are conflicting reports about this. # On some boxes NO_MMAP is needed, and not so elsewhere. # Try uncommenting this if you see things break -- YMMV. diff --git a/builtin-grep.c b/builtin-grep.c index 69b7c4862..93b7e07b3 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -410,8 +410,10 @@ static int fixmatch(const char *pattern, char *line, regmatch_t *match) static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol, char *eol) { int hit = 0; + int at_true_bol = 1; regmatch_t pmatch[10]; + again: if (!opt->fixed) { regex_t *exp = &p->regexp; hit = !regexec(exp, bol, ARRAY_SIZE(pmatch), @@ -422,22 +424,35 @@ static int match_one_pattern(struct grep_opt *opt, struct grep_pat *p, char *bol } if (hit && opt->word_regexp) { - /* Match beginning must be either - * beginning of the line, or at word - * boundary (i.e. the last char must - * not be alnum or underscore). - */ if ((pmatch[0].rm_so < 0) || (eol - bol) <= pmatch[0].rm_so || (pmatch[0].rm_eo < 0) || (eol - bol) < pmatch[0].rm_eo) die("regexp returned nonsense"); - if (pmatch[0].rm_so != 0 && - word_char(bol[pmatch[0].rm_so-1])) - hit = 0; - if (pmatch[0].rm_eo != (eol-bol) && - word_char(bol[pmatch[0].rm_eo])) + + /* Match beginning must be either beginning of the + * line, or at word boundary (i.e. the last char must + * not be a word char). Similarly, match end must be + * either end of the line, or at word boundary + * (i.e. the next char must not be a word char). + */ + if ( ((pmatch[0].rm_so == 0 && at_true_bol) || + !word_char(bol[pmatch[0].rm_so-1])) && + ((pmatch[0].rm_eo == (eol-bol)) || + !word_char(bol[pmatch[0].rm_eo])) ) + ; + else hit = 0; + + if (!hit && pmatch[0].rm_so + bol + 1 < eol) { + /* There could be more than one match on the + * line, and the first match might not be + * strict word match. But later ones could be! + */ + bol = pmatch[0].rm_so + bol + 1; + at_true_bol = 0; + goto again; + } } return hit; } diff --git a/builtin-log.c b/builtin-log.c index bba1496bf..691cf3aef 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -257,6 +257,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) char message_id[1024]; char ref_message_id[1024]; + setup_ident(); git_config(git_format_config); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; @@ -306,7 +307,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) !strcmp(argv[i], "-s")) { const char *committer; const char *endpos; - setup_ident(); committer = git_committer_info(1); endpos = strchr(committer, '>'); if (!endpos) diff --git a/builtin-mv.c b/builtin-mv.c index e47942c13..ce8187c1e 100644 --- a/builtin-mv.c +++ b/builtin-mv.c @@ -48,7 +48,8 @@ static const char *add_slash(const char *path) if (path[len - 1] != '/') { char *with_slash = xmalloc(len + 2); memcpy(with_slash, path, len); - strcat(with_slash + len, "/"); + with_slash[len++] = '/'; + with_slash[len] = 0; return with_slash; } return path; diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index 7c48db9ec..215892b69 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -314,6 +314,7 @@ static int generate_tar(int argc, const char **argv, const char *prefix) struct commit *commit; struct tree_desc tree; struct strbuf current_path; + void *buffer; current_path.buf = xmalloc(PATH_MAX); current_path.alloc = PATH_MAX; @@ -341,8 +342,8 @@ static int generate_tar(int argc, const char **argv, const char *prefix) } else archive_time = time(NULL); - tree.buf = read_object_with_reference(sha1, tree_type, &tree.size, - tree_sha1); + tree.buf = buffer = read_object_with_reference(sha1, tree_type, + &tree.size, tree_sha1); if (!tree.buf) die("not a reference to a tag, commit or tree object: %s", sha1_to_hex(sha1)); @@ -351,6 +352,7 @@ static int generate_tar(int argc, const char **argv, const char *prefix) write_entry(tree_sha1, ¤t_path, 040777, NULL, 0); traverse_tree(&tree, ¤t_path); write_trailer(); + free(buffer); free(current_path.buf); return 0; } diff --git a/git-annotate.perl b/git-annotate.perl index 505b5ccb2..215ed26f3 100755 --- a/git-annotate.perl +++ b/git-annotate.perl @@ -147,7 +147,7 @@ sub init_claim { sub handle_rev { - my $i = 0; + my $revseen = 0; my %seen; while (my $rev = shift @revqueue) { next if $seen{$rev}++; @@ -247,22 +247,129 @@ sub git_find_parent { return $parent; } +sub git_find_all_parents { + my ($rev) = @_; + + my $revparent = open_pipe("git-rev-list","--remove-empty", "--parents","--max-count=1","$rev") + or die "Failed to open git-rev-list to find a single parent: $!"; + + my $parentline = <$revparent>; + chomp $parentline; + my ($origrev, @parents) = split m/\s+/, $parentline; + + close($revparent); + + return @parents; +} + +sub git_merge_base { + my ($rev1, $rev2) = @_; + + my $mb = open_pipe("git-merge-base", $rev1, $rev2) + or die "Failed to open git-merge-base: $!"; + + my $base = <$mb>; + chomp $base; + + close($mb); + + return $base; +} + +# Construct a set of pseudo parents that are in the same order, +# and the same quantity as the real parents, +# but whose SHA1s are as similar to the logical parents +# as possible. +sub get_pseudo_parents { + my ($all, $fake) = @_; + + my @all = @$all; + my @fake = @$fake; + + my @pseudo; + + my %fake = map {$_ => 1} @fake; + my %seenfake; + + my $fakeidx = 0; + foreach my $p (@all) { + if (exists $fake{$p}) { + if ($fake[$fakeidx] ne $p) { + die sprintf("parent mismatch: %s != %s\nall:%s\nfake:%s\n", + $fake[$fakeidx], $p, + join(", ", @all), + join(", ", @fake), + ); + } + + push @pseudo, $p; + $fakeidx++; + $seenfake{$p}++; + + } else { + my $base = git_merge_base($fake[$fakeidx], $p); + if ($base ne $fake[$fakeidx]) { + die sprintf("Result of merge-base doesn't match fake: %s,%s != %s\n", + $fake[$fakeidx], $p, $base); + } + + # The details of how we parse the diffs + # mean that we cannot have a duplicate + # revision in the list, so if we've already + # seen the revision we would normally add, just use + # the actual revision. + if ($seenfake{$base}) { + push @pseudo, $p; + } else { + push @pseudo, $base; + $seenfake{$base}++; + } + } + } + + return @pseudo; +} + # Get a diff between the current revision and a parent. # Record the commit information that results. sub git_diff_parse { my ($parents, $rev, %revinfo) = @_; + my @pseudo_parents; + my @command = ("git-diff-tree"); + my $revision_spec; + + if (scalar @$parents == 1) { + + $revision_spec = join("..", $parents->[0], $rev); + @pseudo_parents = @$parents; + } else { + my @all_parents = git_find_all_parents($rev); + + if (@all_parents != @$parents) { + @pseudo_parents = get_pseudo_parents(\@all_parents, $parents); + } else { + @pseudo_parents = @$parents; + } + + $revision_spec = $rev; + push @command, "-c"; + } + my @filenames = ( $revs{$rev}{'filename'} ); + foreach my $parent (@$parents) { push @filenames, $revs{$parent}{'filename'}; } - my $diff = open_pipe("git-diff-tree","-M","-p","-c",$rev,"--", - @filenames ) + push @command, "-p", "-M", $revision_spec, "--", @filenames; + + + my $diff = open_pipe( @command ) or die "Failed to call git-diff for annotation: $!"; - _git_diff_parse($diff, $parents, $rev, %revinfo); + _git_diff_parse($diff, \@pseudo_parents, $rev, %revinfo); close($diff); } @@ -283,6 +390,7 @@ sub _git_diff_parse { $diff_header_regexp .= "@" x @$parents; $diff_header_regexp .= ' -\d+,\d+' x @$parents; $diff_header_regexp .= ' \+(\d+),\d+'; + $diff_header_regexp .= " " . ("@" x @$parents); my %claim_regexps; my $allparentplus = '^' . '\\+' x @$parents . '(.*)$'; @@ -311,6 +419,7 @@ sub _git_diff_parse { DIFF: while(<$diff>) { chomp; + #printf("%d:%s:\n", $gotheader, $_); if (m/$diff_header_regexp/) { $remstart = $1 - 1; # (0-based arrays) @@ -391,10 +500,17 @@ sub _git_diff_parse { printf("parent %s is on line %d\n", $parent, $pi{$parent}); } + my @context; + for (my $i = -2; $i < 2; $i++) { + push @context, get_line($slines, $ri + $i); + } + my $context = join("\n", @context); + + my $justline = substr($_, scalar @$parents); die sprintf("Line %d, does not match:\n|%s|\n|%s|\n%s\n", $ri, - substr($_,scalar @$parents), - get_line($slines,$ri), $rev); + $justline, + $context); } foreach my $parent (@$parents) { $plines{$parent}[$pi{$parent}++] = $slines->[$ri]; diff --git a/git-clone.sh b/git-clone.sh index acc7a51b9..7060bdab0 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -298,7 +298,7 @@ yes,yes) fi git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1 ;; - http://*) + https://*|http://*) if test -z "@@NO_CURL@@" then clone_dumb_http "$repo" "$D" diff --git a/git-compat-util.h b/git-compat-util.h index 93f558056..3bcf5b13f 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -91,6 +91,9 @@ static inline void *xmalloc(size_t size) ret = malloc(1); if (!ret) die("Out of memory, malloc failed"); +#ifdef XMALLOC_POISON + memset(ret, 0xA5, size); +#endif return ret; } @@ -252,7 +252,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp) { "pack-objects", cmd_pack_objects, RUN_SETUP }, { "prune", cmd_prune, RUN_SETUP }, { "prune-packed", cmd_prune_packed, RUN_SETUP }, - { "push", cmd_push }, + { "push", cmd_push, RUN_SETUP }, { "read-tree", cmd_read_tree, RUN_SETUP }, { "repo-config", cmd_repo_config }, { "rev-list", cmd_rev_list, RUN_SETUP }, diff --git a/http-fetch.c b/http-fetch.c index 1aad39b4d..36af3e5b9 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -1226,6 +1226,7 @@ int main(int argc, const char **argv) int arg = 1; int rc = 0; + setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/local-fetch.c b/local-fetch.c index b216bdd55..4bf86fbbe 100644 --- a/local-fetch.c +++ b/local-fetch.c @@ -210,6 +210,7 @@ int main(int argc, const char **argv) char **commit_id; int arg = 1; + setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/log-tree.c b/log-tree.c index b67b8dd17..05ede0c17 100644 --- a/log-tree.c +++ b/log-tree.c @@ -59,7 +59,7 @@ void show_log(struct rev_info *opt, const char *sep) fputs(diff_unique_abbrev(commit->object.sha1, abbrev_commit), stdout); if (opt->parents) show_parents(commit, abbrev_commit); - putchar('\n'); + putchar(opt->diffopt.line_termination); return; } @@ -184,7 +184,7 @@ const char *setup_git_directory_gently(int *nongit_ok) } return NULL; bad_dir_environ: - if (!nongit_ok) { + if (nongit_ok) { *nongit_ok = 1; return NULL; } diff --git a/ssh-fetch.c b/ssh-fetch.c index 6e16568f8..c7d8fa80e 100644 --- a/ssh-fetch.c +++ b/ssh-fetch.c @@ -132,6 +132,7 @@ int main(int argc, char **argv) prog = getenv("GIT_SSH_PUSH"); if (!prog) prog = "git-ssh-upload"; + setup_ident(); setup_git_directory(); git_config(git_default_config); diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh new file mode 100755 index 000000000..00a7d762c --- /dev/null +++ b/t/t7002-grep.sh @@ -0,0 +1,85 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='git grep -w +' + +. ./test-lib.sh + +test_expect_success setup ' + { + echo foo mmap bar + echo foo_mmap bar + echo foo_mmap bar mmap + echo foo mmap bar_mmap + echo foo_mmap bar mmap baz + } >file && + echo x x xx x >x && + echo y yy >y && + echo zzz > z && + git add file x y z && + git commit -m initial +' + +for H in HEAD '' +do + case "$H" in + HEAD) HC='HEAD:' L='HEAD' ;; + '') HC= L='in working tree' ;; + esac + + test_expect_success "grep -w $L" ' + { + echo ${HC}file:1:foo mmap bar + echo ${HC}file:3:foo_mmap bar mmap + echo ${HC}file:4:foo mmap bar_mmap + echo ${HC}file:5:foo_mmap bar mmap baz + } >expected && + git grep -n -w -e mmap $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (x)" ' + { + echo ${HC}x:1:x x xx x + } >expected && + git grep -n -w -e "x xx* x" $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (y-1)" ' + { + echo ${HC}y:1:y yy + } >expected && + git grep -n -w -e "^y" $H >actual && + diff expected actual + ' + + test_expect_success "grep -w $L (y-2)" ' + : >expected && + if git grep -n -w -e "^y y" $H >actual + then + echo should not have matched + cat actual + false + else + diff expected actual + fi + ' + + test_expect_success "grep -w $L (z)" ' + : >expected && + if git grep -n -w -e "^z" $H >actual + then + echo should not have matched + cat actual + false + else + diff expected actual + fi + ' +done + +test_done |