aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-rev-list.txt5
-rwxr-xr-xGIT-VERSION-GEN10
-rw-r--r--Makefile2
-rw-r--r--builtin-grep.c35
-rw-r--r--builtin-log.c2
-rw-r--r--builtin-mv.c3
-rw-r--r--builtin-tar-tree.c6
-rwxr-xr-xgit-annotate.perl128
-rwxr-xr-xgit-clone.sh2
-rw-r--r--git-compat-util.h3
-rw-r--r--git.c2
-rw-r--r--http-fetch.c1
-rw-r--r--local-fetch.c1
-rw-r--r--log-tree.c2
-rw-r--r--setup.c2
-rw-r--r--ssh-fetch.c1
-rwxr-xr-xt/t7002-grep.sh85
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
diff --git a/Makefile b/Makefile
index dc39f72f1..733fa660d 100644
--- a/Makefile
+++ b/Makefile
@@ -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, &current_path, 040777, NULL, 0);
traverse_tree(&tree, &current_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;
}
diff --git a/git.c b/git.c
index 96e596b1a..db0f86790 100644
--- a/git.c
+++ b/git.c
@@ -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;
}
diff --git a/setup.c b/setup.c
index 358e139d8..2afdba414 100644
--- a/setup.c
+++ b/setup.c
@@ -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