{"thread":{"id":"39809","subject":"[PATCH v3] log: add log.follow config option","startedAt":"2015-07-08T01:29:34Z","lastAt":"2015-07-08T01:29:34Z","messageCount":1,"participants":["David Turner"],"isPatch":true,"patchVersion":3,"patchTotal":null},"messages":[{"id":"265798","messageId":"1436318974-16250-1-git-send-email-dturner@twopensource.com","threadId":"39809","inReplyTo":null,"subject":"[PATCH v3] log: add log.follow config option","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2015-07-08T01:29:34Z","receivedAt":"2015-07-08T01:29:34Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"Many users prefer to always use --follow with logs.  Rather than\naliasing the command, an option might be more convenient for some.\n\nSigned-off-by: David Turner <dturner@twopensource.com>\n---\n Documentation/git-log.txt |  6 ++++++\n builtin/log.c             |  7 +++++++\n diff.c                    |  5 +++--\n diff.h                    |  1 +\n revision.c                | 17 +++++++++++------\n t/t4202-log.sh            | 23 +++++++++++++++++++++++\n 6 files changed, 51 insertions(+), 8 deletions(-)\n\ndiff --git a/Documentation/git-log.txt b/Documentation/git-log.txt\nindex 5692945..79bf4d4 100644\n--- a/Documentation/git-log.txt\n+++ b/Documentation/git-log.txt\n@@ -184,6 +184,12 @@ log.date::\n \t`--date` option.)  Defaults to \"default\", which means to write\n \tdates like `Sat May 8 19:35:34 2010 -0500`.\n \n+log.follow::\n+\tIf a single file argument is given to git log, it will act as\n+\tif the `--follow` option was also used.  This has the same\n+\tlimitations as `--follow`, i.e. it cannot be used to follow\n+\tmultiple files and does not work well on non-linear history.\n+\n log.showRoot::\n \tIf `false`, `git log` and related commands will not treat the\n \tinitial commit as a big creation event.  Any root commits in\ndiff --git a/builtin/log.c b/builtin/log.c\nindex 8781049..6a068f7 100644\n--- a/builtin/log.c\n+++ b/builtin/log.c\n@@ -31,6 +31,7 @@ static const char *default_date_mode = NULL;\n \n static int default_abbrev_commit;\n static int default_show_root = 1;\n+static int default_follow;\n static int decoration_style;\n static int decoration_given;\n static int use_mailmap_config;\n@@ -102,6 +103,8 @@ static void cmd_log_init_defaults(struct rev_info *rev)\n {\n \tif (fmt_pretty)\n \t\tget_commit_format(fmt_pretty, rev);\n+\tif (default_follow)\n+\t\tDIFF_OPT_SET(&rev->diffopt, DEFAULT_FOLLOW_RENAMES);\n \trev->verbose_header = 1;\n \tDIFF_OPT_SET(&rev->diffopt, RECURSIVE);\n \trev->diffopt.stat_width = -1; /* use full terminal width */\n@@ -390,6 +393,10 @@ static int git_log_config(const char *var, const char *value, void *cb)\n \t\tdefault_show_root = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n+\tif (!strcmp(var, \"log.follow\")) {\n+\t\tdefault_follow = git_config_bool(var, value);\n+\t\treturn 0;\n+\t}\n \tif (skip_prefix(var, \"color.decorate.\", &slot_name))\n \t\treturn parse_decorate_color_config(var, slot_name, value);\n \tif (!strcmp(var, \"log.mailmap\")) {\ndiff --git a/diff.c b/diff.c\nindex 87b16d5..135b222 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -3815,9 +3815,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)\n \t\tDIFF_OPT_SET(options, FIND_COPIES_HARDER);\n \telse if (!strcmp(arg, \"--follow\"))\n \t\tDIFF_OPT_SET(options, FOLLOW_RENAMES);\n-\telse if (!strcmp(arg, \"--no-follow\"))\n+\telse if (!strcmp(arg, \"--no-follow\")) {\n \t\tDIFF_OPT_CLR(options, FOLLOW_RENAMES);\n-\telse if (!strcmp(arg, \"--color\"))\n+\t\tDIFF_OPT_CLR(options, DEFAULT_FOLLOW_RENAMES);\n+\t} else if (!strcmp(arg, \"--color\"))\n \t\toptions->use_color = 1;\n \telse if (skip_prefix(arg, \"--color=\", &arg)) {\n \t\tint value = git_config_colorbool(NULL, arg);\ndiff --git a/diff.h b/diff.h\nindex c7ad42a..f7208ad 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -91,6 +91,7 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data)\n #define DIFF_OPT_DIRSTAT_BY_LINE     (1 << 28)\n #define DIFF_OPT_FUNCCONTEXT         (1 << 29)\n #define DIFF_OPT_PICKAXE_IGNORE_CASE (1 << 30)\n+#define DIFF_OPT_DEFAULT_FOLLOW_RENAMES (1 << 31)\n \n #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)\n #define DIFF_OPT_TOUCHED(opts, flag)    ((opts)->touched_flags & DIFF_OPT_##flag)\ndiff --git a/revision.c b/revision.c\nindex 3ff8723..7c1931b 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2311,15 +2311,13 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s\n \tif (revs->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT)\n \t\trevs->diff = 1;\n \n-\t/* Pickaxe, diff-filter and rename following need diffs */\n-\tif (revs->diffopt.pickaxe ||\n-\t    revs->diffopt.filter ||\n-\t    DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))\n-\t\trevs->diff = 1;\n-\n \tif (revs->topo_order)\n \t\trevs->limited = 1;\n \n+\tif (DIFF_OPT_TST(&revs->diffopt, DEFAULT_FOLLOW_RENAMES) &&\n+\t    revs->prune_data.nr == 1)\n+\t\tDIFF_OPT_SET(&revs->diffopt, FOLLOW_RENAMES);\n+\n \tif (revs->prune_data.nr) {\n \t\tcopy_pathspec(&revs->pruning.pathspec, &revs->prune_data);\n \t\t/* Can't prune commits with rename following: the paths change.. */\n@@ -2329,6 +2327,13 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s\n \t\t\tcopy_pathspec(&revs->diffopt.pathspec,\n \t\t\t\t      &revs->prune_data);\n \t}\n+\n+\t/* Pickaxe, diff-filter and rename following need diffs */\n+\tif (revs->diffopt.pickaxe ||\n+\t    revs->diffopt.filter ||\n+\t    DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))\n+\t\trevs->diff = 1;\n+\n \tif (revs->combine_merges)\n \t\trevs->ignore_merges = 0;\n \trevs->diffopt.abbrev = revs->abbrev;\ndiff --git a/t/t4202-log.sh b/t/t4202-log.sh\nindex 1b2e981..dbabbc3 100755\n--- a/t/t4202-log.sh\n+++ b/t/t4202-log.sh\n@@ -146,7 +146,30 @@ test_expect_success 'git log --follow' '\n \tactual=$(git log --follow --pretty=\"format:%s\" ichi) &&\n \texpect=$(echo third ; echo second ; echo initial) &&\n \tverbose test \"$actual\" = \"$expect\"\n+'\n+\n+test_expect_success 'git config log.follow works like --follow' '\n+\ttest_config log.follow true &&\n+\tactual=$(git log --pretty=\"format:%s\" ichi) &&\n+\texpect=$(echo third ; echo second ; echo initial) &&\n+\tverbose test \"$actual\" = \"$expect\"\n+'\n \n+test_expect_success 'git config log.follow does not die with multiple paths' '\n+\ttest_config log.follow true &&\n+\tgit log --pretty=\"format:%s\" ichi ein\n+'\n+\n+test_expect_success 'git config log.follow does not die with no paths' '\n+\ttest_config log.follow true &&\n+\tgit log --\n+'\n+\n+test_expect_success  'git config log.follow is overridden by --no-follow' '\n+\ttest_config log.follow true &&\n+\tactual=$(git log --no-follow --pretty=\"format:%s\" ichi) &&\n+\texpect=\"third\" &&\n+\tverbose test \"$actual\" = \"$expect\"\n '\n \n cat > expect << EOF\n-- \n2.0.5.499.g01f6352.dirty-twtrsrc\n"}]}