diff options
author | Nicolas Pitre <nico@cam.org> | 2007-02-03 13:25:43 -0500 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2007-02-03 11:57:18 -0800 |
commit | eb8381c88518b10d683a29deea1d43ed671f14ec (patch) | |
tree | a9523ae68d874de91032c1ed3be92de168a2f73c /refs.c | |
parent | a7e4fbf990290f955da1319ab605a59f85d3c3e2 (diff) | |
download | git-eb8381c88518b10d683a29deea1d43ed671f14ec.tar.gz |
scan reflogs independently from refs
Currently, the search for all reflogs depends on the existence of
corresponding refs under the .git/refs/ directory. Let's scan the
.git/logs/ directory directly instead.
Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -1201,3 +1201,53 @@ int for_each_reflog_ent(const char *ref, each_reflog_ent_fn fn, void *cb_data) return ret; } +static int do_for_each_reflog(const char *base, each_ref_fn fn, void *cb_data) +{ + DIR *dir = opendir(git_path("logs/%s", base)); + int retval = errno; + + if (dir) { + struct dirent *de; + int baselen = strlen(base); + char *log = xmalloc(baselen + 257); + + memcpy(log, base, baselen); + if (baselen && base[baselen-1] != '/') + log[baselen++] = '/'; + + while ((de = readdir(dir)) != NULL) { + struct stat st; + int namelen; + + if (de->d_name[0] == '.') + continue; + namelen = strlen(de->d_name); + if (namelen > 255) + continue; + if (has_extension(de->d_name, ".lock")) + continue; + memcpy(log + baselen, de->d_name, namelen+1); + if (stat(git_path("logs/%s", log), &st) < 0) + continue; + if (S_ISDIR(st.st_mode)) { + retval = do_for_each_reflog(log, fn, cb_data); + } else { + unsigned char sha1[20]; + if (!resolve_ref(log, sha1, 0, NULL)) + retval = error("bad ref for %s", log); + else + retval = fn(log, sha1, 0, cb_data); + } + if (retval) + break; + } + free(log); + closedir(dir); + } + return retval; +} + +int for_each_reflog(each_ref_fn fn, void *cb_data) +{ + return do_for_each_reflog("", fn, cb_data); +} |