completion: offer ctags symbol names for 'git log -S', '-G' and '-L:'
[gitweb.git] / refs.c
diff --git a/refs.c b/refs.c
index 17f3497a0b5b6d82fd78e7f00b1c1834c67c1611..cd36b64ed93f821936fd7ffb68e60ce384119898 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -419,6 +419,13 @@ static char *substitute_branch_name(const char **string, int *len)
 int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
 {
        char *last_branch = substitute_branch_name(&str, &len);
+       int   refs_found  = expand_ref(str, len, sha1, ref);
+       free(last_branch);
+       return refs_found;
+}
+
+int expand_ref(const char *str, int len, unsigned char *sha1, char **ref)
+{
        const char **p, *r;
        int refs_found = 0;
 
@@ -444,7 +451,6 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)
                        warning("ignoring broken ref %s.", fullref);
                }
        }
-       free(last_branch);
        return refs_found;
 }
 
@@ -632,12 +638,17 @@ int copy_reflog_msg(char *buf, const char *msg)
 
 int should_autocreate_reflog(const char *refname)
 {
-       if (!log_all_ref_updates)
+       switch (log_all_ref_updates) {
+       case LOG_REFS_ALWAYS:
+               return 1;
+       case LOG_REFS_NORMAL:
+               return starts_with(refname, "refs/heads/") ||
+                       starts_with(refname, "refs/remotes/") ||
+                       starts_with(refname, "refs/notes/") ||
+                       !strcmp(refname, "HEAD");
+       default:
                return 0;
-       return starts_with(refname, "refs/heads/") ||
-               starts_with(refname, "refs/remotes/") ||
-               starts_with(refname, "refs/notes/") ||
-               !strcmp(refname, "HEAD");
+       }
 }
 
 int is_branch(const char *refname)
@@ -810,8 +821,7 @@ struct ref_update *ref_transaction_add_update(
                hashcpy(update->new_sha1, new_sha1);
        if (flags & REF_HAVE_OLD)
                hashcpy(update->old_sha1, old_sha1);
-       if (msg)
-               update->msg = xstrdup(msg);
+       update->msg = xstrdup_or_null(msg);
        return update;
 }
 
@@ -877,6 +887,14 @@ int ref_transaction_verify(struct ref_transaction *transaction,
                                      flags, NULL, err);
 }
 
+int update_ref_oid(const char *msg, const char *refname,
+              const struct object_id *new_oid, const struct object_id *old_oid,
+              unsigned int flags, enum action_on_err onerr)
+{
+       return update_ref(msg, refname, new_oid ? new_oid->hash : NULL,
+               old_oid ? old_oid->hash : NULL, flags, onerr);
+}
+
 int update_ref(const char *msg, const char *refname,
               const unsigned char *new_sha1, const unsigned char *old_sha1,
               unsigned int flags, enum action_on_err onerr)
@@ -941,7 +959,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(st_add(st_mult(nr_rules, sizeof(char *)), total_len));
+               scanf_fmts = xmalloc(st_add(st_mult(sizeof(char *), nr_rules), total_len));
 
                offset = 0;
                for (i = 0; i < nr_rules; i++) {
@@ -1157,7 +1175,7 @@ static int do_for_each_ref(const char *submodule, const char *prefix,
        if (!refs)
                return 0;
 
-       iter = files_ref_iterator_begin(submodule, prefix, flags);
+       iter = refs->be->iterator_begin(refs, prefix, flags);
        iter = prefix_ref_iterator_begin(iter, prefix, trim);
 
        return do_for_each_ref_iterator(iter, fn, cb_data);
@@ -1251,8 +1269,8 @@ static const char *resolve_ref_recursively(struct ref_store *refs,
        for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
                unsigned int read_flags = 0;
 
-               if (read_raw_ref(refs, refname,
-                                sha1, &sb_refname, &read_flags)) {
+               if (refs->be->read_raw_ref(refs, refname,
+                                          sha1, &sb_refname, &read_flags)) {
                        *flags |= read_flags;
                        if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING))
                                return NULL;
@@ -1292,6 +1310,14 @@ static const char *resolve_ref_recursively(struct ref_store *refs,
        return NULL;
 }
 
+/* backend functions */
+int refs_init_db(struct strbuf *err)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->init_db(refs, err);
+}
+
 const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
                               unsigned char *sha1, int *flags)
 {
@@ -1299,26 +1325,27 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
                                       resolve_flags, sha1, flags);
 }
 
