]> git.ipfire.org Git - thirdparty/git.git/blobdiff - refs.c
show_head_ref(): check the result of resolve_ref_namespace()
[thirdparty/git.git] / refs.c
diff --git a/refs.c b/refs.c
index e2d34b253e4c9c4efcb30e88d11ccd3ce9e14deb..f0feff72da087d2986edb2d7d52e61eb7e47b7f3 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -124,7 +124,7 @@ int refname_is_safe(const char *refname)
                char *buf;
                int result;
 
-               buf = xmalloc(strlen(refname) + 1);
+               buf = xmallocz(strlen(refname));
                /*
                 * Does the refname try to escape refs/?
                 * For example: refs/foo/../bar is safe but refs/foo/../../bar
@@ -761,10 +761,8 @@ void ref_transaction_free(struct ref_transaction *transaction)
 static struct ref_update *add_update(struct ref_transaction *transaction,
                                     const char *refname)
 {
-       size_t len = strlen(refname) + 1;
-       struct ref_update *update = xcalloc(1, sizeof(*update) + len);
-
-       memcpy((char *)update->refname, refname, len); /* includes NUL */
+       struct ref_update *update;
+       FLEX_ALLOC_STR(update, refname, refname);
        ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
        transaction->updates[transaction->nr++] = update;
        return update;
@@ -908,7 +906,7 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
                        /* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */
                        total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;
 
-               scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);
+               scanf_fmts = xmalloc(st_add(st_mult(nr_rules, sizeof(char *)), total_len));
 
                offset = 0;
                for (i = 0; i < nr_rules; i++) {
@@ -1082,3 +1080,78 @@ int rename_ref_available(const char *oldname, const char *newname)
        strbuf_release(&err);
        return ret;
 }
+
+int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
+{
+       struct object_id oid;
+       int flag;
+
+       if (submodule) {
+               if (resolve_gitlink_ref(submodule, "HEAD", oid.hash) == 0)
+                       return fn("HEAD", &oid, 0, cb_data);
+
+               return 0;
+       }
+
+       if (!read_ref_full("HEAD", RESOLVE_REF_READING, oid.hash, &flag))
+               return fn("HEAD", &oid, flag, cb_data);
+
+       return 0;
+}
+
+int head_ref(each_ref_fn fn, void *cb_data)
+{
+       return head_ref_submodule(NULL, fn, cb_data);
+}
+
+int for_each_ref(each_ref_fn fn, void *cb_data)
+{
+       return do_for_each_ref(NULL, "", fn, 0, 0, cb_data);
+}
+
+int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
+{
+       return do_for_each_ref(submodule, "", fn, 0, 0, cb_data);
+}
+
+int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
+{
+       return do_for_each_ref(NULL, prefix, fn, strlen(prefix), 0, cb_data);
+}
+
+int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
+{
+       unsigned int flag = 0;
+
+       if (broken)
+               flag = DO_FOR_EACH_INCLUDE_BROKEN;
+       return do_for_each_ref(NULL, prefix, fn, 0, flag, cb_data);
+}
+
+int for_each_ref_in_submodule(const char *submodule, const char *prefix,
+               each_ref_fn fn, void *cb_data)
+{
+       return do_for_each_ref(submodule, prefix, fn, strlen(prefix), 0, cb_data);
+}
+
+int for_each_replace_ref(each_ref_fn fn, void *cb_data)
+{
+       return do_for_each_ref(NULL, git_replace_ref_base, fn,
+                              strlen(git_replace_ref_base), 0, cb_data);
+}
+
+int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
+{
+       struct strbuf buf = STRBUF_INIT;
+       int ret;
+       strbuf_addf(&buf, "%srefs/", get_git_namespace());
+       ret = do_for_each_ref(NULL, buf.buf, fn, 0, 0, cb_data);
+       strbuf_release(&buf);
+       return ret;
+}
+
+int for_each_rawref(each_ref_fn fn, void *cb_data)
+{
+       return do_for_each_ref(NULL, "", fn, 0,
+                              DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
+}