}
struct warn_if_dangling_data {
+ FILE *fp;
const char *refname;
const char *msg_fmt;
};
if (!resolves_to || strcmp(resolves_to, d->refname))
return 0;
- printf(d->msg_fmt, refname);
+ fprintf(d->fp, d->msg_fmt, refname);
return 0;
}
-void warn_dangling_symref(const char *msg_fmt, const char *refname)
+void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)
{
- struct warn_if_dangling_data data = { refname, msg_fmt };
+ struct warn_if_dangling_data data = { fp, refname, msg_fmt };
for_each_rawref(warn_if_dangling_symref, &data);
}
return ref;
}
+/* The argument to filter_refs */
+struct ref_filter {
+ const char *pattern;
+ each_ref_fn *fn;
+ void *cb_data;
+};
+
int read_ref(const char *ref, unsigned char *sha1)
{
if (resolve_ref(ref, sha1, 1, NULL))
{
if (strncmp(base, entry->name, trim))
return 0;
+ /* Is this a "negative ref" that represents a deleted ref? */
+ if (is_null_sha1(entry->sha1))
+ return 0;
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
- if (is_null_sha1(entry->sha1))
- return 0;
if (!has_sha1_file(entry->sha1)) {
error("%s does not point to a valid object!", entry->name);
return 0;
return fn(entry->name + trim, entry->sha1, entry->flag, cb_data);
}
+static int filter_refs(const char *ref, const unsigned char *sha, int flags,
+ void *data)
+{
+ struct ref_filter *filter = (struct ref_filter *)data;
+ if (fnmatch(filter->pattern, ref, 0))
+ return 0;
+ return filter->fn(ref, sha, flags, filter->cb_data);
+}
+
int peel_ref(const char *ref, unsigned char *sha1)
{
int flag;
return for_each_ref_in("refs/remotes/", fn, cb_data);
}
+int for_each_replace_ref(each_ref_fn fn, void *cb_data)
+{
+ return do_for_each_ref("refs/replace/", fn, 13, 0, cb_data);
+}
+
+int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
+ const char *prefix, void *cb_data)
+{
+ struct strbuf real_pattern = STRBUF_INIT;
+ struct ref_filter filter;
+ const char *has_glob_specials;
+ int ret;
+
+ if (!prefix && prefixcmp(pattern, "refs/"))
+ strbuf_addstr(&real_pattern, "refs/");
+ else if (prefix)
+ strbuf_addstr(&real_pattern, prefix);
+ strbuf_addstr(&real_pattern, pattern);
+
+ has_glob_specials = strpbrk(pattern, "?*[");
+ if (!has_glob_specials) {
+ /* Append impiled '/' '*' if not present. */
+ if (real_pattern.buf[real_pattern.len - 1] != '/')
+ strbuf_addch(&real_pattern, '/');
+ /* No need to check for '*', there is none. */
+ strbuf_addch(&real_pattern, '*');
+ }
+
+ filter.pattern = real_pattern.buf;
+ filter.fn = fn;
+ filter.cb_data = cb_data;
+ ret = for_each_ref(filter_refs, &filter);
+
+ strbuf_release(&real_pattern);
+ return ret;
+}
+
+int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)
+{
+ return for_each_glob_ref_in(fn, pattern, NULL, cb_data);
+}
+
int for_each_rawref(each_ref_fn fn, void *cb_data)
{
return do_for_each_ref("refs/", fn, 0,
strbuf_init(&path, 20);
strbuf_addstr(&path, file);
- result = remove_dir_recursively(&path, 1);
+ result = remove_dir_recursively(&path, REMOVE_DIR_EMPTY_ONLY);
strbuf_release(&path);
* name is a proper prefix of our refname.
*/
if (missing &&
- !is_refname_available(ref, NULL, get_packed_refs(), 0))
+ !is_refname_available(ref, NULL, get_packed_refs(), 0)) {
+ last_errno = ENOTDIR;
goto error_return;
+ }
lock->lk = xcalloc(1, sizeof(struct lock_file));
if (!found)
return 0;
fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0);
- if (fd < 0)
+ if (fd < 0) {
+ unable_to_lock_error(git_path("packed-refs"), errno);
return error("cannot delete '%s' from packed refs", refname);
+ }
for (list = packed_ref_list; list; list = list->next) {
char line[PATH_MAX + 100];
logfile = git_path("logs/%s", ref);
logfd = open(logfile, O_RDONLY, 0);
if (logfd < 0)
- die("Unable to read log %s: %s", logfile, strerror(errno));
+ die_errno("Unable to read log '%s'", logfile);
fstat(logfd, &st);
if (!st.st_size)
die("Log %s is empty.", logfile);
if (fstat(fileno(logfp), &statbuf) ||
statbuf.st_size < ofs ||
fseek(logfp, -ofs, SEEK_END) ||
- fgets(buf, sizeof(buf), logfp))
+ fgets(buf, sizeof(buf), logfp)) {
+ fclose(logfp);
return -1;
+ }
}
while (fgets(buf, sizeof(buf), logfp)) {