]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'sb/plug-wt-shortstatus-tracking-leak'
authorJunio C Hamano <gitster@pobox.com>
Tue, 14 Apr 2015 18:49:07 +0000 (11:49 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 14 Apr 2015 18:49:07 +0000 (11:49 -0700)
* sb/plug-wt-shortstatus-tracking-leak:
  wt-status.c: fix a memleak

1  2 
wt-status.c

diff --combined wt-status.c
index 853419f05f232045cf4ad3f8a8a2af04be9329a0,3ec4383ae9a3f8c896ba8b7cbe2169e7fb7bd451..38cb165f124d610c789a8d82de42281c795111f7
@@@ -128,7 -128,7 +128,7 @@@ void wt_status_prepare(struct wt_statu
        s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
        s->use_color = -1;
        s->relative_paths = 1;
 -      s->branch = resolve_refdup("HEAD", sha1, 0, NULL);
 +      s->branch = resolve_refdup("HEAD", 0, sha1, NULL);
        s->reference = "HEAD";
        s->fp = stdout;
        s->index_file = get_index_file();
@@@ -188,7 -188,7 +188,7 @@@ static void wt_status_print_unmerged_he
        } else {
                status_printf_ln(s, c, _("  (use \"git add/rm <file>...\" as appropriate to mark resolution)"));
        }
 -      status_printf_ln(s, c, "");
 +      status_printf_ln(s, c, "%s", "");
  }
  
  static void wt_status_print_cached_header(struct wt_status *s)
                status_printf_ln(s, c, _("  (use \"git reset %s <file>...\" to unstage)"), s->reference);
        else
                status_printf_ln(s, c, _("  (use \"git rm --cached <file>...\" to unstage)"));
 -      status_printf_ln(s, c, "");
 +      status_printf_ln(s, c, "%s", "");
  }
  
  static void wt_status_print_dirty_header(struct wt_status *s,
        status_printf_ln(s, c, _("  (use \"git checkout -- <file>...\" to discard changes in working directory)"));
        if (has_dirty_submodules)
                status_printf_ln(s, c, _("  (commit or discard the untracked or modified content in submodules)"));
 -      status_printf_ln(s, c, "");
 +      status_printf_ln(s, c, "%s", "");
  }
  
  static void wt_status_print_other_header(struct wt_status *s,
        if (!s->hints)
                return;
        status_printf_ln(s, c, _("  (use \"git %s <file>...\" to include in what will be committed)"), how);
 -      status_printf_ln(s, c, "");
 +      status_printf_ln(s, c, "%s", "");
  }
  
  static void wt_status_print_trailer(struct wt_status *s)
  {
 -      status_printf_ln(s, color(WT_STATUS_HEADER, s), "");
 +      status_printf_ln(s, color(WT_STATUS_HEADER, s), "%s", "");
  }
  
  #define quote_path quote_path_relative
@@@ -519,19 -519,9 +519,19 @@@ static void wt_status_collect_changes_i
        opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
        setup_revisions(0, NULL, &rev, &opt);
  
 +      DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
        if (s->ignore_submodule_arg) {
 -              DIFF_OPT_SET(&rev.diffopt, OVERRIDE_SUBMODULE_CONFIG);
                handle_ignore_submodules_arg(&rev.diffopt, s->ignore_submodule_arg);
 +      } else {
 +              /*
 +               * Unless the user did explicitly request a submodule ignore
 +               * mode by passing a command line option we do not ignore any
 +               * changed submodule SHA-1s when comparing index and HEAD, no
 +               * matter what is configured. Otherwise the user won't be
 +               * shown any submodules she manually added (and which are
 +               * staged to be committed), which would be really confusing.
 +               */
 +              handle_ignore_submodules_arg(&rev.diffopt, "dirty");
        }
  
        rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
@@@ -574,11 -564,14 +574,11 @@@ static void wt_status_collect_untracked
  {
        int i;
        struct dir_struct dir;
 -      struct timeval t_begin;
 +      uint64_t t_begin = getnanotime();
  
        if (!s->show_untracked_files)
                return;
  
 -      if (advice_status_u_option)
 -              gettimeofday(&t_begin, NULL);
 -
        memset(&dir, 0, sizeof(dir));
        if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES)
                dir.flags |=
        free(dir.ignored);
        clear_directory(&dir);
  
 -      if (advice_status_u_option) {
 -              struct timeval t_end;
 -              gettimeofday(&t_end, NULL);
 -              s->untracked_in_ms =
 -                      (uint64_t)t_end.tv_sec * 1000 + t_end.tv_usec / 1000 -
 -                      ((uint64_t)t_begin.tv_sec * 1000 + t_begin.tv_usec / 1000);
 -      }
 +      if (advice_status_u_option)
 +              s->untracked_in_ms = (getnanotime() - t_begin) / 1000000;
  }
  
  void wt_status_collect(struct wt_status *s)
