From 99516e35d096f41e7133cacde8fbed8ee9a3ecd0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 8 Oct 2007 13:42:41 -0700 Subject: Fix embarrassing "git log --follow" bug It turns out that I completely broke "git log --follow" with my recent patch to revision.c ("Fix revision log diff setup, avoid unnecessary diff generation", commit b7bb760d5ed4881422673d32f869d140221d3564). Why? Because --follow obviously requires the diff machinery to function, exactly the same way pickaxe does. So everybody is away right now, but considering that nobody even noticed this bug, I don't think it matters. But for the record, here's the trivial one-liner fix (well, two, since I also fixed the comment). Because of the nature of the bug, if you ask for patches when following (which is one of the things I normally do), the bug is hidden, because then the request for diff output will automatically also enable the diffs themselves. So while "git log --follow " didn't work, adding a "-p" magically made it work again even without this fix. Signed-off-by: Linus Torvalds Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- revision.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/revision.c b/revision.c index 658471385c..48756b5d44 100644 --- a/revision.c +++ b/revision.c @@ -1256,8 +1256,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch if (revs->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) revs->diff = 1; - /* Pickaxe needs diffs */ - if (revs->diffopt.pickaxe) + /* Pickaxe and rename following needs diffs */ + if (revs->diffopt.pickaxe || revs->diffopt.follow_renames) revs->diff = 1; if (revs->topo_order) -- cgit v1.2.3 From 304b5af64f9b5a6b5e9455e2dcab381c568452b6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 9 Oct 2007 09:35:22 -0700 Subject: Clean up "git log" format with DIFF_FORMAT_NO_OUTPUT This fixes an unnecessary empty line that we add to the log message when we generate diffs, but don't actually end up printing any due to having DIFF_FORMAT_NO_OUTPUT set. This can happen with pickaxe or with rename following. The reason is that we normally add an empty line between the commit and the diff, but we do that even for the case where we've then suppressed the actual printing of the diff. This also updates a couple of tests that assumed the extraneous empty line would exist at the end of output. Signed-off-by: Linus Torvalds Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- log-tree.c | 3 ++- t/t3900-i18n-commit.sh | 2 +- t/t4013/diff.log_-SF_master | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/log-tree.c b/log-tree.c index a6423718e7..b509c0c7ec 100644 --- a/log-tree.c +++ b/log-tree.c @@ -321,7 +321,8 @@ int log_tree_diff_flush(struct rev_info *opt) * output for readability. */ show_log(opt, opt->diffopt.msg_sep); - if (opt->verbose_header && + if ((opt->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT) && + opt->verbose_header && opt->commit_format != CMIT_FMT_ONELINE) { int pch = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_PATCH; if ((pch & opt->diffopt.output_format) == pch) diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index fcbabe8ec3..94b1c24b0a 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -8,7 +8,7 @@ test_description='commit and log output encodings' . ./test-lib.sh compare_with () { - git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' -e '$d' >current && + git show -s $1 | sed -e '1,/^$/d' -e 's/^ //' >current && git diff current "$2" } diff --git a/t/t4013/diff.log_-SF_master b/t/t4013/diff.log_-SF_master index 6162ed2018..c1599f2f52 100644 --- a/t/t4013/diff.log_-SF_master +++ b/t/t4013/diff.log_-SF_master @@ -4,5 +4,4 @@ Author: A U Thor Date: Mon Jun 26 00:02:00 2006 +0000 Third - $ -- cgit v1.2.3 From a72c874e43e89a879fc4a8998ecd6e5a56667929 Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Fri, 5 Oct 2007 22:16:44 +0200 Subject: git-config: don't silently ignore options after --list Error out if someone gives options after --list since that is not a valid syntax. Signed-off-by: Frank Lichtenheld Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- builtin-config.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/builtin-config.c b/builtin-config.c index 0a605e01ac..cb7e9e9391 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -172,8 +172,11 @@ int cmd_config(int argc, const char **argv, const char *prefix) type = T_INT; else if (!strcmp(argv[1], "--bool")) type = T_BOOL; - else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) + else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l")) { + if (argc != 2) + usage(git_config_set_usage); return git_config(show_all_config); + } else if (!strcmp(argv[1], "--global")) { char *home = getenv("HOME"); if (home) { -- cgit v1.2.3 From 7288ed8ebdab54e5aa05400bd840e1348ffdc270 Mon Sep 17 00:00:00 2001 From: Jean-Luc Herren Date: Tue, 9 Oct 2007 21:29:26 +0200 Subject: git add -i: Fix parsing of abbreviated hunk headers The unified diff format allows one-line ranges to be abbreviated by omiting the size. The hunk header "@@ -10,1 +10,1 @@" can be expressed as "@@ -10 +10 @@", but this wasn't properly parsed in all cases. Such abbreviated hunk headers are generated when a one-line change (add, remove or modify) appears without context; for example because the file is a one-liner itself or because GIT_DIFF_OPTS was set to '-u0'. If the user then runs 'git add -i' and enters the 'patch' command for that file, perl complains about undefined variables. Signed-off-by: Jean-Luc Herren Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- git-add--interactive.perl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index be6881496c..15b3f5b36c 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -360,7 +360,9 @@ sub hunk_splittable { sub parse_hunk_header { my ($line) = @_; my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = - $line =~ /^@@ -(\d+)(?:,(\d+)) \+(\d+)(?:,(\d+)) @@/; + $line =~ /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/; + $o_cnt = 1 unless defined $o_cnt; + $n_cnt = 1 unless defined $n_cnt; return ($o_ofs, $o_cnt, $n_ofs, $n_cnt); } @@ -705,9 +707,6 @@ sub patch_update_cmd { parse_hunk_header($text->[0]); if (!$_->{USE}) { - if (!defined $o_cnt) { $o_cnt = 1; } - if (!defined $n_cnt) { $n_cnt = 1; } - # We would have added ($n_cnt - $o_cnt) lines # to the postimage if we were to use this hunk, # but we didn't. So the line number that the next @@ -719,10 +718,10 @@ sub patch_update_cmd { if ($n_lofs) { $n_ofs += $n_lofs; $text->[0] = ("@@ -$o_ofs" . - ((defined $o_cnt) + (($o_cnt != 1) ? ",$o_cnt" : '') . " +$n_ofs" . - ((defined $n_cnt) + (($n_cnt != 1) ? ",$n_cnt" : '') . " @@\n"); } -- cgit v1.2.3 From 7b40a4552a0fbdc6ee9a22ce10408d79ca1599af Mon Sep 17 00:00:00 2001 From: Jean-Luc Herren Date: Tue, 9 Oct 2007 21:34:17 +0200 Subject: git add -i: Remove unused variables Signed-off-by: Jean-Luc Herren Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- git-add--interactive.perl | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 15b3f5b36c..ac598f88e6 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -374,9 +374,8 @@ sub split_hunk { # it can be split, but we would need to take care of # overlaps later. - my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = parse_hunk_header($text->[0]); + my ($o_ofs, undef, $n_ofs) = parse_hunk_header($text->[0]); my $hunk_start = 1; - my $next_hunk_start; OUTER: while (1) { @@ -443,8 +442,8 @@ sub split_hunk { for my $hunk (@split) { $o_ofs = $hunk->{OLD}; $n_ofs = $hunk->{NEW}; - $o_cnt = $hunk->{OCNT}; - $n_cnt = $hunk->{NCNT}; + my $o_cnt = $hunk->{OCNT}; + my $n_cnt = $hunk->{NCNT}; my $head = ("@@ -$o_ofs" . (($o_cnt != 1) ? ",$o_cnt" : '') . @@ -459,7 +458,7 @@ sub split_hunk { sub find_last_o_ctx { my ($it) = @_; my $text = $it->{TEXT}; - my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = parse_hunk_header($text->[0]); + my ($o_ofs, $o_cnt) = parse_hunk_header($text->[0]); my $i = @{$text}; my $last_o_ctx = $o_ofs + $o_cnt; while (0 < --$i) { @@ -531,8 +530,7 @@ sub coalesce_overlapping_hunks { for (grep { $_->{USE} } @in) { my $text = $_->{TEXT}; - my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = - parse_hunk_header($text->[0]); + my ($o_ofs) = parse_hunk_header($text->[0]); if (defined $last_o_ctx && $o_ofs <= $last_o_ctx) { merge_hunk($out[-1], $_); @@ -699,7 +697,7 @@ sub patch_update_cmd { @hunk = coalesce_overlapping_hunks(@hunk); - my ($o_lofs, $n_lofs) = (0, 0); + my $n_lofs = 0; my @result = (); for (@hunk) { my $text = $_->{TEXT}; @@ -806,8 +804,6 @@ sub main_loop { } } -my @z; - refresh(); status_cmd(); main_loop(); -- cgit v1.2.3 From 60fcc2e6ce255da1baa92905c10456981d260fa0 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Wed, 10 Oct 2007 23:14:35 +0100 Subject: clear_commit_marks(): avoid deep recursion Before this patch, clear_commit_marks() recursed for each parent. This could be potentially very expensive in terms of stack space. Probably the only reason that this did not lead to problems is the fact that we typically call clear_commit_marks() after marking a relatively small set of commits. Use (sort of) a tail recursion instead: first recurse on the parents other than the first one, and then continue the loop with the first parent. Noticed by Shawn Pearce. Signed-off-by: Johannes Schindelin Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- commit.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/commit.c b/commit.c index dc5a0643f3..1fbdd2d51b 100644 --- a/commit.c +++ b/commit.c @@ -441,17 +441,22 @@ struct commit *pop_most_recent_commit(struct commit_list **list, void clear_commit_marks(struct commit *commit, unsigned int mark) { - struct commit_list *parents; + while (commit) { + struct commit_list *parents; - commit->object.flags &= ~mark; - parents = commit->parents; - while (parents) { - struct commit *parent = parents->item; + if (!(mark & commit->object.flags)) + return; - /* Have we already cleared this? */ - if (mark & parent->object.flags) - clear_commit_marks(parent, mark); - parents = parents->next; + commit->object.flags &= ~mark; + + parents = commit->parents; + if (!parents) + return; + + while ((parents = parents->next)) + clear_commit_marks(parents->item, mark); + + commit = commit->parents->item; } } -- cgit v1.2.3 From 1ae14a6b52f8f0506780cd361933f717163ae19b Mon Sep 17 00:00:00 2001 From: Gerrit Pape Date: Fri, 12 Oct 2007 11:32:51 +0000 Subject: git-config: handle --file option with relative pathname properly When calling git-config not from the top level directory of a repository, it changes directory before trying to open the config file specified through the --file option, which then fails if the config file was specified by a relative pathname. This patch adjusts the pathname to the config file if applicable. The problem was noticed by Joey Hess, reported through http://bugs.debian.org/445208 Signed-off-by: Gerrit Pape Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- builtin-config.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/builtin-config.c b/builtin-config.c index cb7e9e9391..d98b6c2c4c 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -165,7 +165,7 @@ int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = 0; char* value; - setup_git_directory_gently(&nongit); + const char *file = setup_git_directory_gently(&nongit); while (1 < argc) { if (!strcmp(argv[1], "--int")) @@ -192,7 +192,12 @@ int cmd_config(int argc, const char **argv, const char *prefix) else if (!strcmp(argv[1], "--file") || !strcmp(argv[1], "-f")) { if (argc < 3) usage(git_config_set_usage); - setenv(CONFIG_ENVIRONMENT, argv[2], 1); + if (!is_absolute_path(argv[2]) && file) + file = prefix_filename(file, strlen(file), + argv[2]); + else + file = argv[2]; + setenv(CONFIG_ENVIRONMENT, file, 1); argc--; argv++; } -- cgit v1.2.3 From a5d410153736fc5320ad7322e25a6ccf56efcf10 Mon Sep 17 00:00:00 2001 From: Michele Ballabio Date: Thu, 4 Oct 2007 14:26:54 +0200 Subject: git-reflog: document --verbose Signed-off-by: Michele Ballabio Signed-off-by: Lars Hjemli Signed-off-by: Shawn O. Pearce --- Documentation/git-reflog.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index 5180f6810d..5c7316ceb8 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -16,7 +16,7 @@ The command takes various subcommands, and different options depending on the subcommand: [verse] -git reflog expire [--dry-run] [--stale-fix] +git reflog expire [--dry-run] [--stale-fix] [--verbose] [--expire=