Merge branch 'rs/reflog-exists'
authorJunio C Hamano <gitster@pobox.com>
Fri, 6 Jun 2014 18:23:04 +0000 (11:23 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 Jun 2014 18:23:04 +0000 (11:23 -0700)
* rs/reflog-exists:
checkout.c: use ref_exists instead of file_exist
refs.c: add new functions reflog_exists and delete_reflog

builtin/checkout.c
builtin/reflog.c
refs.c
refs.h
t/t1410-reflog.sh
index ff4492162d9543598c1cdc8951f8604a4712516d..f1dc56e55f7b2200412142b10517458ccfda2952 100644 (file)
@@ -651,12 +651,8 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
                        }
                }
                if (old->path && old->name) {
-                       char log_file[PATH_MAX], ref_file[PATH_MAX];
-
-                       git_snpath(log_file, sizeof(log_file), "logs/%s", old->path);
-                       git_snpath(ref_file, sizeof(ref_file), "%s", old->path);
-                       if (!file_exists(ref_file) && file_exists(log_file))
-                               remove_path(log_file);
+                       if (!ref_exists(old->path) && reflog_exists(old->path))
+                               delete_reflog(old->path);
                }
        }
        remove_branch_state();
index c12a9784e6b45d50129b786a45bb5f4e4dd0801a..e8a8fb13b9ffc8d3276048131e33e9874bc3bdea 100644 (file)
@@ -369,7 +369,7 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused,
        if (!lock)
                return error("cannot lock ref '%s'", ref);
        log_file = git_pathdup("logs/%s", ref);
-       if (!file_exists(log_file))
+       if (!reflog_exists(ref))
                goto finish;
        if (!cmd->dry_run) {
                newlog_path = git_pathdup("logs/%s.lock", ref);
diff --git a/refs.c b/refs.c
index 728a76164830368637e95390d95ce3f7c7df659e..68982637ed89a2d679d5e2a9a86e76e6fb56a7b4 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1999,7 +1999,6 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
 
        *log = NULL;
        for (p = ref_rev_parse_rules; *p; p++) {
-               struct stat st;
                unsigned char hash[20];
                char path[PATH_MAX];
                const char *ref, *it;
@@ -2008,12 +2007,9 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log)
                ref = resolve_ref_unsafe(path, hash, 1, NULL);
                if (!ref)
                        continue;
-               if (!stat(git_path("logs/%s", path), &st) &&
-                   S_ISREG(st.st_mode))
+               if (reflog_exists(path))
                        it = path;
-               else if (strcmp(ref, path) &&
-                        !stat(git_path("logs/%s", ref), &st) &&
-                        S_ISREG(st.st_mode))
+               else if (strcmp(ref, path) && reflog_exists(ref))
                        it = ref;
                else
                        continue;
@@ -3046,6 +3042,19 @@ int read_ref_at(const char *refname, unsigned long at_time, int cnt,
        return 1;
 }
 
+int reflog_exists(const char *refname)
+{
+       struct stat st;
+
+       return !lstat(git_path("logs/%s", refname), &st) &&
+               S_ISREG(st.st_mode);
+}
+
+int delete_reflog(const char *refname)
+{
+       return remove_path(git_path("logs/%s", refname));
+}
+
 static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data)
 {
        unsigned char osha1[20], nsha1[20];
diff --git a/refs.h b/refs.h
index 0f08def21020a166902de169dd46c63c85fdfd0e..09ff483c19ec9484359864640da86f9a40418ecc 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -161,6 +161,12 @@ extern int read_ref_at(const char *refname, unsigned long at_time, int cnt,
                       unsigned char *sha1, char **msg,
                       unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt);
 
+/** Check if a particular reflog exists */
+extern int reflog_exists(const char *refname);
+
+/** Delete a reflog */
+extern int delete_reflog(const char *refname);
+
 /* iterate over reflog entries */
 typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *);
 int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data);
index 236b13a3ab27f54808fa88574738747e3c3936b1..8cab06f90a52b82518aca6f7baa0530eb77ab986 100755 (executable)
@@ -245,4 +245,12 @@ test_expect_success 'gc.reflogexpire=false' '
 
 '
 
+test_expect_success 'checkout should not delete log for packed ref' '
+       test $(git reflog master | wc -l) = 4 &&
+       git branch foo &&
+       git pack-refs --all &&
+       git checkout foo &&
+       test $(git reflog master | wc -l) = 4
+'
+
 test_done