-int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)
+int resolve_gitlink_ref(const char *submodule, const char *refname,
+                       unsigned char *sha1)
 {
-       size_t len = strlen(path);
+       size_t len = strlen(submodule);
        struct ref_store *refs;
        int flags;
 
-       while (len && path[len - 1] == '/')
+       while (len && submodule[len - 1] == '/')
                len--;
 
        if (!len)
                return -1;
 
-       if (path[len]) {
+       if (submodule[len]) {
                /* We need to strip off one or more trailing slashes */
-               char *stripped = xmemdupz(path, len);
+               char *stripped = xmemdupz(submodule, len);
 
                refs = get_ref_store(stripped);
                free(stripped);
        } else {
-               refs = get_ref_store(path);
+               refs = get_ref_store(submodule);
        }
 
        if (!refs)
@@ -1420,6 +1447,29 @@ void assert_main_repository(struct ref_store *refs, const char *caller)
 }
 
 /* backend functions */
+int pack_refs(unsigned int flags)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->pack_refs(refs, flags);
+}
+
+int peel_ref(const char *refname, unsigned char *sha1)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->peel_ref(refs, refname, sha1);
+}
+
+int create_symref(const char *ref_target, const char *refs_heads_master,
+                 const char *logmsg)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->create_symref(refs, ref_target, refs_heads_master,
+                                      logmsg);
+}
+
 int ref_transaction_commit(struct ref_transaction *transaction,
                           struct strbuf *err)
 {
@@ -1427,3 +1477,98 @@ int ref_transaction_commit(struct ref_transaction *transaction,
 
        return refs->be->transaction_commit(refs, transaction, err);
 }
+
+int verify_refname_available(const char *refname,
+                            const struct string_list *extra,
+                            const struct string_list *skip,
+                            struct strbuf *err)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->verify_refname_available(refs, refname, extra, skip, err);
+}
+
+int for_each_reflog(each_ref_fn fn, void *cb_data)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+       struct ref_iterator *iter;
+
+       iter = refs->be->reflog_iterator_begin(refs);
+
+       return do_for_each_ref_iterator(iter, fn, cb_data);
+}
+
+int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
+                               void *cb_data)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->for_each_reflog_ent_reverse(refs, refname,
+                                                    fn, cb_data);
+}
+
+int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
+                       void *cb_data)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->for_each_reflog_ent(refs, refname, fn, cb_data);
+}
+
+int reflog_exists(const char *refname)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->reflog_exists(refs, refname);
+}
+
+int safe_create_reflog(const char *refname, int force_create,
+                      struct strbuf *err)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->create_reflog(refs, refname, force_create, err);
+}
+
+int delete_reflog(const char *refname)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->delete_reflog(refs, refname);
+}
+
+int reflog_expire(const char *refname, const unsigned char *sha1,
+                 unsigned int flags,
+                 reflog_expiry_prepare_fn prepare_fn,
+                 reflog_expiry_should_prune_fn should_prune_fn,
+                 reflog_expiry_cleanup_fn cleanup_fn,
+                 void *policy_cb_data)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->reflog_expire(refs, refname, sha1, flags,
+                                      prepare_fn, should_prune_fn,
+                                      cleanup_fn, policy_cb_data);
+}
+
+int initial_ref_transaction_commit(struct ref_transaction *transaction,
+                                  struct strbuf *err)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->initial_transaction_commit(refs, transaction, err);
+}
+
+int delete_refs(struct string_list *refnames, unsigned int flags)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->delete_refs(refs, refnames, flags);
+}
+
+int rename_ref(const char *oldref, const char *newref, const char *logmsg)
+{
+       struct ref_store *refs = get_ref_store(NULL);
+
+       return refs->be->rename_ref(refs, oldref, newref, logmsg);
+}