Merge branch 'ss/describe-dirty-in-the-right-directory'
authorJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2019 06:05:29 +0000 (22:05 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2019 06:05:29 +0000 (22:05 -0800)
"git --work-tree=$there --git-dir=$here describe --dirty" did not
work correctly as it did not pay attention to the location of the
worktree specified by the user by mistake, which has been
corrected.

* ss/describe-dirty-in-the-right-directory:
t6120: test for describe with a bare repository
describe: setup working tree for --dirty

1  2 
builtin/describe.c
t/t6120-describe.sh
diff --combined builtin/describe.c
index 02ec56417a197b7e252625561fa462a215499a4d,d281dff2b346dc7a0f2f3a69247cf683a859fb6c..1409cedce2fb08dc24b57db9e3a3591c3760d8af
@@@ -1,4 -1,3 +1,4 @@@
 +#define USE_THE_INDEX_COMPATIBILITY_MACROS
  #include "cache.h"
  #include "config.h"
  #include "lockfile.h"
  #include "hashmap.h"
  #include "argv-array.h"
  #include "run-command.h"
 +#include "object-store.h"
  #include "revision.h"
  #include "list-objects.h"
 +#include "commit-slab.h"
  
  #define MAX_TAGS      (FLAG_BITS - 1)
  
 +define_commit_slab(commit_names, struct commit_name *);
 +
  static const char * const describe_usage[] = {
        N_("git describe [<options>] [<commit-ish>...]"),
        N_("git describe [<options>] --dirty"),
@@@ -42,7 -37,6 +42,7 @@@ static struct string_list patterns = ST
  static struct string_list exclude_patterns = STRING_LIST_INIT_NODUP;
  static int always;
  static const char *suffix, *dirty, *broken;
 +static struct commit_names commit_names;
  
  /* diff-index command arguments to check if working tree is dirty. */
  static const char *diff_index_args[] = {
@@@ -63,7 -57,7 +63,7 @@@ static const char *prio_names[] = 
        N_("head"), N_("lightweight"), N_("annotated"),
  };
  
 -static int commit_name_cmp(const void *unused_cmp_data,
 +static int commit_name_neq(const void *unused_cmp_data,
                           const void *entry,
                           const void *entry_or_key,
                           const void *peeled)
@@@ -71,7 -65,7 +71,7 @@@
        const struct commit_name *cn1 = entry;
        const struct commit_name *cn2 = entry_or_key;
  
 -      return oidcmp(&cn1->peeled, peeled ? peeled : &cn2->peeled);
 +      return !oideq(&cn1->peeled, peeled ? peeled : &cn2->peeled);
  }
  
  static inline struct commit_name *find_commit_name(const struct object_id *peeled)
@@@ -94,13 -88,13 +94,13 @@@ static int replace_name(struct commit_n
                struct tag *t;
  
                if (!e->tag) {
 -                      t = lookup_tag(&e->oid);
 +                      t = lookup_tag(the_repository, &e->oid);
                        if (!t || parse_tag(t))
                                return 1;
                        e->tag = t;
                }
  
 -              t = lookup_tag(oid);
 +              t = lookup_tag(the_repository, oid);
                if (!t || parse_tag(t))
                        return 0;
                *tag = t;
@@@ -191,7 -185,7 +191,7 @@@ static int get_name(const char *path, c
  
        /* Is it annotated? */
        if (!peel_ref(path, &peeled)) {
 -              is_annotated = !!oidcmp(oid, &peeled);
 +              is_annotated = !oideq(oid, &peeled);
        } else {
                oidcpy(&peeled, oid);
                is_annotated = 0;
@@@ -268,7 -262,7 +268,7 @@@ static unsigned long finish_depth_compu
  static void append_name(struct commit_name *n, struct strbuf *dst)
  {
        if (n->prio == 2 && !n->tag) {
 -              n->tag = lookup_tag(&n->oid);
 +              n->tag = lookup_tag(the_repository, &n->oid);
                if (!n->tag || parse_tag(n->tag))
                        die(_("annotated tag %s not available"), n->path);
        }
@@@ -304,7 -298,7 +304,7 @@@ static void describe_commit(struct obje
        unsigned long seen_commits = 0;
        unsigned int unannotated_cnt = 0;
  
 -      cmit = lookup_commit_reference(oid);
 +      cmit = lookup_commit_reference(the_repository, oid);
  
        n = find_commit_name(&cmit->object.oid);
        if (n && (tags || all || n->prio == 2)) {
        if (!have_util) {
                struct hashmap_iter iter;
                struct commit *c;
 -              struct commit_name *n = hashmap_iter_first(&names, &iter);
 +              struct commit_name *n;
 +
 +              init_commit_names(&commit_names);
 +              n = hashmap_iter_first(&names, &iter);
                for (; n; n = hashmap_iter_next(&iter)) {
 -                      c = lookup_commit_reference_gently(&n->peeled, 1);
 +                      c = lookup_commit_reference_gently(the_repository,
 +                                                         &n->peeled, 1);
                        if (c)
 -                              c->util = n;
 +                              *commit_names_at(&commit_names, c) = n;
                }
                have_util = 1;
        }
        while (list) {
                struct commit *c = pop_commit(&list);
                struct commit_list *parents = c->parents;
 +              struct commit_name **slot;
 +
                seen_commits++;
 -              n = c->util;
 +              slot = commit_names_peek(&commit_names, c);
 +              n = slot ? *slot : NULL;
                if (n) {
                        if (!tags && !all && n->prio < 2) {
                                unannotated_cnt++;
@@@ -470,7 -457,7 +470,7 @@@ static void process_object(struct objec
  {
        struct process_commit_data *pcd = data;
  
 -      if (!oidcmp(&pcd->looking_for, &obj->oid) && !pcd->dst->len) {
 +      if (oideq(&pcd->looking_for, &obj->oid) && !pcd->dst->len) {
                reset_revision_walk();
                describe_commit(&pcd->current_commit, pcd->dst);
                strbuf_addf(pcd->dst, ":%s", path);
@@@ -489,7 -476,7 +489,7 @@@ static void describe_blob(struct object
                "--objects", "--in-commit-order", "--reverse", "HEAD",
                NULL);
  
 -      init_revisions(&revs, NULL);
 +      repo_init_revisions(the_repository, &revs, NULL);
        if (setup_revisions(args.argc, args.argv, &revs, NULL) > 1)
                BUG("setup_revisions could not handle all args?");
  
@@@ -511,7 -498,7 +511,7 @@@ static void describe(const char *arg, i
  
        if (get_oid(arg, &oid))
                die(_("Not a valid object name %s"), arg);
 -      cmit = lookup_commit_reference_gently(&oid, 1);
 +      cmit = lookup_commit_reference_gently(the_repository, &oid, 1);
  
        if (cmit)
                describe_commit(&oid, &sb);
@@@ -597,7 -584,7 +597,7 @@@ int cmd_describe(int argc, const char *
                return cmd_name_rev(args.argc, args.argv, prefix);
        }
  
 -      hashmap_init(&names, commit_name_cmp, NULL, 0);
 +      hashmap_init(&names, commit_name_neq, NULL, 0);
        for_each_rawref(get_name, NULL);
        if (!hashmap_get_size(&names) && !always)
                die(_("No names found, cannot describe anything."));
                        struct argv_array args = ARGV_ARRAY_INIT;
                        int fd, result;
  
 -                      read_cache_preload(NULL);
+                       setup_work_tree();
 +                      read_cache();
                        refresh_index(&the_index, REFRESH_QUIET|REFRESH_UNMERGED,
                                      NULL, NULL, NULL);
                        fd = hold_locked_index(&index_lock, 0);
                        if (0 <= fd)
 -                              update_index_if_able(&the_index, &index_lock);
 +                              repo_update_index_if_able(the_repository, &index_lock);
  
 -                      init_revisions(&revs, prefix);
 +                      repo_init_revisions(the_repository, &revs, prefix);
                        argv_array_pushv(&args, diff_index_args);
                        if (setup_revisions(args.argc, args.argv, &revs, NULL) != 1)
                                BUG("malformed internal diff-index command line");
diff --combined t/t6120-describe.sh
index d639d946965547c86708701bfde276649c568a15,1b8690a7c992e13173fda9d6a45bd36c2d286cce..ee5b03ee18ada34a7b8012d219cbb63c4bb7f256
@@@ -121,9 -121,10 +121,9 @@@ test_expect_success 'describe --contain
        test_cmp expect actual
  '
  
 -: >err.expect
  check_describe tags/A --all A^0
  test_expect_success 'no warning was displayed for A' '
 -      test_cmp err.expect err.actual
 +      test_must_be_empty err.actual
  '
  
  test_expect_success 'rename tag A to Q locally' '
@@@ -143,16 -144,46 +143,46 @@@ test_expect_success 'rename tag Q back 
  test_expect_success 'pack tag refs' 'git pack-refs'
  check_describe A-* HEAD
  
+ test_expect_success 'describe works from outside repo using --git-dir' '
+       git clone --bare "$TRASH_DIRECTORY" "$TRASH_DIRECTORY/bare" &&
+       git --git-dir "$TRASH_DIRECTORY/bare" describe >out &&
+       grep "^A-[1-9][0-9]\?-g[0-9a-f]\+$" out
+ '
  check_describe "A-*[0-9a-f]" --dirty
  
+ test_expect_success 'describe --dirty with --work-tree' '
+       (
+               cd "$TEST_DIRECTORY" &&
+               git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty >"$TRASH_DIRECTORY/out"
+       ) &&
+       grep "^A-[1-9][0-9]\?-g[0-9a-f]\+$" out
+ '
  test_expect_success 'set-up dirty work tree' '
        echo >>file
  '
  
  check_describe "A-*[0-9a-f]-dirty" --dirty
  
+ test_expect_success 'describe --dirty with --work-tree (dirty)' '
+       (
+               cd "$TEST_DIRECTORY" &&
+               git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty >"$TRASH_DIRECTORY/out"
+       ) &&
+       grep "^A-[1-9][0-9]\?-g[0-9a-f]\+-dirty$" out
+ '
  check_describe "A-*[0-9a-f].mod" --dirty=.mod
  
+ test_expect_success 'describe --dirty=.mod with --work-tree (dirty)' '
+       (
+               cd "$TEST_DIRECTORY" &&
+               git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty=.mod >"$TRASH_DIRECTORY/out"
+       ) &&
+       grep "^A-[1-9][0-9]\?-g[0-9a-f]\+.mod$" out
+ '
  test_expect_success 'describe --dirty HEAD' '
        test_must_fail git describe --dirty HEAD
  '
@@@ -303,8 -334,17 +333,17 @@@ test_expect_success 'describe chokes o
        mv .git/modules/sub1/ .git/modules/sub_moved &&
        test_must_fail git describe --dirty
  '
  test_expect_success 'describe ignoring a broken submodule' '
        git describe --broken >out &&
+       grep broken out
+ '
+ test_expect_success 'describe with --work-tree ignoring a broken submodule' '
+       (
+               cd "$TEST_DIRECTORY" &&
+               git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --broken >"$TRASH_DIRECTORY/out"
+       ) &&
        test_when_finished "mv .git/modules/sub_moved .git/modules/sub1" &&
        grep broken out
  '