Skip to content

Commit

Permalink
log: add "log.follow" configuration variable
Browse files Browse the repository at this point in the history
People who work on projects with mostly linear history with frequent
whole file renames may want to always use "git log --follow" when
inspecting the life of the content that live in a single path.

Teach the command to behave as if "--follow" was given from the
command line when log.follow configuration variable is set *and*
there is one (and only one) path on the command line.

Signed-off-by: David Turner <dturner@twopensource.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
dturner-tw authored and gitster committed Jul 9, 2015
1 parent 5bdb7a7 commit 076c983
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 2 deletions.
6 changes: 6 additions & 0 deletions Documentation/git-log.txt
Expand Up @@ -184,6 +184,12 @@ log.date::
`--date` option.) Defaults to "default", which means to write
dates like `Sat May 8 19:35:34 2010 -0500`.

log.follow::
If a single <path> is given to git log, it will act as
if the `--follow` option was also used. This has the same
limitations as `--follow`, i.e. it cannot be used to follow
multiple files and does not work well on non-linear history.

log.showRoot::
If `false`, `git log` and related commands will not treat the
initial commit as a big creation event. Any root commits in
Expand Down
16 changes: 16 additions & 0 deletions builtin/log.c
Expand Up @@ -31,6 +31,7 @@ static const char *default_date_mode = NULL;

static int default_abbrev_commit;
static int default_show_root = 1;
static int default_follow;
static int decoration_style;
static int decoration_given;
static int use_mailmap_config;
Expand Down Expand Up @@ -102,6 +103,8 @@ static void cmd_log_init_defaults(struct rev_info *rev)
{
if (fmt_pretty)
get_commit_format(fmt_pretty, rev);
if (default_follow)
DIFF_OPT_SET(&rev->diffopt, DEFAULT_FOLLOW_RENAMES);
rev->verbose_header = 1;
DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
rev->diffopt.stat_width = -1; /* use full terminal width */
Expand Down Expand Up @@ -390,6 +393,10 @@ static int git_log_config(const char *var, const char *value, void *cb)
default_show_root = git_config_bool(var, value);
return 0;
}
if (!strcmp(var, "log.follow")) {
default_follow = git_config_bool(var, value);
return 0;
}
if (skip_prefix(var, "color.decorate.", &slot_name))
return parse_decorate_color_config(var, slot_name, value);
if (!strcmp(var, "log.mailmap")) {
Expand Down Expand Up @@ -618,6 +625,14 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix)
return cmd_log_walk(&rev);
}

static void default_follow_tweak(struct rev_info *rev,
struct setup_revision_opt *opt)
{
if (DIFF_OPT_TST(&rev->diffopt, DEFAULT_FOLLOW_RENAMES) &&
rev->prune_data.nr == 1)
DIFF_OPT_SET(&rev->diffopt, FOLLOW_RENAMES);
}

int cmd_log(int argc, const char **argv, const char *prefix)
{
struct rev_info rev;
Expand All @@ -631,6 +646,7 @@ int cmd_log(int argc, const char **argv, const char *prefix)
memset(&opt, 0, sizeof(opt));
opt.def = "HEAD";
opt.revarg_opt = REVARG_COMMITTISH;
opt.tweak = default_follow_tweak;
cmd_log_init(argc, argv, prefix, &rev, &opt);
return cmd_log_walk(&rev);
}
Expand Down
5 changes: 3 additions & 2 deletions diff.c
Expand Up @@ -3815,9 +3815,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_SET(options, FIND_COPIES_HARDER);
else if (!strcmp(arg, "--follow"))
DIFF_OPT_SET(options, FOLLOW_RENAMES);
else if (!strcmp(arg, "--no-follow"))
else if (!strcmp(arg, "--no-follow")) {
DIFF_OPT_CLR(options, FOLLOW_RENAMES);
else if (!strcmp(arg, "--color"))
DIFF_OPT_CLR(options, DEFAULT_FOLLOW_RENAMES);
} else if (!strcmp(arg, "--color"))
options->use_color = 1;
else if (skip_prefix(arg, "--color=", &arg)) {
int value = git_config_colorbool(NULL, arg);
Expand Down
1 change: 1 addition & 0 deletions diff.h
Expand Up @@ -91,6 +91,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)
#define DIFF_OPT_DIRSTAT_BY_LINE (1 << 28)
#define DIFF_OPT_FUNCCONTEXT (1 << 29)
#define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30)
#define DIFF_OPT_DEFAULT_FOLLOW_RENAMES (1 << 31)

#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
#define DIFF_OPT_TOUCHED(opts, flag) ((opts)->touched_flags & DIFF_OPT_##flag)
Expand Down
23 changes: 23 additions & 0 deletions t/t4202-log.sh
Expand Up @@ -146,7 +146,30 @@ test_expect_success 'git log --follow' '
actual=$(git log --follow --pretty="format:%s" ichi) &&
expect=$(echo third ; echo second ; echo initial) &&
verbose test "$actual" = "$expect"
'

test_expect_success 'git config log.follow works like --follow' '
test_config log.follow true &&
actual=$(git log --pretty="format:%s" ichi) &&
expect=$(echo third ; echo second ; echo initial) &&
verbose test "$actual" = "$expect"
'

test_expect_success 'git config log.follow does not die with multiple paths' '
test_config log.follow true &&
git log --pretty="format:%s" ichi ein
'

test_expect_success 'git config log.follow does not die with no paths' '
test_config log.follow true &&
git log --
'

test_expect_success 'git config log.follow is overridden by --no-follow' '
test_config log.follow true &&
actual=$(git log --no-follow --pretty="format:%s" ichi) &&
expect="third" &&
verbose test "$actual" = "$expect"
'

cat > expect << EOF
Expand Down

0 comments on commit 076c983

Please sign in to comment.