Merge branch 'jc/maint-follow-rename-fix'
authorJunio C Hamano <gitster@pobox.com>
Wed, 18 Aug 2010 19:47:18 +0000 (12:47 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 18 Aug 2010 19:47:18 +0000 (12:47 -0700)
* jc/maint-follow-rename-fix:
log: test for regression introduced in v1.7.2-rc0~103^2~2
diff --follow: do call diffcore_std() as necessary
diff --follow: do not waste cycles while recursing

1  2 
diff.c
diff.h
diff --combined diff.c
index ccc9f1f64d094b1943c905f4060dce555745d48b,93004922dee5b4f148dc8e6be5be469f1ffe75e6..7a75bd74c9ab9c98da12f5511ff321645cfa883b
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -31,7 -31,6 +31,7 @@@ static const char *external_diff_cmd_cf
  int diff_auto_refresh_index = 1;
  static int diff_mnemonic_prefix;
  static int diff_no_prefix;
 +static struct diff_options default_diff_options;
  
  static char diff_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_RESET,
@@@ -108,9 -107,6 +108,9 @@@ int git_diff_ui_config(const char *var
        if (!strcmp(var, "diff.wordregex"))
                return git_config_string(&diff_word_regex_cfg, var, value);
  
 +      if (!strcmp(var, "diff.ignoresubmodules"))
 +              handle_ignore_submodules_arg(&default_diff_options, value);
 +
        return git_diff_basic_config(var, value, cb);
  }
  
@@@ -145,9 -141,6 +145,9 @@@ int git_diff_basic_config(const char *v
                return 0;
        }
  
 +      if (!prefixcmp(var, "submodule."))
 +              return parse_submodule_config_option(var, value);
 +
        return git_color_default_config(var, value, cb);
  }
  
@@@ -2826,7 -2819,7 +2826,7 @@@ static void run_checkdiff(struct diff_f
  
  void diff_setup(struct diff_options *options)
  {
 -      memset(options, 0, sizeof(*options));
 +      memcpy(options, &default_diff_options, sizeof(*options));
  
        options->file = stdout;
  
@@@ -3178,13 -3171,11 +3178,13 @@@ int diff_opt_parse(struct diff_options 
                DIFF_OPT_SET(options, ALLOW_TEXTCONV);
        else if (!strcmp(arg, "--no-textconv"))
                DIFF_OPT_CLR(options, ALLOW_TEXTCONV);
 -      else if (!strcmp(arg, "--ignore-submodules"))
 +      else if (!strcmp(arg, "--ignore-submodules")) {
 +              DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(options, "all");
 -      else if (!prefixcmp(arg, "--ignore-submodules="))
 +      } else if (!prefixcmp(arg, "--ignore-submodules=")) {
 +              DIFF_OPT_SET(options, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(options, arg + 20);
 -      else if (!strcmp(arg, "--submodule"))
 +      else if (!strcmp(arg, "--submodule"))
                DIFF_OPT_SET(options, SUBMODULE_LOG);
        else if (!prefixcmp(arg, "--submodule=")) {
                if (!strcmp(arg + 12, "log"))
@@@ -4073,25 -4064,24 +4073,24 @@@ void diffcore_fix_diff_index(struct dif
  
  void diffcore_std(struct diff_options *options)
  {
-       /* We never run this function more than one time, because the
-        * rename/copy detection logic can only run once.
-        */
-       if (diff_queued_diff.run)
-               return;
        if (options->skip_stat_unmatch)
                diffcore_skip_stat_unmatch(options);
-       if (options->break_opt != -1)
-               diffcore_break(options->break_opt);
-       if (options->detect_rename)
-               diffcore_rename(options);
-       if (options->break_opt != -1)
-               diffcore_merge_broken();
+       if (!options->found_follow) {
+               /* See try_to_follow_renames() in tree-diff.c */
+               if (options->break_opt != -1)
+                       diffcore_break(options->break_opt);
+               if (options->detect_rename)
+                       diffcore_rename(options);
+               if (options->break_opt != -1)
+                       diffcore_merge_broken();
+       }
        if (options->pickaxe)
                diffcore_pickaxe(options->pickaxe, options->pickaxe_opts);
        if (options->orderfile)
                diffcore_order(options->orderfile);
-       diff_resolve_rename_copy();
+       if (!options->found_follow)
+               /* See try_to_follow_renames() in tree-diff.c */
+               diff_resolve_rename_copy();
        diffcore_apply_filter(options->filter);
  
        if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
        else
                DIFF_OPT_CLR(options, HAS_CHANGES);
  
-       diff_queued_diff.run = 1;
+       options->found_follow = 0;
  }
  
  int diff_result_code(struct diff_options *opt, int status)
        return result;
  }
  
 +/*
 + * Shall changes to this submodule be ignored?
 + *
 + * Submodule changes can be configured to be ignored separately for each path,
 + * but that configuration can be overridden from the command line.
 + */
 +static int is_submodule_ignored(const char *path, struct diff_options *options)
 +{
 +      int ignored = 0;
 +      unsigned orig_flags = options->flags;
 +      if (!DIFF_OPT_TST(options, OVERRIDE_SUBMODULE_CONFIG))
 +              set_diffopt_flags_from_submodule_config(options, path);
 +      if (DIFF_OPT_TST(options, IGNORE_SUBMODULES))
 +              ignored = 1;
 +      options->flags = orig_flags;
 +      return ignored;
 +}
 +
  void diff_addremove(struct diff_options *options,
                    int addremove, unsigned mode,
                    const unsigned char *sha1,
  {
        struct diff_filespec *one, *two;
  
 -      if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(mode))
 +      if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options))
                return;
  
        /* This may look odd, but it is a preparation for
@@@ -4189,8 -4161,8 +4188,8 @@@ void diff_change(struct diff_options *o
  {
        struct diff_filespec *one, *two;
  
 -      if (DIFF_OPT_TST(options, IGNORE_SUBMODULES) && S_ISGITLINK(old_mode)
 -                      && S_ISGITLINK(new_mode))
 +      if (S_ISGITLINK(old_mode) && S_ISGITLINK(new_mode) &&
 +          is_submodule_ignored(concatpath, options))
                return;
  
        if (DIFF_OPT_TST(options, REVERSE_DIFF)) {
diff --combined diff.h
index 53ad345469ad106e768c0d9eda7f732e09832b01,6fff024e3ad9462c717595cd90d7fcca1da6410c..d43da9da95fae4dd13d3abbe738948708cf90939
--- 1/diff.h
--- 2/diff.h
+++ b/diff.h
@@@ -77,7 -77,6 +77,7 @@@ typedef struct strbuf *(*diff_prefix_fn
  #define DIFF_OPT_DIRTY_SUBMODULES    (1 << 24)
  #define DIFF_OPT_IGNORE_UNTRACKED_IN_SUBMODULES (1 << 25)
  #define DIFF_OPT_IGNORE_DIRTY_SUBMODULES (1 << 26)
 +#define DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG (1 << 27)
  
  #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)
  #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)
@@@ -127,6 -126,9 +127,9 @@@ struct diff_options 
        /* this is set by diffcore for DIFF_FORMAT_PATCH */
        int found_changes;
  
+       /* to support internal diff recursion by --follow hack*/
+       int found_follow;
        FILE *file;
        int close_file;