@@@ -725,30 -723,44 +725,30 @@@ static void wt_status_print_changed(str
  
  static void wt_status_print_submodule_summary(struct wt_status *s, int uncommitted)
  {
 -      struct child_process sm_summary;
 -      char summary_limit[64];
 -      char index[PATH_MAX];
 -      const char *env[] = { NULL, NULL };
 -      struct argv_array argv = ARGV_ARRAY_INIT;
 +      struct child_process sm_summary = CHILD_PROCESS_INIT;
        struct strbuf cmd_stdout = STRBUF_INIT;
        struct strbuf summary = STRBUF_INIT;
        char *summary_content;
 -      size_t len;
 -
 -      sprintf(summary_limit, "%d", s->submodule_summary);
 -      snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", s->index_file);
 -
 -      env[0] = index;
 -      argv_array_push(&argv, "submodule");
 -      argv_array_push(&argv, "summary");
 -      argv_array_push(&argv, uncommitted ? "--files" : "--cached");
 -      argv_array_push(&argv, "--for-status");
 -      argv_array_push(&argv, "--summary-limit");
 -      argv_array_push(&argv, summary_limit);
 +
 +      argv_array_pushf(&sm_summary.env_array, "GIT_INDEX_FILE=%s",
 +                       s->index_file);
 +
 +      argv_array_push(&sm_summary.args, "submodule");
 +      argv_array_push(&sm_summary.args, "summary");
 +      argv_array_push(&sm_summary.args, uncommitted ? "--files" : "--cached");
 +      argv_array_push(&sm_summary.args, "--for-status");
 +      argv_array_push(&sm_summary.args, "--summary-limit");
 +      argv_array_pushf(&sm_summary.args, "%d", s->submodule_summary);
        if (!uncommitted)
 -              argv_array_push(&argv, s->amend ? "HEAD^" : "HEAD");
 +              argv_array_push(&sm_summary.args, s->amend ? "HEAD^" : "HEAD");
  
 -      memset(&sm_summary, 0, sizeof(sm_summary));
 -      sm_summary.argv = argv.argv;
 -      sm_summary.env = env;
        sm_summary.git_cmd = 1;
        sm_summary.no_stdin = 1;
 -      fflush(s->fp);
 -      sm_summary.out = -1;
 -
 -      run_command(&sm_summary);
 -      argv_array_clear(&argv);
  
 -      len = strbuf_read(&cmd_stdout, sm_summary.out, 1024);
 +      capture_command(&sm_summary, &cmd_stdout, 1024);
  
        /* prepend header, only if there's an actual output */
 -      if (len) {
 +      if (cmd_stdout.len) {
                if (uncommitted)
                        strbuf_addstr(&summary, _("Submodules changed but not updated:"));
                else
        strbuf_release(&cmd_stdout);
  
        if (s->display_comment_prefix) {
 +              size_t len;
                summary_content = strbuf_detach(&summary, &len);
                strbuf_add_commented_lines(&summary, summary_content, len);
                free(summary_content);
@@@ -815,7 -826,7 +815,7 @@@ static void wt_status_print_other(struc
        string_list_clear(&output, 0);
        strbuf_release(&buf);
  conclude:
 -      status_printf_ln(s, GIT_COLOR_NORMAL, "");
 +      status_printf_ln(s, GIT_COLOR_NORMAL, "%s", "");
  }
  
  void wt_status_truncate_message_at_cut_line(struct strbuf *buf)
@@@ -845,8 -856,6 +845,8 @@@ static void wt_status_print_verbose(str
  {
        struct rev_info rev;
        struct setup_revision_opt opt;
 +      int dirty_submodules;
 +      const char *c = color(WT_STATUS_HEADER, s);
  
        init_revisions(&rev, NULL);
        DIFF_OPT_SET(&rev.diffopt, ALLOW_TEXTCONV);
                rev.diffopt.use_color = 0;
                wt_status_add_cut_line(s->fp);
        }
 +      if (s->verbose > 1 && s->commitable) {
 +              /* print_updated() printed a header, so do we */
 +              if (s->fp != stdout)
 +                      wt_status_print_trailer(s);
 +              status_printf_ln(s, c, _("Changes to be committed:"));
 +              rev.diffopt.a_prefix = "c/";
 +              rev.diffopt.b_prefix = "i/";
 +      } /* else use prefix as per user config */
        run_diff_index(&rev, 1);
 +      if (s->verbose > 1 &&
 +          wt_status_check_worktree_changes(s, &dirty_submodules)) {
 +              status_printf_ln(s, c,
 +                      "--------------------------------------------------");
 +              status_printf_ln(s, c, _("Changes not staged for commit:"));
 +              setup_work_tree();
 +              rev.diffopt.a_prefix = "i/";
 +              rev.diffopt.b_prefix = "w/";
 +              run_diff_files(&rev, 0);
 +      }
  }
  
  static void wt_status_print_tracking(struct wt_status *s)
                color_fprintf_ln(s->fp, color(WT_STATUS_HEADER, s), "%c",
                                 comment_line_char);
        else
 -              fprintf_ln(s->fp, "");
 +              fputs("", s->fp);
  }
  
  static int has_unmerged(struct wt_status *s)
@@@ -1156,7 -1147,7 +1156,7 @@@ static char *read_and_strip_branch(cons
        if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0)
                goto got_nothing;
  
 -      while (&sb.len && sb.buf[sb.len - 1] == '\n')
 +      while (sb.len && sb.buf[sb.len - 1] == '\n')
                strbuf_setlen(&sb, sb.len - 1);
        if (!sb.len)
                goto got_nothing;
@@@ -1238,8 -1229,6 +1238,8 @@@ static void wt_status_get_detached_from
                state->detached_from =
                        xstrdup(find_unique_abbrev(cb.nsha1, DEFAULT_ABBREV));
        hashcpy(state->detached_sha1, cb.nsha1);
 +      state->detached_at = !get_sha1("HEAD", sha1) &&
 +                           !hashcmp(sha1, state->detached_sha1);
  
        free(ref);
        strbuf_release(&cb.buf);
@@@ -1328,8 -1317,10 +1328,8 @@@ void wt_status_print(struct wt_status *
                                on_what = _("rebase in progress; onto ");
                                branch_name = state.onto;
                        } else if (state.detached_from) {
 -                              unsigned char sha1[20];
                                branch_name = state.detached_from;
 -                              if (!get_sha1("HEAD", sha1) &&
 -                                  !hashcmp(sha1, state.detached_sha1))
 +                              if (state.detached_at)
                                        on_what = _("HEAD detached at ");
                                else
                                        on_what = _("HEAD detached from ");
                                on_what = _("Not currently on any branch.");
                        }
                }
 -              status_printf(s, color(WT_STATUS_HEADER, s), "");
 +              status_printf(s, color(WT_STATUS_HEADER, s), "%s", "");
                status_printf_more(s, branch_status_color, "%s", on_what);
                status_printf_more(s, branch_color, "%s\n", branch_name);
                if (!s->is_initial)
        free(state.detached_from);
  
        if (s->is_initial) {
 -              status_printf_ln(s, color(WT_STATUS_HEADER, s), "");
 +              status_printf_ln(s, color(WT_STATUS_HEADER, s), "%s", "");
                status_printf_ln(s, color(WT_STATUS_HEADER, s), _("Initial commit"));
 -              status_printf_ln(s, color(WT_STATUS_HEADER, s), "");
 +              status_printf_ln(s, color(WT_STATUS_HEADER, s), "%s", "");
        }
  
        wt_status_print_updated(s);
                if (s->show_ignored_files)
                        wt_status_print_other(s, &s->ignored, _("Ignored files"), "add -f");
                if (advice_status_u_option && 2000 < s->untracked_in_ms) {
 -                      status_printf_ln(s, GIT_COLOR_NORMAL, "");
 +                      status_printf_ln(s, GIT_COLOR_NORMAL, "%s", "");
                        status_printf_ln(s, GIT_COLOR_NORMAL,
                                         _("It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
                                           "may speed it up, but you have to be careful not to forget to add\n"
@@@ -1550,6 -1541,7 +1550,7 @@@ static void wt_shortstatus_print_tracki
        base = shorten_unambiguous_ref(base, 0);
        color_fprintf(s->fp, header_color, "...");
        color_fprintf(s->fp, branch_color_remote, "%s", base);
+       free((char *)base);
  
        if (!upstream_is_gone && !num_ours && !num_theirs) {
                fputc(s->null_termination ? '\0' : '\n', s->fp);