{"thread":{"id":"37345","subject":"[PATCH v2 02/23] refs-common.c: create a file to host all common refs code","startedAt":"2014-08-13T20:14:44Z","lastAt":"2014-08-26T22:11:45Z","messageCount":27,"participants":["Ronnie Sahlberg","Junio C Hamano"],"isPatch":true,"patchVersion":2,"patchTotal":23},"messages":[{"id":"247687","messageId":"1407960907-18189-1-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":null,"subject":"[PATCH v2 00/23] backend-struct-db","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:44Z","receivedAt":"2014-08-13T20:14:44Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"List, please review\n\nThis series is called backend-struct-db and is also available at\nhttps://github.com/rsahlberg/git/tree/backend-struct-db\n\nThis series is built on and follows after the series\nref-transactions-send-pack\n\n\nThis series does not change any logic or behaviour but mainly just shuffles\ncode around and adds method pointers for the backend functions.\n\nThe first patch adds a new public function for checking if a refname is\navailable or not. This function is needed not because we want to have\ndifferent is_refname_available semantics for different backends, we don't,\nbut because its implementation is quite dependant on the backend type.\n\n15 of the patches, the refs-common.c patches, focuses on moving all backend\nagnostic refs functions to a common file. This file will contain all\nbackend agnostic refs functions.\n\nThe last 6 patches adds a backend structure with the methods we need to\ndescribe a pluggable backend. Currently we only have one built in backend,\nthe current files based backend. These patches do not change any of the\nbehavior other than that we now call the methods through backend specific\nwrapper functions rather than calling them directly.\n\n\nAt this stage we now have a defined set of methods needed for a refs\nbackend and we can start building and adding new types of ref backends\nto git.\n\n\nVersion 2:\n- Do not use C99 style initializers as suggested by David Turner.\n- Make head_ref_namespaced a common function instead of a backend function\n\n\nRonnie Sahlberg (23):\n  refs.c: create a public function for is_refname_available\n  refs-common.c: create a file to host all common refs code\n  refs-common.c: move update_ref to refs-common.c\n  refs-common.c: move delete_ref to the common code\n  refs-common.c: move rename_ref to the common code\n  refs-common.c: move read_ref_at to the refs common file\n  refs-common.c: move the hidden refs functions to the common code\n  refs-common.c: move dwim and friend functions to refs common\n  refs-common.c: move warn_if_dangling_symref* to refs-common\n  refs-common.c: move read_ref, read_ref_full and ref_exists to common\n  refs-common.c: move resolve_refdup to common\n  refs-common.c: move check_refname_component to the common code\n  refs-common.c: move is_branch to the common code\n  refs-common.c: move names_conflict to the common code\n  refs-common.c: move prettify_refname to the common code\n  refs-common.c: move ref iterators to the common code\n  refs-common.c: move head_ref_namespaced to the common file\n  refs.c: add a backend method structure with transaction functions\n  refs.c: add reflog backend methods\n  refs.c: add methods for misc ref operations\n  refs.c: add methods for head_ref*\n  refs.c: add methods for the ref iterators\n  refs-be-files.c: rename refs.c to refs-be-files.c\n\n Makefile        |    3 +-\n refs-be-files.c | 3323 ++++++++++++++++++++++++++++++++++++++++++++\n refs-common.c   |  966 +++++++++++++\n refs.c          | 4082 -------------------------------------------------------\n refs.h          |  111 ++\n 5 files changed, 4402 insertions(+), 4083 deletions(-)\n create mode 100644 refs-be-files.c\n create mode 100644 refs-common.c\n delete mode 100644 refs.c\n\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247700","messageId":"1407960907-18189-2-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 01/23] refs.c: create a public function for is_refname_available","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:45Z","receivedAt":"2014-08-13T20:14:45Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Export a generic is_refname_available() function. We will need this\nas a public shared function later when we add additional refs backends\nsince we want to keep using the same rules for ref naming across\nall backends.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs.c | 29 ++++++++++++++++++-----------\n refs.h |  6 ++++++\n 2 files changed, 24 insertions(+), 11 deletions(-)\n\ndiff --git a/refs.c b/refs.c\nindex 7e13c0f..4a22513 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -830,9 +830,9 @@ static int name_conflict_fn(struct ref_entry *entry, void *cb_data)\n  * operation). skip contains a list of refs we want to skip checking for\n  * conflicts with.\n  */\n-static int is_refname_available(const char *refname,\n-\t\t\t\tstruct ref_dir *dir,\n-\t\t\t\tconst char **skip, int skipnum)\n+static int is_refname_available_dir(const char *refname,\n+\t\t\t\t    struct ref_dir *dir,\n+\t\t\t\t    const char **skip, int skipnum)\n {\n \tstruct name_conflict_cb data;\n \tdata.refname = refname;\n@@ -1238,6 +1238,18 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs)\n \treturn get_ref_dir(refs->loose);\n }\n \n+int is_refname_available(const char *refname, const char **skip, int skipnum)\n+{\n+\tif (!is_refname_available_dir(refname, get_packed_refs(&ref_cache),\n+\t\t\t\t      skip, skipnum))\n+\t\treturn 0;\n+\n+\tif (!is_refname_available_dir(refname, get_loose_refs(&ref_cache),\n+\t\t\t\t      skip, skipnum))\n+\t\treturn 0;\n+\treturn 1;\n+}\n+\n /* We allow \"recursive\" symbolic refs. Only within reason, though */\n #define MAXDEPTH 5\n #define MAXREFLEN (1024)\n@@ -2168,8 +2180,8 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname,\n \t * name is a proper prefix of our refname.\n \t */\n \tif (missing &&\n-\t     !is_refname_available(refname, get_packed_refs(&ref_cache),\n-\t\t\t\t   skip, skipnum)) {\n+\t     !is_refname_available_dir(refname, get_packed_refs(&ref_cache),\n+\t\t\t\t       skip, skipnum)) {\n \t\tlast_errno = ENOTDIR;\n \t\tgoto error_return;\n \t}\n@@ -2676,12 +2688,7 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms\n \t\treturn 1;\n \t}\n \n-\tif (!is_refname_available(newrefname, get_packed_refs(&ref_cache),\n-\t\t\t\t  &oldrefname, 1))\n-\t\treturn 1;\n-\n-\tif (!is_refname_available(newrefname, get_loose_refs(&ref_cache),\n-\t\t\t\t  &oldrefname, 1))\n+\tif (!is_refname_available(newrefname, &oldrefname, 1))\n \t\treturn 1;\n \n \tlog = reflog_exists(oldrefname);\ndiff --git a/refs.h b/refs.h\nindex f44b5c8..d526da0 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -131,6 +131,12 @@ extern int ref_exists(const char *);\n extern int is_branch(const char *refname);\n \n /*\n+ * Check that a particular refname is available for creation. skip contains\n+ * a list of refnames to exclude from the refname collision tests.\n+ */\n+int is_refname_available(const char *refname, const char **skip, int skipnum);\n+\n+/*\n  * If refname is a non-symbolic reference that refers to a tag object,\n  * and the tag can be (recursively) dereferenced to a non-tag object,\n  * store the SHA1 of the referred-to object to sha1 and return 0.  If\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247685","messageId":"1407960907-18189-3-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 02/23] refs-common.c: create a file to host all common refs code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:46Z","receivedAt":"2014-08-13T20:14:46Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Create refs-common.c which will hold all backend agnostic refs code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n Makefile      | 1 +\n refs-common.c | 2 ++\n 2 files changed, 3 insertions(+)\n create mode 100644 refs-common.c\n\ndiff --git a/Makefile b/Makefile\nindex 07ea105..7705136 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -858,6 +858,7 @@ LIB_OBJS += reachable.o\n LIB_OBJS += read-cache.o\n LIB_OBJS += reflog-walk.o\n LIB_OBJS += refs.o\n+LIB_OBJS += refs-common.o\n LIB_OBJS += remote.o\n LIB_OBJS += replace_object.o\n LIB_OBJS += rerere.o\ndiff --git a/refs-common.c b/refs-common.c\nnew file mode 100644\nindex 0000000..44d96d2\n--- /dev/null\n+++ b/refs-common.c\n@@ -0,0 +1,2 @@\n+/* common code for all ref backends */\n+\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247703","messageId":"1407960907-18189-4-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 03/23] refs-common.c: move update_ref to refs-common.c","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:47Z","receivedAt":"2014-08-13T20:14:47Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"This change moves update_ref() to the refs-common.c file since this function\ndoes not contain any backend specific code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 25 +++++++++++++++++++++++++\n refs.c        | 23 -----------------------\n 2 files changed, 25 insertions(+), 23 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 44d96d2..cb884b2 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -1,2 +1,27 @@\n /* common code for all ref backends */\n+#include \"cache.h\"\n+#include \"refs.h\"\n+\n+int update_ref(const char *action, const char *refname,\n+\t       const unsigned char *sha1, const unsigned char *oldval,\n+\t       int flags, struct strbuf *e)\n+{\n+\tstruct ref_transaction *t;\n+\tstruct strbuf err = STRBUF_INIT;\n+\n+\tt = transaction_begin(&err);\n+\tif (!t ||\n+\t    transaction_update_sha1(t, refname, sha1, oldval, flags,\n+\t\t\t\t    !!oldval, action, &err) ||\n+\t    transaction_commit(t, &err)) {\n+\t\tconst char *str = \"update_ref failed for ref '%s': %s\";\n+\n+\t\ttransaction_free(t);\n+\t\tif (e)\n+\t\t\tstrbuf_addf(e, str, refname, err.buf);\n+\t\tstrbuf_release(&err);\n+\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\n \ndiff --git a/refs.c b/refs.c\nindex 4a22513..eb66cf7 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -3576,29 +3576,6 @@ int transaction_delete_sha1(struct ref_transaction *transaction,\n \t\t\t\t      old_sha1, flags, have_old, msg, err);\n }\n \n-int update_ref(const char *action, const char *refname,\n-\t       const unsigned char *sha1, const unsigned char *oldval,\n-\t       int flags, struct strbuf *e)\n-{\n-\tstruct ref_transaction *t;\n-\tstruct strbuf err = STRBUF_INIT;\n-\n-\tt = transaction_begin(&err);\n-\tif (!t ||\n-\t    transaction_update_sha1(t, refname, sha1, oldval, flags,\n-\t\t\t\t    !!oldval, action, &err) ||\n-\t    transaction_commit(t, &err)) {\n-\t\tconst char *str = \"update_ref failed for ref '%s': %s\";\n-\n-\t\ttransaction_free(t);\n-\t\tif (e)\n-\t\t\tstrbuf_addf(e, str, refname, err.buf);\n-\t\tstrbuf_release(&err);\n-\t\treturn 1;\n-\t}\n-\treturn 0;\n-}\n-\n static int ref_update_compare(const void *r1, const void *r2)\n {\n \tconst struct ref_update * const *u1 = r1;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247686","messageId":"1407960907-18189-5-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 04/23] refs-common.c: move delete_ref to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:48Z","receivedAt":"2014-08-13T20:14:48Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"This change moves delete_ref() to the refs-common.c file since this function\ndoes not contain any backend specific code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 18 ++++++++++++++++++\n refs.c        | 19 -------------------\n 2 files changed, 18 insertions(+), 19 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex cb884b2..71ad358 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -25,3 +25,21 @@ int update_ref(const char *action, const char *refname,\n \treturn 0;\n }\n \n+int delete_ref(const char *refname, const unsigned char *sha1, int delopt)\n+{\n+\tstruct ref_transaction *transaction;\n+\tstruct strbuf err = STRBUF_INIT;\n+\n+\ttransaction = transaction_begin(&err);\n+\tif (!transaction ||\n+\t    transaction_delete_sha1(transaction, refname, sha1, delopt,\n+\t\t\t\t    sha1 && !is_null_sha1(sha1), NULL, &err) ||\n+\t    transaction_commit(transaction, &err)) {\n+\t\terror(\"%s\", err.buf);\n+\t\ttransaction_free(transaction);\n+\t\tstrbuf_release(&err);\n+\t\treturn 1;\n+\t}\n+\ttransaction_free(transaction);\n+\treturn 0;\n+}\ndiff --git a/refs.c b/refs.c\nindex eb66cf7..faf794c 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2622,25 +2622,6 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err)\n \treturn 0;\n }\n \n-int delete_ref(const char *refname, const unsigned char *sha1, int delopt)\n-{\n-\tstruct ref_transaction *transaction;\n-\tstruct strbuf err = STRBUF_INIT;\n-\n-\ttransaction = transaction_begin(&err);\n-\tif (!transaction ||\n-\t    transaction_delete_sha1(transaction, refname, sha1, delopt,\n-\t\t\t\t    sha1 && !is_null_sha1(sha1), NULL, &err) ||\n-\t    transaction_commit(transaction, &err)) {\n-\t\terror(\"%s\", err.buf);\n-\t\ttransaction_free(transaction);\n-\t\tstrbuf_release(&err);\n-\t\treturn 1;\n-\t}\n-\ttransaction_free(transaction);\n-\treturn 0;\n-}\n-\n struct rename_reflog_cb {\n \tstruct ref_transaction *transaction;\n \tconst char *refname;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247690","messageId":"1407960907-18189-6-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 05/23] refs-common.c: move rename_ref to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:49Z","receivedAt":"2014-08-13T20:14:49Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"This change moves rename_ref() to the refs-common.c file since this function\ndoes not contain any backend specific code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 92 -----------------------------------------------------------\n 2 files changed, 92 insertions(+), 92 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 71ad358..f99d83e 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -43,3 +43,95 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)\n \ttransaction_free(transaction);\n \treturn 0;\n }\n+\n+struct rename_reflog_cb {\n+\tstruct ref_transaction *transaction;\n+\tconst char *refname;\n+\tstruct strbuf *err;\n+};\n+\n+static int rename_reflog_ent(unsigned char *osha1, unsigned char *nsha1,\n+\t\t\t     const char *id, unsigned long timestamp, int tz,\n+\t\t\t     const char *message, void *cb_data)\n+{\n+\tstruct rename_reflog_cb *cb = cb_data;\n+\tstruct reflog_committer_info ci;\n+\n+\tmemset(&ci, 0, sizeof(ci));\n+\tci.id = id;\n+\tci.timestamp = timestamp;\n+\tci.tz = tz;\n+\treturn transaction_update_reflog(cb->transaction, cb->refname,\n+\t\t\t\t\t nsha1, osha1, &ci, message, 0,\n+\t\t\t\t\t cb->err);\n+}\n+\n+int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg)\n+{\n+\tunsigned char sha1[20];\n+\tint flag = 0, log;\n+\tstruct ref_transaction *transaction = NULL;\n+\tstruct strbuf err = STRBUF_INIT;\n+\tconst char *symref = NULL;\n+\tstruct rename_reflog_cb cb;\n+\tstruct reflog_committer_info ci;\n+\n+\tmemset(&ci, 0, sizeof(ci));\n+\tci.committer_info = git_committer_info(0);\n+\n+\tsymref = resolve_ref_unsafe(oldrefname, sha1,\n+\t\t\t\t    RESOLVE_REF_READING, &flag);\n+\tif (flag & REF_ISSYMREF) {\n+\t\terror(\"refname %s is a symbolic ref, renaming it is not supported\",\n+\t\t\toldrefname);\n+\t\treturn 1;\n+\t}\n+\tif (!symref) {\n+\t\terror(\"refname %s not found\", oldrefname);\n+\t\treturn 1;\n+\t}\n+\n+\tif (!is_refname_available(newrefname, &oldrefname, 1))\n+\t\treturn 1;\n+\n+\tlog = reflog_exists(oldrefname);\n+\ttransaction = transaction_begin(&err);\n+\tif (!transaction)\n+\t\tgoto fail;\n+\n+\tif (strcmp(oldrefname, newrefname)) {\n+\t\tif (log && transaction_update_reflog(transaction, newrefname,\n+\t\t\t\t\t\t     sha1, sha1, &ci, NULL,\n+\t\t\t\t\t\t     REFLOG_TRUNCATE, &err))\n+\t\t\tgoto fail;\n+\t\tcb.transaction = transaction;\n+\t\tcb.refname = newrefname;\n+\t\tcb.err = &err;\n+\t\tif (log && for_each_reflog_ent(oldrefname, rename_reflog_ent,\n+\t\t\t\t\t       &cb))\n+\t\t\tgoto fail;\n+\n+\t\tif (transaction_delete_sha1(transaction, oldrefname, sha1,\n+\t\t\t\t\t    REF_NODEREF,\n+\t\t\t\t\t    1, NULL, &err))\n+\t\t\tgoto fail;\n+\t}\n+\tif (transaction_update_sha1(transaction, newrefname, sha1,\n+\t\t\t\t    NULL, 0, 0, NULL, &err))\n+\t\tgoto fail;\n+\tif (log && transaction_update_reflog(transaction, newrefname, sha1,\n+\t\t\t\t\t     sha1, &ci, logmsg,\n+\t\t\t\t\t     REFLOG_COMMITTER_INFO_IS_VALID,\n+\t\t\t\t\t     &err))\n+\t\tgoto fail;\n+\tif (transaction_commit(transaction, &err))\n+\t\tgoto fail;\n+\ttransaction_free(transaction);\n+\treturn 0;\n+\n+ fail:\n+\terror(\"rename_ref failed: %s\", err.buf);\n+\tstrbuf_release(&err);\n+\ttransaction_free(transaction);\n+\treturn 1;\n+}\ndiff --git a/refs.c b/refs.c\nindex faf794c..7d579be 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2622,98 +2622,6 @@ static int delete_ref_loose(struct ref_lock *lock, int flag, struct strbuf *err)\n \treturn 0;\n }\n \n-struct rename_reflog_cb {\n-\tstruct ref_transaction *transaction;\n-\tconst char *refname;\n-\tstruct strbuf *err;\n-};\n-\n-static int rename_reflog_ent(unsigned char *osha1, unsigned char *nsha1,\n-\t\t\t     const char *id, unsigned long timestamp, int tz,\n-\t\t\t     const char *message, void *cb_data)\n-{\n-\tstruct rename_reflog_cb *cb = cb_data;\n-\tstruct reflog_committer_info ci;\n-\n-\tmemset(&ci, 0, sizeof(ci));\n-\tci.id = id;\n-\tci.timestamp = timestamp;\n-\tci.tz = tz;\n-\treturn transaction_update_reflog(cb->transaction, cb->refname,\n-\t\t\t\t\t nsha1, osha1, &ci, message, 0,\n-\t\t\t\t\t cb->err);\n-}\n-\n-int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg)\n-{\n-\tunsigned char sha1[20];\n-\tint flag = 0, log;\n-\tstruct ref_transaction *transaction = NULL;\n-\tstruct strbuf err = STRBUF_INIT;\n-\tconst char *symref = NULL;\n-\tstruct rename_reflog_cb cb;\n-\tstruct reflog_committer_info ci;\n-\n-\tmemset(&ci, 0, sizeof(ci));\n-\tci.committer_info = git_committer_info(0);\n-\n-\tsymref = resolve_ref_unsafe(oldrefname, sha1,\n-\t\t\t\t    RESOLVE_REF_READING, &flag);\n-\tif (flag & REF_ISSYMREF) {\n-\t\terror(\"refname %s is a symbolic ref, renaming it is not supported\",\n-\t\t\toldrefname);\n-\t\treturn 1;\n-\t}\n-\tif (!symref) {\n-\t\terror(\"refname %s not found\", oldrefname);\n-\t\treturn 1;\n-\t}\n-\n-\tif (!is_refname_available(newrefname, &oldrefname, 1))\n-\t\treturn 1;\n-\n-\tlog = reflog_exists(oldrefname);\n-\ttransaction = transaction_begin(&err);\n-\tif (!transaction)\n-\t\tgoto fail;\n-\n-\tif (strcmp(oldrefname, newrefname)) {\n-\t\tif (log && transaction_update_reflog(transaction, newrefname,\n-\t\t\t\t\t\t     sha1, sha1, &ci, NULL,\n-\t\t\t\t\t\t     REFLOG_TRUNCATE, &err))\n-\t\t\tgoto fail;\n-\t\tcb.transaction = transaction;\n-\t\tcb.refname = newrefname;\n-\t\tcb.err = &err;\n-\t\tif (log && for_each_reflog_ent(oldrefname, rename_reflog_ent,\n-\t\t\t\t\t       &cb))\n-\t\t\tgoto fail;\n-\n-\t\tif (transaction_delete_sha1(transaction, oldrefname, sha1,\n-\t\t\t\t\t    REF_NODEREF,\n-\t\t\t\t\t    1, NULL, &err))\n-\t\t\tgoto fail;\n-\t}\n-\tif (transaction_update_sha1(transaction, newrefname, sha1,\n-\t\t\t\t    NULL, 0, 0, NULL, &err))\n-\t\tgoto fail;\n-\tif (log && transaction_update_reflog(transaction, newrefname, sha1,\n-\t\t\t\t\t     sha1, &ci, logmsg,\n-\t\t\t\t\t     REFLOG_COMMITTER_INFO_IS_VALID,\n-\t\t\t\t\t     &err))\n-\t\tgoto fail;\n-\tif (transaction_commit(transaction, &err))\n-\t\tgoto fail;\n-\ttransaction_free(transaction);\n-\treturn 0;\n-\n- fail:\n-\terror(\"rename_ref failed: %s\", err.buf);\n-\tstrbuf_release(&err);\n-\ttransaction_free(transaction);\n-\treturn 1;\n-}\n-\n static int close_ref(struct ref_lock *lock)\n {\n \tif (close_lock_file(lock->lk))\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247704","messageId":"1407960907-18189-7-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 06/23] refs-common.c: move read_ref_at to the refs common file","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:50Z","receivedAt":"2014-08-13T20:14:50Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"This change moves read_ref_at() to the refs-common.c file since this function\ndoes not contain any backend specific code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 114 ----------------------------------------------------------\n 2 files changed, 114 insertions(+), 114 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex f99d83e..3d7354e 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -135,3 +135,117 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms\n \ttransaction_free(transaction);\n \treturn 1;\n }\n+\n+struct read_ref_at_cb {\n+\tconst char *refname;\n+\tunsigned long at_time;\n+\tint cnt;\n+\tint reccnt;\n+\tunsigned char *sha1;\n+\tint found_it;\n+\n+\tunsigned char osha1[20];\n+\tunsigned char nsha1[20];\n+\tint tz;\n+\tunsigned long date;\n+\tchar **msg;\n+\tunsigned long *cutoff_time;\n+\tint *cutoff_tz;\n+\tint *cutoff_cnt;\n+};\n+\n+static int read_ref_at_ent(unsigned char *osha1, unsigned char *nsha1,\n+\t\tconst char *id, unsigned long timestamp, int tz,\n+\t\tconst char *message, void *cb_data)\n+{\n+\tstruct read_ref_at_cb *cb = cb_data;\n+\n+\tcb->reccnt++;\n+\tcb->tz = tz;\n+\tcb->date = timestamp;\n+\n+\tif (timestamp <= cb->at_time || cb->cnt == 0) {\n+\t\tif (cb->msg)\n+\t\t\t*cb->msg = xstrdup(message);\n+\t\tif (cb->cutoff_time)\n+\t\t\t*cb->cutoff_time = timestamp;\n+\t\tif (cb->cutoff_tz)\n+\t\t\t*cb->cutoff_tz = tz;\n+\t\tif (cb->cutoff_cnt)\n+\t\t\t*cb->cutoff_cnt = cb->reccnt - 1;\n+\t\t/*\n+\t\t * we have not yet updated cb->[n|o]sha1 so they still\n+\t\t * hold the values for the previous record.\n+\t\t */\n+\t\tif (!is_null_sha1(cb->osha1)) {\n+\t\t\thashcpy(cb->sha1, nsha1);\n+\t\t\tif (hashcmp(cb->osha1, nsha1))\n+\t\t\t\twarning(\"Log for ref %s has gap after %s.\",\n+\t\t\t\t\tcb->refname, show_date(cb->date, cb->tz, DATE_RFC2822));\n+\t\t}\n+\t\telse if (cb->date == cb->at_time)\n+\t\t\thashcpy(cb->sha1, nsha1);\n+\t\telse if (hashcmp(nsha1, cb->sha1))\n+\t\t\twarning(\"Log for ref %s unexpectedly ended on %s.\",\n+\t\t\t\tcb->refname, show_date(cb->date, cb->tz,\n+\t\t\t\t\t\t   DATE_RFC2822));\n+\t\thashcpy(cb->osha1, osha1);\n+\t\thashcpy(cb->nsha1, nsha1);\n+\t\tcb->found_it = 1;\n+\t\treturn 1;\n+\t}\n+\thashcpy(cb->osha1, osha1);\n+\thashcpy(cb->nsha1, nsha1);\n+\tif (cb->cnt > 0)\n+\t\tcb->cnt--;\n+\treturn 0;\n+}\n+\n+static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1,\n+\t\t\t\t  const char *id, unsigned long timestamp,\n+\t\t\t\t  int tz, const char *message, void *cb_data)\n+{\n+\tstruct read_ref_at_cb *cb = cb_data;\n+\n+\tif (cb->msg)\n+\t\t*cb->msg = xstrdup(message);\n+\tif (cb->cutoff_time)\n+\t\t*cb->cutoff_time = timestamp;\n+\tif (cb->cutoff_tz)\n+\t\t*cb->cutoff_tz = tz;\n+\tif (cb->cutoff_cnt)\n+\t\t*cb->cutoff_cnt = cb->reccnt;\n+\thashcpy(cb->sha1, osha1);\n+\tif (is_null_sha1(cb->sha1))\n+\t\thashcpy(cb->sha1, nsha1);\n+\t/* We just want the first entry */\n+\treturn 1;\n+}\n+\n+int read_ref_at(const char *refname, unsigned long at_time, int cnt,\n+\t\tunsigned char *sha1, char **msg,\n+\t\tunsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)\n+{\n+\tstruct read_ref_at_cb cb;\n+\n+\tmemset(&cb, 0, sizeof(cb));\n+\tcb.refname = refname;\n+\tcb.at_time = at_time;\n+\tcb.cnt = cnt;\n+\tcb.msg = msg;\n+\tcb.cutoff_time = cutoff_time;\n+\tcb.cutoff_tz = cutoff_tz;\n+\tcb.cutoff_cnt = cutoff_cnt;\n+\tcb.sha1 = sha1;\n+\n+\tfor_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);\n+\n+\tif (!cb.reccnt)\n+\t\tdie(\"Log for %s is empty.\", refname);\n+\tif (cb.found_it)\n+\t\treturn 0;\n+\n+\tfor_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb);\n+\n+\treturn 1;\n+}\ndiff --git a/refs.c b/refs.c\nindex 7d579be..52ca0bb 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2935,120 +2935,6 @@ int create_symref(const char *ref_target, const char *refs_heads_master,\n \treturn 0;\n }\n \n-struct read_ref_at_cb {\n-\tconst char *refname;\n-\tunsigned long at_time;\n-\tint cnt;\n-\tint reccnt;\n-\tunsigned char *sha1;\n-\tint found_it;\n-\n-\tunsigned char osha1[20];\n-\tunsigned char nsha1[20];\n-\tint tz;\n-\tunsigned long date;\n-\tchar **msg;\n-\tunsigned long *cutoff_time;\n-\tint *cutoff_tz;\n-\tint *cutoff_cnt;\n-};\n-\n-static int read_ref_at_ent(unsigned char *osha1, unsigned char *nsha1,\n-\t\tconst char *id, unsigned long timestamp, int tz,\n-\t\tconst char *message, void *cb_data)\n-{\n-\tstruct read_ref_at_cb *cb = cb_data;\n-\n-\tcb->reccnt++;\n-\tcb->tz = tz;\n-\tcb->date = timestamp;\n-\n-\tif (timestamp <= cb->at_time || cb->cnt == 0) {\n-\t\tif (cb->msg)\n-\t\t\t*cb->msg = xstrdup(message);\n-\t\tif (cb->cutoff_time)\n-\t\t\t*cb->cutoff_time = timestamp;\n-\t\tif (cb->cutoff_tz)\n-\t\t\t*cb->cutoff_tz = tz;\n-\t\tif (cb->cutoff_cnt)\n-\t\t\t*cb->cutoff_cnt = cb->reccnt - 1;\n-\t\t/*\n-\t\t * we have not yet updated cb->[n|o]sha1 so they still\n-\t\t * hold the values for the previous record.\n-\t\t */\n-\t\tif (!is_null_sha1(cb->osha1)) {\n-\t\t\thashcpy(cb->sha1, nsha1);\n-\t\t\tif (hashcmp(cb->osha1, nsha1))\n-\t\t\t\twarning(\"Log for ref %s has gap after %s.\",\n-\t\t\t\t\tcb->refname, show_date(cb->date, cb->tz, DATE_RFC2822));\n-\t\t}\n-\t\telse if (cb->date == cb->at_time)\n-\t\t\thashcpy(cb->sha1, nsha1);\n-\t\telse if (hashcmp(nsha1, cb->sha1))\n-\t\t\twarning(\"Log for ref %s unexpectedly ended on %s.\",\n-\t\t\t\tcb->refname, show_date(cb->date, cb->tz,\n-\t\t\t\t\t\t   DATE_RFC2822));\n-\t\thashcpy(cb->osha1, osha1);\n-\t\thashcpy(cb->nsha1, nsha1);\n-\t\tcb->found_it = 1;\n-\t\treturn 1;\n-\t}\n-\thashcpy(cb->osha1, osha1);\n-\thashcpy(cb->nsha1, nsha1);\n-\tif (cb->cnt > 0)\n-\t\tcb->cnt--;\n-\treturn 0;\n-}\n-\n-static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1,\n-\t\t\t\t  const char *id, unsigned long timestamp,\n-\t\t\t\t  int tz, const char *message, void *cb_data)\n-{\n-\tstruct read_ref_at_cb *cb = cb_data;\n-\n-\tif (cb->msg)\n-\t\t*cb->msg = xstrdup(message);\n-\tif (cb->cutoff_time)\n-\t\t*cb->cutoff_time = timestamp;\n-\tif (cb->cutoff_tz)\n-\t\t*cb->cutoff_tz = tz;\n-\tif (cb->cutoff_cnt)\n-\t\t*cb->cutoff_cnt = cb->reccnt;\n-\thashcpy(cb->sha1, osha1);\n-\tif (is_null_sha1(cb->sha1))\n-\t\thashcpy(cb->sha1, nsha1);\n-\t/* We just want the first entry */\n-\treturn 1;\n-}\n-\n-int read_ref_at(const char *refname, unsigned long at_time, int cnt,\n-\t\tunsigned char *sha1, char **msg,\n-\t\tunsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)\n-{\n-\tstruct read_ref_at_cb cb;\n-\n-\tmemset(&cb, 0, sizeof(cb));\n-\tcb.refname = refname;\n-\tcb.at_time = at_time;\n-\tcb.cnt = cnt;\n-\tcb.msg = msg;\n-\tcb.cutoff_time = cutoff_time;\n-\tcb.cutoff_tz = cutoff_tz;\n-\tcb.cutoff_cnt = cutoff_cnt;\n-\tcb.sha1 = sha1;\n-\n-\tfor_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);\n-\n-\tif (!cb.reccnt)\n-\t\tdie(\"Log for %s is empty.\", refname);\n-\tif (cb.found_it)\n-\t\treturn 0;\n-\n-\tfor_each_reflog_ent(refname, read_ref_at_ent_oldest, &cb);\n-\n-\treturn 1;\n-}\n-\n int reflog_exists(const char *refname)\n {\n \tstruct stat st;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247697","messageId":"1407960907-18189-8-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 07/23] refs-common.c: move the hidden refs functions to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:51Z","receivedAt":"2014-08-13T20:14:51Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"This change moves the hidden refs functions to the refs-common.c file since\nthese functions do not contain any backend specific code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 44 ++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 43 -------------------------------------------\n 2 files changed, 44 insertions(+), 43 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 3d7354e..c40fa96 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -1,6 +1,7 @@\n /* common code for all ref backends */\n #include \"cache.h\"\n #include \"refs.h\"\n+#include \"string-list.h\"\n \n int update_ref(const char *action, const char *refname,\n \t       const unsigned char *sha1, const unsigned char *oldval,\n@@ -249,3 +250,46 @@ int read_ref_at(const char *refname, unsigned long at_time, int cnt,\n \n \treturn 1;\n }\n+\n+static struct string_list *hide_refs;\n+\n+int parse_hide_refs_config(const char *var, const char *value, const char *section)\n+{\n+\tif (!strcmp(\"transfer.hiderefs\", var) ||\n+\t    /* NEEDSWORK: use parse_config_key() once both are merged */\n+\t    (starts_with(var, section) && var[strlen(section)] == '.' &&\n+\t     !strcmp(var + strlen(section), \".hiderefs\"))) {\n+\t\tchar *ref;\n+\t\tint len;\n+\n+\t\tif (!value)\n+\t\t\treturn config_error_nonbool(var);\n+\t\tref = xstrdup(value);\n+\t\tlen = strlen(ref);\n+\t\twhile (len && ref[len - 1] == '/')\n+\t\t\tref[--len] = '\\0';\n+\t\tif (!hide_refs) {\n+\t\t\thide_refs = xcalloc(1, sizeof(*hide_refs));\n+\t\t\thide_refs->strdup_strings = 1;\n+\t\t}\n+\t\tstring_list_append(hide_refs, ref);\n+\t}\n+\treturn 0;\n+}\n+\n+int ref_is_hidden(const char *refname)\n+{\n+\tstruct string_list_item *item;\n+\n+\tif (!hide_refs)\n+\t\treturn 0;\n+\tfor_each_string_list_item(item, hide_refs) {\n+\t\tint len;\n+\t\tif (!starts_with(refname, item->string))\n+\t\t\tcontinue;\n+\t\tlen = strlen(item->string);\n+\t\tif (!refname[len] || refname[len] == '/')\n+\t\t\treturn 1;\n+\t}\n+\treturn 0;\n+}\ndiff --git a/refs.c b/refs.c\nindex 52ca0bb..6181edf 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -3796,46 +3796,3 @@ char *shorten_unambiguous_ref(const char *refname, int strict)\n \tfree(short_name);\n \treturn xstrdup(refname);\n }\n-\n-static struct string_list *hide_refs;\n-\n-int parse_hide_refs_config(const char *var, const char *value, const char *section)\n-{\n-\tif (!strcmp(\"transfer.hiderefs\", var) ||\n-\t    /* NEEDSWORK: use parse_config_key() once both are merged */\n-\t    (starts_with(var, section) && var[strlen(section)] == '.' &&\n-\t     !strcmp(var + strlen(section), \".hiderefs\"))) {\n-\t\tchar *ref;\n-\t\tint len;\n-\n-\t\tif (!value)\n-\t\t\treturn config_error_nonbool(var);\n-\t\tref = xstrdup(value);\n-\t\tlen = strlen(ref);\n-\t\twhile (len && ref[len - 1] == '/')\n-\t\t\tref[--len] = '\\0';\n-\t\tif (!hide_refs) {\n-\t\t\thide_refs = xcalloc(1, sizeof(*hide_refs));\n-\t\t\thide_refs->strdup_strings = 1;\n-\t\t}\n-\t\tstring_list_append(hide_refs, ref);\n-\t}\n-\treturn 0;\n-}\n-\n-int ref_is_hidden(const char *refname)\n-{\n-\tstruct string_list_item *item;\n-\n-\tif (!hide_refs)\n-\t\treturn 0;\n-\tfor_each_string_list_item(item, hide_refs) {\n-\t\tint len;\n-\t\tif (!starts_with(refname, item->string))\n-\t\t\tcontinue;\n-\t\tlen = strlen(item->string);\n-\t\tif (!refname[len] || refname[len] == '/')\n-\t\t\treturn 1;\n-\t}\n-\treturn 0;\n-}\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247692","messageId":"1407960907-18189-9-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 08/23] refs-common.c: move dwim and friend functions to refs common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:52Z","receivedAt":"2014-08-13T20:14:52Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"These functions do not contain any backend specific code so we can move\nthem to the common code and share across all backends.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 202 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 202 ----------------------------------------------------------\n 2 files changed, 202 insertions(+), 202 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex c40fa96..ac081e1 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -293,3 +293,205 @@ int ref_is_hidden(const char *refname)\n \t}\n \treturn 0;\n }\n+\n+static const char *ref_rev_parse_rules[] = {\n+\t\"%.*s\",\n+\t\"refs/%.*s\",\n+\t\"refs/tags/%.*s\",\n+\t\"refs/heads/%.*s\",\n+\t\"refs/remotes/%.*s\",\n+\t\"refs/remotes/%.*s/HEAD\",\n+\tNULL\n+};\n+\n+int refname_match(const char *abbrev_name, const char *full_name)\n+{\n+\tconst char **p;\n+\tconst int abbrev_name_len = strlen(abbrev_name);\n+\n+\tfor (p = ref_rev_parse_rules; *p; p++) {\n+\t\tif (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {\n+\t\t\treturn 1;\n+\t\t}\n+\t}\n+\n+\treturn 0;\n+}\n+\n+/*\n+ * *string and *len will only be substituted, and *string returned (for\n+ * later free()ing) if the string passed in is a magic short-hand form\n+ * to name a branch.\n+ */\n+static char *substitute_branch_name(const char **string, int *len)\n+{\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint ret = interpret_branch_name(*string, *len, &buf);\n+\n+\tif (ret == *len) {\n+\t\tsize_t size;\n+\t\t*string = strbuf_detach(&buf, &size);\n+\t\t*len = size;\n+\t\treturn (char *)*string;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)\n+{\n+\tchar *last_branch = substitute_branch_name(&str, &len);\n+\tconst char **p, *r;\n+\tint refs_found = 0;\n+\n+\t*ref = NULL;\n+\tfor (p = ref_rev_parse_rules; *p; p++) {\n+\t\tchar fullref[PATH_MAX];\n+\t\tunsigned char sha1_from_ref[20];\n+\t\tunsigned char *this_result;\n+\t\tint flag;\n+\n+\t\tthis_result = refs_found ? sha1_from_ref : sha1;\n+\t\tmksnpath(fullref, sizeof(fullref), *p, len, str);\n+\t\tr = resolve_ref_unsafe(fullref, this_result,\n+\t\t\t\t       RESOLVE_REF_READING, &flag);\n+\t\tif (r) {\n+\t\t\tif (!refs_found++)\n+\t\t\t\t*ref = xstrdup(r);\n+\t\t\tif (!warn_ambiguous_refs)\n+\t\t\t\tbreak;\n+\t\t} else if ((flag & REF_ISSYMREF) && strcmp(fullref, \"HEAD\")) {\n+\t\t\twarning(\"ignoring dangling symref %s.\", fullref);\n+\t\t} else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) {\n+\t\t\twarning(\"ignoring broken ref %s.\", fullref);\n+\t\t}\n+\t}\n+\tfree(last_branch);\n+\treturn refs_found;\n+}\n+\n+int dwim_log(const char *str, int len, unsigned char *sha1, char **log)\n+{\n+\tchar *last_branch = substitute_branch_name(&str, &len);\n+\tconst char **p;\n+\tint logs_found = 0;\n+\n+\t*log = NULL;\n+\tfor (p = ref_rev_parse_rules; *p; p++) {\n+\t\tunsigned char hash[20];\n+\t\tchar path[PATH_MAX];\n+\t\tconst char *ref, *it;\n+\n+\t\tmksnpath(path, sizeof(path), *p, len, str);\n+\t\tref = resolve_ref_unsafe(path, hash, RESOLVE_REF_READING, NULL);\n+\t\tif (!ref)\n+\t\t\tcontinue;\n+\t\tif (reflog_exists(path))\n+\t\t\tit = path;\n+\t\telse if (strcmp(ref, path) && reflog_exists(ref))\n+\t\t\tit = ref;\n+\t\telse\n+\t\t\tcontinue;\n+\t\tif (!logs_found++) {\n+\t\t\t*log = xstrdup(it);\n+\t\t\thashcpy(sha1, hash);\n+\t\t}\n+\t\tif (!warn_ambiguous_refs)\n+\t\t\tbreak;\n+\t}\n+\tfree(last_branch);\n+\treturn logs_found;\n+}\n+\n+char *shorten_unambiguous_ref(const char *refname, int strict)\n+{\n+\tint i;\n+\tstatic char **scanf_fmts;\n+\tstatic int nr_rules;\n+\tchar *short_name;\n+\n+\tif (!nr_rules) {\n+\t\t/*\n+\t\t * Pre-generate scanf formats from ref_rev_parse_rules[].\n+\t\t * Generate a format suitable for scanf from a\n+\t\t * ref_rev_parse_rules rule by interpolating \"%s\" at the\n+\t\t * location of the \"%.*s\".\n+\t\t */\n+\t\tsize_t total_len = 0;\n+\t\tsize_t offset = 0;\n+\n+\t\t/* the rule list is NULL terminated, count them first */\n+\t\tfor (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)\n+\t\t\t/* -2 for strlen(\"%.*s\") - strlen(\"%s\"); +1 for NUL */\n+\t\t\ttotal_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;\n+\n+\t\tscanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);\n+\n+\t\toffset = 0;\n+\t\tfor (i = 0; i < nr_rules; i++) {\n+\t\t\tassert(offset < total_len);\n+\t\t\tscanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;\n+\t\t\toffset += snprintf(scanf_fmts[i], total_len - offset,\n+\t\t\t\t\t   ref_rev_parse_rules[i], 2, \"%s\") + 1;\n+\t\t}\n+\t}\n+\n+\t/* bail out if there are no rules */\n+\tif (!nr_rules)\n+\t\treturn xstrdup(refname);\n+\n+\t/* buffer for scanf result, at most refname must fit */\n+\tshort_name = xstrdup(refname);\n+\n+\t/* skip first rule, it will always match */\n+\tfor (i = nr_rules - 1; i > 0 ; --i) {\n+\t\tint j;\n+\t\tint rules_to_fail = i;\n+\t\tint short_name_len;\n+\n+\t\tif (1 != sscanf(refname, scanf_fmts[i], short_name))\n+\t\t\tcontinue;\n+\n+\t\tshort_name_len = strlen(short_name);\n+\n+\t\t/*\n+\t\t * in strict mode, all (except the matched one) rules\n+\t\t * must fail to resolve to a valid non-ambiguous ref\n+\t\t */\n+\t\tif (strict)\n+\t\t\trules_to_fail = nr_rules;\n+\n+\t\t/*\n+\t\t * check if the short name resolves to a valid ref,\n+\t\t * but use only rules prior to the matched one\n+\t\t */\n+\t\tfor (j = 0; j < rules_to_fail; j++) {\n+\t\t\tconst char *rule = ref_rev_parse_rules[j];\n+\t\t\tchar refname[PATH_MAX];\n+\n+\t\t\t/* skip matched rule */\n+\t\t\tif (i == j)\n+\t\t\t\tcontinue;\n+\n+\t\t\t/*\n+\t\t\t * the short name is ambiguous, if it resolves\n+\t\t\t * (with this previous rule) to a valid ref\n+\t\t\t * read_ref() returns 0 on success\n+\t\t\t */\n+\t\t\tmksnpath(refname, sizeof(refname),\n+\t\t\t\t rule, short_name_len, short_name);\n+\t\t\tif (ref_exists(refname))\n+\t\t\t\tbreak;\n+\t\t}\n+\n+\t\t/*\n+\t\t * short name is non-ambiguous if all previous rules\n+\t\t * haven't resolved to a valid ref\n+\t\t */\n+\t\tif (j == rules_to_fail)\n+\t\t\treturn short_name;\n+\t}\n+\n+\tfree(short_name);\n+\treturn xstrdup(refname);\n+}\ndiff --git a/refs.c b/refs.c\nindex 6181edf..56e146f 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1956,30 +1956,6 @@ const char *prettify_refname(const char *name)\n \t\t0);\n }\n \n-static const char *ref_rev_parse_rules[] = {\n-\t\"%.*s\",\n-\t\"refs/%.*s\",\n-\t\"refs/tags/%.*s\",\n-\t\"refs/heads/%.*s\",\n-\t\"refs/remotes/%.*s\",\n-\t\"refs/remotes/%.*s/HEAD\",\n-\tNULL\n-};\n-\n-int refname_match(const char *abbrev_name, const char *full_name)\n-{\n-\tconst char **p;\n-\tconst int abbrev_name_len = strlen(abbrev_name);\n-\n-\tfor (p = ref_rev_parse_rules; *p; p++) {\n-\t\tif (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) {\n-\t\t\treturn 1;\n-\t\t}\n-\t}\n-\n-\treturn 0;\n-}\n-\n static void unlock_ref(struct ref_lock *lock)\n {\n \t/* Do not free lock->lk -- atexit() still looks at them */\n@@ -2033,91 +2009,6 @@ static int remove_empty_directories(const char *file)\n \treturn result;\n }\n \n-/*\n- * *string and *len will only be substituted, and *string returned (for\n- * later free()ing) if the string passed in is a magic short-hand form\n- * to name a branch.\n- */\n-static char *substitute_branch_name(const char **string, int *len)\n-{\n-\tstruct strbuf buf = STRBUF_INIT;\n-\tint ret = interpret_branch_name(*string, *len, &buf);\n-\n-\tif (ret == *len) {\n-\t\tsize_t size;\n-\t\t*string = strbuf_detach(&buf, &size);\n-\t\t*len = size;\n-\t\treturn (char *)*string;\n-\t}\n-\n-\treturn NULL;\n-}\n-\n-int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref)\n-{\n-\tchar *last_branch = substitute_branch_name(&str, &len);\n-\tconst char **p, *r;\n-\tint refs_found = 0;\n-\n-\t*ref = NULL;\n-\tfor (p = ref_rev_parse_rules; *p; p++) {\n-\t\tchar fullref[PATH_MAX];\n-\t\tunsigned char sha1_from_ref[20];\n-\t\tunsigned char *this_result;\n-\t\tint flag;\n-\n-\t\tthis_result = refs_found ? sha1_from_ref : sha1;\n-\t\tmksnpath(fullref, sizeof(fullref), *p, len, str);\n-\t\tr = resolve_ref_unsafe(fullref, this_result,\n-\t\t\t\t       RESOLVE_REF_READING, &flag);\n-\t\tif (r) {\n-\t\t\tif (!refs_found++)\n-\t\t\t\t*ref = xstrdup(r);\n-\t\t\tif (!warn_ambiguous_refs)\n-\t\t\t\tbreak;\n-\t\t} else if ((flag & REF_ISSYMREF) && strcmp(fullref, \"HEAD\")) {\n-\t\t\twarning(\"ignoring dangling symref %s.\", fullref);\n-\t\t} else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) {\n-\t\t\twarning(\"ignoring broken ref %s.\", fullref);\n-\t\t}\n-\t}\n-\tfree(last_branch);\n-\treturn refs_found;\n-}\n-\n-int dwim_log(const char *str, int len, unsigned char *sha1, char **log)\n-{\n-\tchar *last_branch = substitute_branch_name(&str, &len);\n-\tconst char **p;\n-\tint logs_found = 0;\n-\n-\t*log = NULL;\n-\tfor (p = ref_rev_parse_rules; *p; p++) {\n-\t\tunsigned char hash[20];\n-\t\tchar path[PATH_MAX];\n-\t\tconst char *ref, *it;\n-\n-\t\tmksnpath(path, sizeof(path), *p, len, str);\n-\t\tref = resolve_ref_unsafe(path, hash, RESOLVE_REF_READING, NULL);\n-\t\tif (!ref)\n-\t\t\tcontinue;\n-\t\tif (reflog_exists(path))\n-\t\t\tit = path;\n-\t\telse if (strcmp(ref, path) && reflog_exists(ref))\n-\t\t\tit = ref;\n-\t\telse\n-\t\t\tcontinue;\n-\t\tif (!logs_found++) {\n-\t\t\t*log = xstrdup(it);\n-\t\t\thashcpy(sha1, hash);\n-\t\t}\n-\t\tif (!warn_ambiguous_refs)\n-\t\t\tbreak;\n-\t}\n-\tfree(last_branch);\n-\treturn logs_found;\n-}\n-\n /* This function should make sure errno is meaningful on error */\n static struct ref_lock *lock_ref_sha1_basic(const char *refname,\n \t\t\t\t\t    const unsigned char *old_sha1,\n@@ -3703,96 +3594,3 @@ cleanup:\n \t\tret = -2;\n \treturn ret;\n }\n-\n-char *shorten_unambiguous_ref(const char *refname, int strict)\n-{\n-\tint i;\n-\tstatic char **scanf_fmts;\n-\tstatic int nr_rules;\n-\tchar *short_name;\n-\n-\tif (!nr_rules) {\n-\t\t/*\n-\t\t * Pre-generate scanf formats from ref_rev_parse_rules[].\n-\t\t * Generate a format suitable for scanf from a\n-\t\t * ref_rev_parse_rules rule by interpolating \"%s\" at the\n-\t\t * location of the \"%.*s\".\n-\t\t */\n-\t\tsize_t total_len = 0;\n-\t\tsize_t offset = 0;\n-\n-\t\t/* the rule list is NULL terminated, count them first */\n-\t\tfor (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++)\n-\t\t\t/* -2 for strlen(\"%.*s\") - strlen(\"%s\"); +1 for NUL */\n-\t\t\ttotal_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1;\n-\n-\t\tscanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len);\n-\n-\t\toffset = 0;\n-\t\tfor (i = 0; i < nr_rules; i++) {\n-\t\t\tassert(offset < total_len);\n-\t\t\tscanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;\n-\t\t\toffset += snprintf(scanf_fmts[i], total_len - offset,\n-\t\t\t\t\t   ref_rev_parse_rules[i], 2, \"%s\") + 1;\n-\t\t}\n-\t}\n-\n-\t/* bail out if there are no rules */\n-\tif (!nr_rules)\n-\t\treturn xstrdup(refname);\n-\n-\t/* buffer for scanf result, at most refname must fit */\n-\tshort_name = xstrdup(refname);\n-\n-\t/* skip first rule, it will always match */\n-\tfor (i = nr_rules - 1; i > 0 ; --i) {\n-\t\tint j;\n-\t\tint rules_to_fail = i;\n-\t\tint short_name_len;\n-\n-\t\tif (1 != sscanf(refname, scanf_fmts[i], short_name))\n-\t\t\tcontinue;\n-\n-\t\tshort_name_len = strlen(short_name);\n-\n-\t\t/*\n-\t\t * in strict mode, all (except the matched one) rules\n-\t\t * must fail to resolve to a valid non-ambiguous ref\n-\t\t */\n-\t\tif (strict)\n-\t\t\trules_to_fail = nr_rules;\n-\n-\t\t/*\n-\t\t * check if the short name resolves to a valid ref,\n-\t\t * but use only rules prior to the matched one\n-\t\t */\n-\t\tfor (j = 0; j < rules_to_fail; j++) {\n-\t\t\tconst char *rule = ref_rev_parse_rules[j];\n-\t\t\tchar refname[PATH_MAX];\n-\n-\t\t\t/* skip matched rule */\n-\t\t\tif (i == j)\n-\t\t\t\tcontinue;\n-\n-\t\t\t/*\n-\t\t\t * the short name is ambiguous, if it resolves\n-\t\t\t * (with this previous rule) to a valid ref\n-\t\t\t * read_ref() returns 0 on success\n-\t\t\t */\n-\t\t\tmksnpath(refname, sizeof(refname),\n-\t\t\t\t rule, short_name_len, short_name);\n-\t\t\tif (ref_exists(refname))\n-\t\t\t\tbreak;\n-\t\t}\n-\n-\t\t/*\n-\t\t * short name is non-ambiguous if all previous rules\n-\t\t * haven't resolved to a valid ref\n-\t\t */\n-\t\tif (j == rules_to_fail)\n-\t\t\treturn short_name;\n-\t}\n-\n-\tfree(short_name);\n-\treturn xstrdup(refname);\n-}\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247701","messageId":"1407960907-18189-10-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 09/23] refs-common.c: move warn_if_dangling_symref* to refs-common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:53Z","receivedAt":"2014-08-13T20:14:53Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"These functions do not use any backend specific code so we can move\nthem to the common code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 52 ----------------------------------------------------\n 2 files changed, 52 insertions(+), 52 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex ac081e1..ab3a118 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -495,3 +495,55 @@ char *shorten_unambiguous_ref(const char *refname, int strict)\n \tfree(short_name);\n \treturn xstrdup(refname);\n }\n+\n+struct warn_if_dangling_data {\n+\tFILE *fp;\n+\tconst char *refname;\n+\tconst struct string_list *refnames;\n+\tconst char *msg_fmt;\n+};\n+\n+static int warn_if_dangling_symref(const char *refname, const unsigned char *sha1,\n+\t\t\t\t   int flags, void *cb_data)\n+{\n+\tstruct warn_if_dangling_data *d = cb_data;\n+\tconst char *resolves_to;\n+\tunsigned char junk[20];\n+\n+\tif (!(flags & REF_ISSYMREF))\n+\t\treturn 0;\n+\n+\tresolves_to = resolve_ref_unsafe(refname, junk, 0, NULL);\n+\tif (!resolves_to\n+\t    || (d->refname\n+\t\t? strcmp(resolves_to, d->refname)\n+\t\t: !string_list_has_string(d->refnames, resolves_to))) {\n+\t\treturn 0;\n+\t}\n+\n+\tfprintf(d->fp, d->msg_fmt, refname);\n+\tfputc('\\n', d->fp);\n+\treturn 0;\n+}\n+\n+void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)\n+{\n+\tstruct warn_if_dangling_data data;\n+\n+\tdata.fp = fp;\n+\tdata.refname = refname;\n+\tdata.refnames = NULL;\n+\tdata.msg_fmt = msg_fmt;\n+\tfor_each_rawref(warn_if_dangling_symref, &data);\n+}\n+\n+void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)\n+{\n+\tstruct warn_if_dangling_data data;\n+\n+\tdata.fp = fp;\n+\tdata.refname = NULL;\n+\tdata.refnames = refnames;\n+\tdata.msg_fmt = msg_fmt;\n+\tfor_each_rawref(warn_if_dangling_symref, &data);\n+}\ndiff --git a/refs.c b/refs.c\nindex 56e146f..40c329b 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1667,58 +1667,6 @@ int peel_ref(const char *refname, unsigned char *sha1)\n \treturn peel_object(base, sha1);\n }\n \n-struct warn_if_dangling_data {\n-\tFILE *fp;\n-\tconst char *refname;\n-\tconst struct string_list *refnames;\n-\tconst char *msg_fmt;\n-};\n-\n-static int warn_if_dangling_symref(const char *refname, const unsigned char *sha1,\n-\t\t\t\t   int flags, void *cb_data)\n-{\n-\tstruct warn_if_dangling_data *d = cb_data;\n-\tconst char *resolves_to;\n-\tunsigned char junk[20];\n-\n-\tif (!(flags & REF_ISSYMREF))\n-\t\treturn 0;\n-\n-\tresolves_to = resolve_ref_unsafe(refname, junk, 0, NULL);\n-\tif (!resolves_to\n-\t    || (d->refname\n-\t\t? strcmp(resolves_to, d->refname)\n-\t\t: !string_list_has_string(d->refnames, resolves_to))) {\n-\t\treturn 0;\n-\t}\n-\n-\tfprintf(d->fp, d->msg_fmt, refname);\n-\tfputc('\\n', d->fp);\n-\treturn 0;\n-}\n-\n-void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname)\n-{\n-\tstruct warn_if_dangling_data data;\n-\n-\tdata.fp = fp;\n-\tdata.refname = refname;\n-\tdata.refnames = NULL;\n-\tdata.msg_fmt = msg_fmt;\n-\tfor_each_rawref(warn_if_dangling_symref, &data);\n-}\n-\n-void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_list *refnames)\n-{\n-\tstruct warn_if_dangling_data data;\n-\n-\tdata.fp = fp;\n-\tdata.refname = NULL;\n-\tdata.refnames = refnames;\n-\tdata.msg_fmt = msg_fmt;\n-\tfor_each_rawref(warn_if_dangling_symref, &data);\n-}\n-\n /*\n  * Call fn for each reference in the specified ref_cache, omitting\n  * references not in the containing_dir of base.  fn is called for all\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247705","messageId":"1407960907-18189-11-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 10/23] refs-common.c: move read_ref, read_ref_full and ref_exists to common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:54Z","receivedAt":"2014-08-13T20:14:54Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"These functions do not depend on the backend implementation so we\ncan move them to the common code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 18 ++++++++++++++++++\n refs.c        | 18 ------------------\n 2 files changed, 18 insertions(+), 18 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex ab3a118..37d3d14 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -547,3 +547,21 @@ void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_li\n \tdata.msg_fmt = msg_fmt;\n \tfor_each_rawref(warn_if_dangling_symref, &data);\n }\n+\n+int read_ref_full(const char *refname, unsigned char *sha1, int flags, int *ref_flag)\n+{\n+\tif (resolve_ref_unsafe(refname, sha1, flags, ref_flag))\n+\t\treturn 0;\n+\treturn -1;\n+}\n+\n+int read_ref(const char *refname, unsigned char *sha1)\n+{\n+\treturn read_ref_full(refname, sha1, RESOLVE_REF_READING, NULL);\n+}\n+\n+int ref_exists(const char *refname)\n+{\n+\tunsigned char sha1[20];\n+\treturn !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL);\n+}\ndiff --git a/refs.c b/refs.c\nindex 40c329b..a94378e 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1514,24 +1514,6 @@ struct ref_filter {\n \tvoid *cb_data;\n };\n \n-int read_ref_full(const char *refname, unsigned char *sha1, int flags, int *ref_flag)\n-{\n-\tif (resolve_ref_unsafe(refname, sha1, flags, ref_flag))\n-\t\treturn 0;\n-\treturn -1;\n-}\n-\n-int read_ref(const char *refname, unsigned char *sha1)\n-{\n-\treturn read_ref_full(refname, sha1, RESOLVE_REF_READING, NULL);\n-}\n-\n-int ref_exists(const char *refname)\n-{\n-\tunsigned char sha1[20];\n-\treturn !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL);\n-}\n-\n static int filter_refs(const char *refname, const unsigned char *sha1, int flags,\n \t\t       void *data)\n {\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247699","messageId":"1407960907-18189-12-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 11/23] refs-common.c: move resolve_refdup to common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:55Z","receivedAt":"2014-08-13T20:14:55Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"This function can be shared across all refs backends so move it\nto the common code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 6 ++++++\n refs.c        | 6 ------\n 2 files changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 37d3d14..655a1a0 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -565,3 +565,9 @@ int ref_exists(const char *refname)\n \tunsigned char sha1[20];\n \treturn !!resolve_ref_unsafe(refname, sha1, RESOLVE_REF_READING, NULL);\n }\n+\n+char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int *ref_flag)\n+{\n+\tconst char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag);\n+\treturn ret ? xstrdup(ret) : NULL;\n+}\ndiff --git a/refs.c b/refs.c\nindex a94378e..ed7bc61 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1501,12 +1501,6 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int fla\n \t}\n }\n \n-char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int *ref_flag)\n-{\n-\tconst char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag);\n-\treturn ret ? xstrdup(ret) : NULL;\n-}\n-\n /* The argument to filter_refs */\n struct ref_filter {\n \tconst char *pattern;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247694","messageId":"1407960907-18189-13-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 12/23] refs-common.c: move check_refname_component to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:56Z","receivedAt":"2014-08-13T20:14:56Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"This function does not contain any backend specific code so we\ncan move it to the common code.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 110 ----------------------------------------------------------\n 2 files changed, 110 insertions(+), 110 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 655a1a0..f8b79e0 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -571,3 +571,113 @@ char *resolve_refdup(const char *ref, unsigned char *sha1, int flags, int *ref_f\n \tconst char *ret = resolve_ref_unsafe(ref, sha1, flags, ref_flag);\n \treturn ret ? xstrdup(ret) : NULL;\n }\n+\n+/*\n+ * How to handle various characters in refnames:\n+ * 0: An acceptable character for refs\n+ * 1: End-of-component\n+ * 2: ., look for a preceding . to reject .. in refs\n+ * 3: {, look for a preceding @ to reject @{ in refs\n+ * 4: A bad character: ASCII control characters, \"~\", \"^\", \":\" or SP\n+ */\n+static unsigned char refname_disposition[256] = {\n+\t1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n+\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n+\t4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 1,\n+\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,\n+\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n+\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,\n+\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n+\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4\n+};\n+\n+/*\n+ * Try to read one refname component from the front of refname.\n+ * Return the length of the component found, or -1 if the component is\n+ * not legal.  It is legal if it is something reasonable to have under\n+ * \".git/refs/\"; We do not like it if:\n+ *\n+ * - any path component of it begins with \".\", or\n+ * - it has double dots \"..\", or\n+ * - it has ASCII control character, \"~\", \"^\", \":\" or SP, anywhere, or\n+ * - it ends with a \"/\".\n+ * - it ends with \".lock\"\n+ * - it contains a \"\\\" (backslash)\n+ */\n+static int check_refname_component(const char *refname, int flags)\n+{\n+\tconst char *cp;\n+\tchar last = '\\0';\n+\n+\tfor (cp = refname; ; cp++) {\n+\t\tint ch = *cp & 255;\n+\t\tunsigned char disp = refname_disposition[ch];\n+\t\tswitch (disp) {\n+\t\tcase 1:\n+\t\t\tgoto out;\n+\t\tcase 2:\n+\t\t\tif (last == '.')\n+\t\t\t\treturn -1; /* Refname contains \"..\". */\n+\t\t\tbreak;\n+\t\tcase 3:\n+\t\t\tif (last == '@')\n+\t\t\t\treturn -1; /* Refname contains \"@{\". */\n+\t\t\tbreak;\n+\t\tcase 4:\n+\t\t\treturn -1;\n+\t\t}\n+\t\tlast = ch;\n+\t}\n+out:\n+\tif (cp == refname)\n+\t\treturn 0; /* Component has zero length. */\n+\tif (refname[0] == '.') {\n+\t\tif (!(flags & REFNAME_DOT_COMPONENT))\n+\t\t\treturn -1; /* Component starts with '.'. */\n+\t\t/*\n+\t\t * Even if leading dots are allowed, don't allow \".\"\n+\t\t * as a component (\"..\" is prevented by a rule above).\n+\t\t */\n+\t\tif (refname[1] == '\\0')\n+\t\t\treturn -1; /* Component equals \".\". */\n+\t}\n+\tif (cp - refname >= 5 && !memcmp(cp - 5, \".lock\", 5))\n+\t\treturn -1; /* Refname ends with \".lock\". */\n+\treturn cp - refname;\n+}\n+\n+int check_refname_format(const char *refname, int flags)\n+{\n+\tint component_len, component_count = 0;\n+\n+\tif (!strcmp(refname, \"@\"))\n+\t\t/* Refname is a single character '@'. */\n+\t\treturn -1;\n+\n+\twhile (1) {\n+\t\t/* We are at the start of a path component. */\n+\t\tcomponent_len = check_refname_component(refname, flags);\n+\t\tif (component_len <= 0) {\n+\t\t\tif ((flags & REFNAME_REFSPEC_PATTERN) &&\n+\t\t\t\t\trefname[0] == '*' &&\n+\t\t\t\t\t(refname[1] == '\\0' || refname[1] == '/')) {\n+\t\t\t\t/* Accept one wildcard as a full refname component. */\n+\t\t\t\tflags &= ~REFNAME_REFSPEC_PATTERN;\n+\t\t\t\tcomponent_len = 1;\n+\t\t\t} else {\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t}\n+\t\tcomponent_count++;\n+\t\tif (refname[component_len] == '\\0')\n+\t\t\tbreak;\n+\t\t/* Skip to next component. */\n+\t\trefname += component_len + 1;\n+\t}\n+\n+\tif (refname[component_len - 1] == '.')\n+\t\treturn -1; /* Refname ends with '.'. */\n+\tif (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)\n+\t\treturn -1; /* Refname has only one component. */\n+\treturn 0;\n+}\ndiff --git a/refs.c b/refs.c\nindex ed7bc61..55bced9 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -6,25 +6,6 @@\n #include \"string-list.h\"\n \n /*\n- * How to handle various characters in refnames:\n- * 0: An acceptable character for refs\n- * 1: End-of-component\n- * 2: ., look for a preceding . to reject .. in refs\n- * 3: {, look for a preceding @ to reject @{ in refs\n- * 4: A bad character: ASCII control characters, \"~\", \"^\", \":\" or SP\n- */\n-static unsigned char refname_disposition[256] = {\n-\t1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n-\t4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,\n-\t4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 1,\n-\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 4,\n-\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n-\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 0,\n-\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n-\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 4, 4\n-};\n-\n-/*\n  * Used as a flag to transaction_delete_sha1 when a loose ref is being\n  * pruned.\n  */\n@@ -35,97 +16,6 @@ static unsigned char refname_disposition[256] = {\n  */\n #define UPDATE_REFLOG_NOLOCK 0x0200\n \n-/*\n- * Try to read one refname component from the front of refname.\n- * Return the length of the component found, or -1 if the component is\n- * not legal.  It is legal if it is something reasonable to have under\n- * \".git/refs/\"; We do not like it if:\n- *\n- * - any path component of it begins with \".\", or\n- * - it has double dots \"..\", or\n- * - it has ASCII control character, \"~\", \"^\", \":\" or SP, anywhere, or\n- * - it ends with a \"/\".\n- * - it ends with \".lock\"\n- * - it contains a \"\\\" (backslash)\n- */\n-static int check_refname_component(const char *refname, int flags)\n-{\n-\tconst char *cp;\n-\tchar last = '\\0';\n-\n-\tfor (cp = refname; ; cp++) {\n-\t\tint ch = *cp & 255;\n-\t\tunsigned char disp = refname_disposition[ch];\n-\t\tswitch (disp) {\n-\t\tcase 1:\n-\t\t\tgoto out;\n-\t\tcase 2:\n-\t\t\tif (last == '.')\n-\t\t\t\treturn -1; /* Refname contains \"..\". */\n-\t\t\tbreak;\n-\t\tcase 3:\n-\t\t\tif (last == '@')\n-\t\t\t\treturn -1; /* Refname contains \"@{\". */\n-\t\t\tbreak;\n-\t\tcase 4:\n-\t\t\treturn -1;\n-\t\t}\n-\t\tlast = ch;\n-\t}\n-out:\n-\tif (cp == refname)\n-\t\treturn 0; /* Component has zero length. */\n-\tif (refname[0] == '.') {\n-\t\tif (!(flags & REFNAME_DOT_COMPONENT))\n-\t\t\treturn -1; /* Component starts with '.'. */\n-\t\t/*\n-\t\t * Even if leading dots are allowed, don't allow \".\"\n-\t\t * as a component (\"..\" is prevented by a rule above).\n-\t\t */\n-\t\tif (refname[1] == '\\0')\n-\t\t\treturn -1; /* Component equals \".\". */\n-\t}\n-\tif (cp - refname >= 5 && !memcmp(cp - 5, \".lock\", 5))\n-\t\treturn -1; /* Refname ends with \".lock\". */\n-\treturn cp - refname;\n-}\n-\n-int check_refname_format(const char *refname, int flags)\n-{\n-\tint component_len, component_count = 0;\n-\n-\tif (!strcmp(refname, \"@\"))\n-\t\t/* Refname is a single character '@'. */\n-\t\treturn -1;\n-\n-\twhile (1) {\n-\t\t/* We are at the start of a path component. */\n-\t\tcomponent_len = check_refname_component(refname, flags);\n-\t\tif (component_len <= 0) {\n-\t\t\tif ((flags & REFNAME_REFSPEC_PATTERN) &&\n-\t\t\t\t\trefname[0] == '*' &&\n-\t\t\t\t\t(refname[1] == '\\0' || refname[1] == '/')) {\n-\t\t\t\t/* Accept one wildcard as a full refname component. */\n-\t\t\t\tflags &= ~REFNAME_REFSPEC_PATTERN;\n-\t\t\t\tcomponent_len = 1;\n-\t\t\t} else {\n-\t\t\t\treturn -1;\n-\t\t\t}\n-\t\t}\n-\t\tcomponent_count++;\n-\t\tif (refname[component_len] == '\\0')\n-\t\t\tbreak;\n-\t\t/* Skip to next component. */\n-\t\trefname += component_len + 1;\n-\t}\n-\n-\tif (refname[component_len - 1] == '.')\n-\t\treturn -1; /* Refname ends with '.'. */\n-\tif (!(flags & REFNAME_ALLOW_ONELEVEL) && component_count < 2)\n-\t\treturn -1; /* Refname has only one component. */\n-\treturn 0;\n-}\n-\n struct ref_entry;\n \n /*\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247707","messageId":"1407960907-18189-14-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 13/23] refs-common.c: move is_branch to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:57Z","receivedAt":"2014-08-13T20:14:57Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 5 +++++\n refs.c        | 5 -----\n 2 files changed, 5 insertions(+), 5 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex f8b79e0..5f83d7e 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -3,6 +3,11 @@\n #include \"refs.h\"\n #include \"string-list.h\"\n \n+int is_branch(const char *refname)\n+{\n+\treturn !strcmp(refname, \"HEAD\") || starts_with(refname, \"refs/heads/\");\n+}\n+\n int update_ref(const char *action, const char *refname,\n \t       const unsigned char *sha1, const unsigned char *oldval,\n \t       int flags, struct strbuf *e)\ndiff --git a/refs.c b/refs.c\nindex 55bced9..70c034c 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2483,11 +2483,6 @@ static int log_ref_write(const char *refname, const unsigned char *old_sha1,\n \treturn 0;\n }\n \n-int is_branch(const char *refname)\n-{\n-\treturn !strcmp(refname, \"HEAD\") || starts_with(refname, \"refs/heads/\");\n-}\n-\n static int write_sha1_update_reflog(struct ref_lock *lock,\n \tconst unsigned char *sha1, const char *logmsg)\n {\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247706","messageId":"1407960907-18189-15-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 14/23] refs-common.c: move names_conflict to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:58Z","receivedAt":"2014-08-13T20:14:58Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c |  8 ++++++++\n refs.c        | 14 --------------\n refs.h        |  9 +++++++++\n 3 files changed, 17 insertions(+), 14 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 5f83d7e..6eef80b 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -3,6 +3,14 @@\n #include \"refs.h\"\n #include \"string-list.h\"\n \n+int names_conflict(const char *refname1, const char *refname2)\n+{\n+\tfor (; *refname1 && *refname1 == *refname2; refname1++, refname2++)\n+\t\t;\n+\treturn (*refname1 == '\\0' && *refname2 == '/')\n+\t\t|| (*refname1 == '/' && *refname2 == '\\0');\n+}\n+\n int is_branch(const char *refname)\n {\n \treturn !strcmp(refname, \"HEAD\") || starts_with(refname, \"refs/heads/\");\ndiff --git a/refs.c b/refs.c\nindex 70c034c..6542969 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -676,20 +676,6 @@ static void prime_ref_dir(struct ref_dir *dir)\n \t\t\tprime_ref_dir(get_ref_dir(entry));\n \t}\n }\n-/*\n- * Return true iff refname1 and refname2 conflict with each other.\n- * Two reference names conflict if one of them exactly matches the\n- * leading components of the other; e.g., \"foo/bar\" conflicts with\n- * both \"foo\" and with \"foo/bar/baz\" but not with \"foo/bar\" or\n- * \"foo/barbados\".\n- */\n-static int names_conflict(const char *refname1, const char *refname2)\n-{\n-\tfor (; *refname1 && *refname1 == *refname2; refname1++, refname2++)\n-\t\t;\n-\treturn (*refname1 == '\\0' && *refname2 == '/')\n-\t\t|| (*refname1 == '/' && *refname2 == '\\0');\n-}\n \n struct name_conflict_cb {\n \tconst char *refname;\ndiff --git a/refs.h b/refs.h\nindex d526da0..a14fc5d 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -128,6 +128,15 @@ int pack_refs(unsigned int flags, struct strbuf *err);\n \n extern int ref_exists(const char *);\n \n+/*\n+ * Return true iff refname1 and refname2 conflict with each other.\n+ * Two reference names conflict if one of them exactly matches the\n+ * leading components of the other; e.g., \"foo/bar\" conflicts with\n+ * both \"foo\" and with \"foo/bar/baz\" but not with \"foo/bar\" or\n+ * \"foo/barbados\".\n+ */\n+int names_conflict(const char *refname1, const char *refname2);\n+\n extern int is_branch(const char *refname);\n \n /*\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247702","messageId":"1407960907-18189-16-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 15/23] refs-common.c: move prettify_refname to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:14:59Z","receivedAt":"2014-08-13T20:14:59Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 9 +++++++++\n refs.c        | 9 ---------\n 2 files changed, 9 insertions(+), 9 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 6eef80b..d8a295c 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -3,6 +3,15 @@\n #include \"refs.h\"\n #include \"string-list.h\"\n \n+const char *prettify_refname(const char *name)\n+{\n+\treturn name + (\n+\t\tstarts_with(name, \"refs/heads/\") ? 11 :\n+\t\tstarts_with(name, \"refs/tags/\") ? 10 :\n+\t\tstarts_with(name, \"refs/remotes/\") ? 13 :\n+\t\t0);\n+}\n+\n int names_conflict(const char *refname1, const char *refname2)\n {\n \tfor (; *refname1 && *refname1 == *refname2; refname1++, refname2++)\ndiff --git a/refs.c b/refs.c\nindex 6542969..fb9c614 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1747,15 +1747,6 @@ int for_each_rawref(each_ref_fn fn, void *cb_data)\n \t\t\t       DO_FOR_EACH_INCLUDE_BROKEN, cb_data);\n }\n \n-const char *prettify_refname(const char *name)\n-{\n-\treturn name + (\n-\t\tstarts_with(name, \"refs/heads/\") ? 11 :\n-\t\tstarts_with(name, \"refs/tags/\") ? 10 :\n-\t\tstarts_with(name, \"refs/remotes/\") ? 13 :\n-\t\t0);\n-}\n-\n static void unlock_ref(struct ref_lock *lock)\n {\n \t/* Do not free lock->lk -- atexit() still looks at them */\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247691","messageId":"1407960907-18189-17-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 16/23] refs-common.c: move ref iterators to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:15:00Z","receivedAt":"2014-08-13T20:15:00Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 81 -----------------------------------------------------------\n 2 files changed, 81 insertions(+), 81 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex d8a295c..3b20db3 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -668,6 +668,87 @@ out:\n \treturn cp - refname;\n }\n \n+/* The argument to filter_refs */\n+struct ref_filter {\n+\tconst char *pattern;\n+\teach_ref_fn *fn;\n+\tvoid *cb_data;\n+};\n+\n+static int filter_refs(const char *refname, const unsigned char *sha1, int flags,\n+\t\t       void *data)\n+{\n+\tstruct ref_filter *filter = (struct ref_filter *)data;\n+\tif (wildmatch(filter->pattern, refname, 0, NULL))\n+\t\treturn 0;\n+\treturn filter->fn(refname, sha1, flags, filter->cb_data);\n+}\n+\n+int for_each_tag_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn for_each_ref_in(\"refs/tags/\", fn, cb_data);\n+}\n+\n+int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n+{\n+\treturn for_each_ref_in_submodule(submodule, \"refs/tags/\", fn, cb_data);\n+}\n+\n+int for_each_branch_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn for_each_ref_in(\"refs/heads/\", fn, cb_data);\n+}\n+\n+int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n+{\n+\treturn for_each_ref_in_submodule(submodule, \"refs/heads/\", fn, cb_data);\n+}\n+\n+int for_each_remote_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn for_each_ref_in(\"refs/remotes/\", fn, cb_data);\n+}\n+\n+int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n+{\n+\treturn for_each_ref_in_submodule(submodule, \"refs/remotes/\", fn, cb_data);\n+}\n+\n+int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,\n+\tconst char *prefix, void *cb_data)\n+{\n+\tstruct strbuf real_pattern = STRBUF_INIT;\n+\tstruct ref_filter filter;\n+\tint ret;\n+\n+\tif (!prefix && !starts_with(pattern, \"refs/\"))\n+\t\tstrbuf_addstr(&real_pattern, \"refs/\");\n+\telse if (prefix)\n+\t\tstrbuf_addstr(&real_pattern, prefix);\n+\tstrbuf_addstr(&real_pattern, pattern);\n+\n+\tif (!has_glob_specials(pattern)) {\n+\t\t/* Append implied '/' '*' if not present. */\n+\t\tif (real_pattern.buf[real_pattern.len - 1] != '/')\n+\t\t\tstrbuf_addch(&real_pattern, '/');\n+\t\t/* No need to check for '*', there is none. */\n+\t\tstrbuf_addch(&real_pattern, '*');\n+\t}\n+\n+\tfilter.pattern = real_pattern.buf;\n+\tfilter.fn = fn;\n+\tfilter.cb_data = cb_data;\n+\tret = for_each_ref(filter_refs, &filter);\n+\n+\tstrbuf_release(&real_pattern);\n+\treturn ret;\n+}\n+\n+int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n+{\n+\treturn for_each_glob_ref_in(fn, pattern, NULL, cb_data);\n+}\n+\n int check_refname_format(const char *refname, int flags)\n {\n \tint component_len, component_count = 0;\ndiff --git a/refs.c b/refs.c\nindex fb9c614..9aa88ef 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1377,22 +1377,6 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int fla\n \t}\n }\n \n-/* The argument to filter_refs */\n-struct ref_filter {\n-\tconst char *pattern;\n-\teach_ref_fn *fn;\n-\tvoid *cb_data;\n-};\n-\n-static int filter_refs(const char *refname, const unsigned char *sha1, int flags,\n-\t\t       void *data)\n-{\n-\tstruct ref_filter *filter = (struct ref_filter *)data;\n-\tif (wildmatch(filter->pattern, refname, 0, NULL))\n-\t\treturn 0;\n-\treturn filter->fn(refname, sha1, flags, filter->cb_data);\n-}\n-\n enum peel_status {\n \t/* object was peeled successfully: */\n \tPEEL_PEELED = 0,\n@@ -1646,36 +1630,6 @@ int for_each_ref_in_submodule(const char *submodule, const char *prefix,\n \treturn do_for_each_ref(get_ref_cache(submodule), prefix, fn, strlen(prefix), 0, cb_data);\n }\n \n-int for_each_tag_ref(each_ref_fn fn, void *cb_data)\n-{\n-\treturn for_each_ref_in(\"refs/tags/\", fn, cb_data);\n-}\n-\n-int for_each_tag_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n-{\n-\treturn for_each_ref_in_submodule(submodule, \"refs/tags/\", fn, cb_data);\n-}\n-\n-int for_each_branch_ref(each_ref_fn fn, void *cb_data)\n-{\n-\treturn for_each_ref_in(\"refs/heads/\", fn, cb_data);\n-}\n-\n-int for_each_branch_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n-{\n-\treturn for_each_ref_in_submodule(submodule, \"refs/heads/\", fn, cb_data);\n-}\n-\n-int for_each_remote_ref(each_ref_fn fn, void *cb_data)\n-{\n-\treturn for_each_ref_in(\"refs/remotes/\", fn, cb_data);\n-}\n-\n-int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n-{\n-\treturn for_each_ref_in_submodule(submodule, \"refs/remotes/\", fn, cb_data);\n-}\n-\n int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(&ref_cache, \"refs/replace/\", fn, 13, 0, cb_data);\n@@ -1706,41 +1660,6 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)\n \treturn ret;\n }\n \n-int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,\n-\tconst char *prefix, void *cb_data)\n-{\n-\tstruct strbuf real_pattern = STRBUF_INIT;\n-\tstruct ref_filter filter;\n-\tint ret;\n-\n-\tif (!prefix && !starts_with(pattern, \"refs/\"))\n-\t\tstrbuf_addstr(&real_pattern, \"refs/\");\n-\telse if (prefix)\n-\t\tstrbuf_addstr(&real_pattern, prefix);\n-\tstrbuf_addstr(&real_pattern, pattern);\n-\n-\tif (!has_glob_specials(pattern)) {\n-\t\t/* Append implied '/' '*' if not present. */\n-\t\tif (real_pattern.buf[real_pattern.len - 1] != '/')\n-\t\t\tstrbuf_addch(&real_pattern, '/');\n-\t\t/* No need to check for '*', there is none. */\n-\t\tstrbuf_addch(&real_pattern, '*');\n-\t}\n-\n-\tfilter.pattern = real_pattern.buf;\n-\tfilter.fn = fn;\n-\tfilter.cb_data = cb_data;\n-\tret = for_each_ref(filter_refs, &filter);\n-\n-\tstrbuf_release(&real_pattern);\n-\treturn ret;\n-}\n-\n-int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data)\n-{\n-\treturn for_each_glob_ref_in(fn, pattern, NULL, cb_data);\n-}\n-\n int for_each_rawref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(&ref_cache, \"\", fn, 0,\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247698","messageId":"1407960907-18189-18-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 17/23] refs-common.c: move head_ref_namespaced to the common file","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:15:01Z","receivedAt":"2014-08-13T20:15:01Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 15 +++++++++++++++\n refs.c        | 15 ---------------\n 2 files changed, 15 insertions(+), 15 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 3b20db3..aafc4c8 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -570,6 +570,21 @@ void warn_dangling_symrefs(FILE *fp, const char *msg_fmt, const struct string_li\n \tfor_each_rawref(warn_if_dangling_symref, &data);\n }\n \n+int head_ref_namespaced(each_ref_fn fn, void *cb_data)\n+{\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint ret = 0;\n+\tunsigned char sha1[20];\n+\tint flag;\n+\n+\tstrbuf_addf(&buf, \"%sHEAD\", get_git_namespace());\n+\tif (!read_ref_full(buf.buf, sha1, RESOLVE_REF_READING, &flag))\n+\t\tret = fn(buf.buf, sha1, flag, cb_data);\n+\tstrbuf_release(&buf);\n+\n+\treturn ret;\n+}\n+\n int read_ref_full(const char *refname, unsigned char *sha1, int flags, int *ref_flag)\n {\n \tif (resolve_ref_unsafe(refname, sha1, flags, ref_flag))\ndiff --git a/refs.c b/refs.c\nindex 9aa88ef..e58a7e1 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1635,21 +1635,6 @@ int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n \treturn do_for_each_ref(&ref_cache, \"refs/replace/\", fn, 13, 0, cb_data);\n }\n \n-int head_ref_namespaced(each_ref_fn fn, void *cb_data)\n-{\n-\tstruct strbuf buf = STRBUF_INIT;\n-\tint ret = 0;\n-\tunsigned char sha1[20];\n-\tint flag;\n-\n-\tstrbuf_addf(&buf, \"%sHEAD\", get_git_namespace());\n-\tif (!read_ref_full(buf.buf, sha1, RESOLVE_REF_READING, &flag))\n-\t\tret = fn(buf.buf, sha1, flag, cb_data);\n-\tstrbuf_release(&buf);\n-\n-\treturn ret;\n-}\n-\n int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247695","messageId":"1407960907-18189-19-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 18/23] refs.c: add a backend method structure with transaction functions","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:15:02Z","receivedAt":"2014-08-13T20:15:02Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Add a ref structure for backend methods. Start by adding method pointers\nfor the transaction functions.\n\nRename the existing transaction functions to files_* and make them static.\nAdd new transaction functions that just pass through to the appropriate\nmethods for the backend.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++\n refs.c        | 68 +++++++++++++++++++++++++++++++++++------------------------\n refs.h        | 35 ++++++++++++++++++++++++++++++\n 3 files changed, 130 insertions(+), 27 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex aafc4c8..e7cea02 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -799,3 +799,57 @@ int check_refname_format(const char *refname, int flags)\n \t\treturn -1; /* Refname has only one component. */\n \treturn 0;\n }\n+\n+/* backend functions */\n+struct ref_transaction *transaction_begin(struct strbuf *err)\n+{\n+\treturn refs->transaction_begin(err);\n+}\n+\n+int transaction_update_sha1(struct ref_transaction *transaction,\n+\t\t\t    const char *refname, const unsigned char *new_sha1,\n+\t\t\t    const unsigned char *old_sha1, int flags,\n+\t\t\t    int have_old, const char *msg, struct strbuf *err)\n+{\n+\treturn refs->transaction_update_sha1(transaction, refname, new_sha1,\n+\t\t\t\t\t     old_sha1, flags, have_old, msg,\n+\t\t\t\t\t     err);\n+}\n+\n+int transaction_create_sha1(struct ref_transaction *transaction,\n+\t\t\t    const char *refname, const unsigned char *new_sha1,\n+\t\t\t    int flags, const char *msg, struct strbuf *err)\n+{\n+\treturn refs->transaction_create_sha1(transaction, refname, new_sha1,\n+\t\t\t\t\t     flags, msg, err);\n+}\n+int transaction_delete_sha1(struct ref_transaction *transaction,\n+\t\t\t    const char *refname, const unsigned char *old_sha1,\n+\t\t\t    int flags, int have_old, const char *msg,\n+\t\t\t    struct strbuf *err)\n+{\n+\treturn refs->transaction_delete_sha1(transaction, refname, old_sha1,\n+\t\t\t\t\t     flags, have_old, msg, err);\n+}\n+\n+int transaction_update_reflog(struct ref_transaction *transaction,\n+\t\t\t      const char *refname,\n+\t\t\t      const unsigned char *new_sha1,\n+\t\t\t      const unsigned char *old_sha1,\n+\t\t\t      struct reflog_committer_info *ci,\n+\t\t\t      const char *msg, int flags,\n+\t\t\t      struct strbuf *err)\n+{\n+\treturn refs->transaction_update_reflog(transaction, refname, new_sha1,\n+\t\t\t\t\t       old_sha1, ci, msg, flags, err);\n+}\n+\n+int transaction_commit(struct ref_transaction *transaction, struct strbuf *err)\n+{\n+\treturn refs->transaction_commit(transaction, err);\n+}\n+\n+void transaction_free(struct ref_transaction *transaction)\n+{\n+\treturn refs->transaction_free(transaction);\n+}\ndiff --git a/refs.c b/refs.c\nindex e58a7e1..27eafd0 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2777,12 +2777,12 @@ struct ref_transaction {\n \tenum ref_transaction_state state;\n };\n \n-struct ref_transaction *transaction_begin(struct strbuf *err)\n+static struct ref_transaction *files_transaction_begin(struct strbuf *err)\n {\n \treturn xcalloc(1, sizeof(struct ref_transaction));\n }\n \n-void transaction_free(struct ref_transaction *transaction)\n+static void files_transaction_free(struct ref_transaction *transaction)\n {\n \tint i;\n \n@@ -2812,13 +2812,13 @@ static struct ref_update *add_update(struct ref_transaction *transaction,\n \treturn update;\n }\n \n-int transaction_update_reflog(struct ref_transaction *transaction,\n-\t\t\t      const char *refname,\n-\t\t\t      const unsigned char *new_sha1,\n-\t\t\t      const unsigned char *old_sha1,\n-\t\t\t      struct reflog_committer_info *ci,\n-\t\t\t      const char *msg, int flags,\n-\t\t\t      struct strbuf *err)\n+static int files_transaction_update_reflog(struct ref_transaction *transaction,\n+\t\t\t\t\t   const char *refname,\n+\t\t\t\t\t   const unsigned char *new_sha1,\n+\t\t\t\t\t   const unsigned char *old_sha1,\n+\t\t\t\t\t   struct reflog_committer_info *ci,\n+\t\t\t\t\t   const char *msg, int flags,\n+\t\t\t\t\t   struct strbuf *err)\n {\n \tstruct ref_update *update;\n \tint i;\n@@ -2865,12 +2865,13 @@ int transaction_update_reflog(struct ref_transaction *transaction,\n \treturn 0;\n }\n \n-int transaction_update_sha1(struct ref_transaction *transaction,\n-\t\t\t    const char *refname,\n-\t\t\t    const unsigned char *new_sha1,\n-\t\t\t    const unsigned char *old_sha1,\n-\t\t\t    int flags, int have_old, const char *msg,\n-\t\t\t    struct strbuf *err)\n+static int files_transaction_update_sha1(struct ref_transaction *transaction,\n+\t\t\t\t\t const char *refname,\n+\t\t\t\t\t const unsigned char *new_sha1,\n+\t\t\t\t\t const unsigned char *old_sha1,\n+\t\t\t\t\t int flags, int have_old,\n+\t\t\t\t\t const char *msg,\n+\t\t\t\t\t struct strbuf *err)\n {\n \tstruct ref_update *update;\n \n@@ -2897,11 +2898,11 @@ int transaction_update_sha1(struct ref_transaction *transaction,\n \treturn 0;\n }\n \n-int transaction_create_sha1(struct ref_transaction *transaction,\n-\t\t\t    const char *refname,\n-\t\t\t    const unsigned char *new_sha1,\n-\t\t\t    int flags, const char *msg,\n-\t\t\t    struct strbuf *err)\n+static int files_transaction_create_sha1(struct ref_transaction *transaction,\n+\t\t\t\t\t const char *refname,\n+\t\t\t\t\t const unsigned char *new_sha1,\n+\t\t\t\t\t int flags, const char *msg,\n+\t\t\t\t\t struct strbuf *err)\n {\n \tif (transaction->state != REF_TRANSACTION_OPEN)\n \t\tdie(\"BUG: create called for transaction that is not open\");\n@@ -2913,11 +2914,12 @@ int transaction_create_sha1(struct ref_transaction *transaction,\n \t\t\t\t       null_sha1, flags, 1, msg, err);\n }\n \n-int transaction_delete_sha1(struct ref_transaction *transaction,\n-\t\t\t    const char *refname,\n-\t\t\t    const unsigned char *old_sha1,\n-\t\t\t    int flags, int have_old, const char *msg,\n-\t\t\t    struct strbuf *err)\n+static int files_transaction_delete_sha1(struct ref_transaction *transaction,\n+\t\t\t\t\t const char *refname,\n+\t\t\t\t\t const unsigned char *old_sha1,\n+\t\t\t\t\t int flags, int have_old,\n+\t\t\t\t\t const char *msg,\n+\t\t\t\t\t struct strbuf *err)\n {\n \tif (transaction->state != REF_TRANSACTION_OPEN)\n \t\tdie(\"BUG: delete called for transaction that is not open\");\n@@ -2959,8 +2961,8 @@ static int ref_update_reject_duplicates(struct ref_update **updates, int n,\n \treturn 0;\n }\n \n-int transaction_commit(struct ref_transaction *transaction,\n-\t\t       struct strbuf *err)\n+static int files_transaction_commit(struct ref_transaction *transaction,\n+\t\t\t\t    struct strbuf *err)\n {\n \tint ret = 0, delnum = 0, i, df_conflict = 0, need_repack = 0;\n \tint num_updates = 0;\n@@ -3284,3 +3286,15 @@ cleanup:\n \t\tret = -2;\n \treturn ret;\n }\n+\n+struct ref_be refs_files = {\n+\tfiles_transaction_begin,\n+\tfiles_transaction_update_sha1,\n+\tfiles_transaction_create_sha1,\n+\tfiles_transaction_delete_sha1,\n+\tfiles_transaction_update_reflog,\n+\tfiles_transaction_commit,\n+\tfiles_transaction_free,\n+};\n+\n+struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex a14fc5d..4b669f5 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -350,4 +350,39 @@ int update_ref(const char *action, const char *refname,\n extern int parse_hide_refs_config(const char *var, const char *value, const char *);\n extern int ref_is_hidden(const char *);\n \n+\n+/* refs backends */\n+typedef struct ref_transaction *(*transaction_begin_fn)(struct strbuf *err);\n+typedef int (*transaction_update_sha1_fn)(struct ref_transaction *transaction,\n+\t\tconst char *refname, const unsigned char *new_sha1,\n+\t\tconst unsigned char *old_sha1, int flags, int have_old,\n+\t\tconst char *msg, struct strbuf *err);\n+typedef int (*transaction_create_sha1_fn)(struct ref_transaction *transaction,\n+\t\tconst char *refname, const unsigned char *new_sha1,\n+\t\tint flags, const char *msg, struct strbuf *err);\n+typedef int (*transaction_delete_sha1_fn)(struct ref_transaction *transaction,\n+\t\tconst char *refname, const unsigned char *old_sha1,\n+\t\tint flags, int have_old, const char *msg, struct strbuf *err);\n+typedef int (*transaction_update_reflog_fn)(\n+\t\tstruct ref_transaction *transaction,\n+\t\tconst char *refname, const unsigned char *new_sha1,\n+\t\tconst unsigned char *old_sha1,\n+\t\tstruct reflog_committer_info *ci,\n+\t\tconst char *msg, int flags, struct strbuf *err);\n+typedef int (*transaction_commit_fn)(struct ref_transaction *transaction,\n+\t\t\t\t       struct strbuf *err);\n+typedef void (*transaction_free_fn)(struct ref_transaction *transaction);\n+\n+struct ref_be {\n+\ttransaction_begin_fn transaction_begin;\n+\ttransaction_update_sha1_fn transaction_update_sha1;\n+\ttransaction_create_sha1_fn transaction_create_sha1;\n+\ttransaction_delete_sha1_fn transaction_delete_sha1;\n+\ttransaction_update_reflog_fn transaction_update_reflog;\n+\ttransaction_commit_fn transaction_commit;\n+\ttransaction_free_fn transaction_free;\n+};\n+\n+extern struct ref_be *refs;\n+\n #endif /* REFS_H */\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247689","messageId":"1407960907-18189-20-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 19/23] refs.c: add reflog backend methods","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:15:03Z","receivedAt":"2014-08-13T20:15:03Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Add methods for the reflog functions.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 32 ++++++++++++++++++++++++++++++++\n refs.c        | 18 ++++++++++++------\n refs.h        | 17 +++++++++++++++++\n 3 files changed, 61 insertions(+), 6 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex e7cea02..68152d6 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -853,3 +853,35 @@ void transaction_free(struct ref_transaction *transaction)\n {\n \treturn refs->transaction_free(transaction);\n }\n+\n+int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,\n+\t\t\t\tvoid *cb_data)\n+{\n+\treturn refs->for_each_reflog_ent_reverse(refname, fn, cb_data);\n+}\n+\n+int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,\n+\t\t\tvoid *cb_data)\n+{\n+\treturn refs->for_each_reflog_ent(refname, fn, cb_data);\n+}\n+\n+int for_each_reflog(each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_reflog(fn, cb_data);\n+}\n+\n+int reflog_exists(const char *refname)\n+{\n+\treturn refs->reflog_exists(refname);\n+}\n+\n+int create_reflog(const char *refname)\n+{\n+\treturn refs->create_reflog(refname);\n+}\n+\n+int delete_reflog(const char *refname)\n+{\n+\treturn refs->delete_reflog(refname);\n+}\ndiff --git a/refs.c b/refs.c\nindex 27eafd0..699b548 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2251,7 +2251,7 @@ static int copy_msg(char *buf, const char *msg)\n }\n \n /* This function must set a meaningful errno on failure */\n-int create_reflog(const char *refname)\n+static int files_create_reflog(const char *refname)\n {\n \tint logfd, oflags = O_APPEND | O_WRONLY;\n \tchar logfile[PATH_MAX];\n@@ -2516,7 +2516,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,\n \treturn 0;\n }\n \n-int reflog_exists(const char *refname)\n+static int files_reflog_exists(const char *refname)\n {\n \tstruct stat st;\n \n@@ -2524,7 +2524,7 @@ int reflog_exists(const char *refname)\n \t\tS_ISREG(st.st_mode);\n }\n \n-int delete_reflog(const char *refname)\n+static int files_delete_reflog(const char *refname)\n {\n \treturn remove_path(git_path(\"logs/%s\", refname));\n }\n@@ -2568,7 +2568,7 @@ static char *find_beginning_of_line(char *bob, char *scan)\n \treturn scan;\n }\n \n-int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data)\n+static int files_for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data)\n {\n \tstruct strbuf sb = STRBUF_INIT;\n \tFILE *logfp;\n@@ -2645,7 +2645,7 @@ int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void\n \treturn ret;\n }\n \n-int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data)\n+static int files_for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data)\n {\n \tFILE *logfp;\n \tstruct strbuf sb = STRBUF_INIT;\n@@ -2706,7 +2706,7 @@ static int do_for_each_reflog(struct strbuf *name, each_ref_fn fn, void *cb_data\n \treturn retval;\n }\n \n-int for_each_reflog(each_ref_fn fn, void *cb_data)\n+static int files_for_each_reflog(each_ref_fn fn, void *cb_data)\n {\n \tint retval;\n \tstruct strbuf name;\n@@ -3295,6 +3295,12 @@ struct ref_be refs_files = {\n \tfiles_transaction_update_reflog,\n \tfiles_transaction_commit,\n \tfiles_transaction_free,\n+\tfiles_for_each_reflog_ent,\n+\tfiles_for_each_reflog_ent_reverse,\n+\tfiles_for_each_reflog,\n+\tfiles_reflog_exists,\n+\tfiles_create_reflog,\n+\tfiles_delete_reflog,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex 4b669f5..302eb03 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -373,6 +373,17 @@ typedef int (*transaction_commit_fn)(struct ref_transaction *transaction,\n \t\t\t\t       struct strbuf *err);\n typedef void (*transaction_free_fn)(struct ref_transaction *transaction);\n \n+typedef int (*for_each_reflog_ent_fn)(const char *refname,\n+\t\t\t\t      each_reflog_ent_fn fn,\n+\t\t\t\t      void *cb_data);\n+typedef int (*for_each_reflog_ent_reverse_fn)(const char *refname,\n+\t\t\t\t\t      each_reflog_ent_fn fn,\n+\t\t\t\t\t      void *cb_data);\n+typedef int (*for_each_reflog_fn)(each_ref_fn fn, void *cb_data);\n+typedef int (*reflog_exists_fn)(const char *refname);\n+typedef int (*create_reflog_fn)(const char *refname);\n+typedef int (*delete_reflog_fn)(const char *refname);\n+\n struct ref_be {\n \ttransaction_begin_fn transaction_begin;\n \ttransaction_update_sha1_fn transaction_update_sha1;\n@@ -381,6 +392,12 @@ struct ref_be {\n \ttransaction_update_reflog_fn transaction_update_reflog;\n \ttransaction_commit_fn transaction_commit;\n \ttransaction_free_fn transaction_free;\n+\tfor_each_reflog_ent_fn for_each_reflog_ent;\n+\tfor_each_reflog_ent_reverse_fn for_each_reflog_ent_reverse;\n+\tfor_each_reflog_fn for_each_reflog;\n+\treflog_exists_fn reflog_exists;\n+\tcreate_reflog_fn create_reflog;\n+\tdelete_reflog_fn delete_reflog;\n };\n \n extern struct ref_be *refs;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247693","messageId":"1407960907-18189-21-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 20/23] refs.c: add methods for misc ref operations","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:15:04Z","receivedAt":"2014-08-13T20:15:04Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Add ref backend methods for:\nresolve_ref_unsafe, is_refname_available, pack_refs, peel_ref,\ncreate_symref, resolve_gitlink_ref.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 33 +++++++++++++++++++++++++++++++++\n refs.c        | 22 +++++++++++++++-------\n refs.h        | 19 +++++++++++++++++++\n 3 files changed, 67 insertions(+), 7 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 68152d6..d9688e2 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -885,3 +885,36 @@ int delete_reflog(const char *refname)\n {\n \treturn refs->delete_reflog(refname);\n }\n+\n+const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1,\n+\t\t\t       int reading, int *flag)\n+{\n+\treturn refs->resolve_ref_unsafe(ref, sha1, reading, flag);\n+}\n+\n+int is_refname_available(const char *refname, const char **skip, int skipnum)\n+{\n+\treturn refs->is_refname_available(refname, skip, skipnum);\n+}\n+\n+int pack_refs(unsigned int flags, struct strbuf *err)\n+{\n+\treturn refs->pack_refs(flags, err);\n+}\n+\n+int peel_ref(const char *refname, unsigned char *sha1)\n+{\n+\treturn refs->peel_ref(refname, sha1);\n+}\n+\n+int create_symref(const char *ref_target, const char *refs_heads_master,\n+\t\t  const char *logmsg)\n+{\n+\treturn refs->create_symref(ref_target, refs_heads_master, logmsg);\n+}\n+\n+int resolve_gitlink_ref(const char *path, const char *refname,\n+\t\t\tunsigned char *sha1)\n+{\n+\treturn refs->resolve_gitlink_ref(path, refname, sha1);\n+}\ndiff --git a/refs.c b/refs.c\nindex 699b548..9439809 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1114,7 +1114,8 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs)\n \treturn get_ref_dir(refs->loose);\n }\n \n-int is_refname_available(const char *refname, const char **skip, int skipnum)\n+static int files_is_refname_available(const char *refname, const char **skip,\n+\t\t\t\t      int skipnum)\n {\n \tif (!is_refname_available_dir(refname, get_packed_refs(&ref_cache),\n \t\t\t\t      skip, skipnum))\n@@ -1188,7 +1189,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs,\n \treturn resolve_gitlink_ref_recursive(refs, p, sha1, recursion+1);\n }\n \n-int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)\n+static int files_resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sha1)\n {\n \tint len = strlen(path), retval;\n \tchar *submodule;\n@@ -1247,7 +1248,7 @@ static const char *handle_missing_loose_ref(const char *refname,\n }\n \n /* This function needs to return a meaningful errno on failure */\n-const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int flags, int *ref_flag)\n+static const char *files_resolve_ref_unsafe(const char *refname, unsigned char *sha1, int flags, int *ref_flag)\n {\n \tint depth = MAXDEPTH;\n \tssize_t len;\n@@ -1466,7 +1467,7 @@ static enum peel_status peel_entry(struct ref_entry *entry, int repeel)\n \treturn status;\n }\n \n-int peel_ref(const char *refname, unsigned char *sha1)\n+static int files_peel_ref(const char *refname, unsigned char *sha1)\n {\n \tint flag;\n \tunsigned char base[20];\n@@ -2080,7 +2081,7 @@ static void prune_refs(struct ref_to_prune *r)\n \t}\n }\n \n-int pack_refs(unsigned int flags, struct strbuf *err)\n+static int files_pack_refs(unsigned int flags, struct strbuf *err)\n {\n \tstruct pack_refs_cb_data cbdata;\n \n@@ -2453,8 +2454,9 @@ static int write_ref_sha1(struct ref_lock *lock,\n \treturn 0;\n }\n \n-int create_symref(const char *ref_target, const char *refs_heads_master,\n-\t\t  const char *logmsg)\n+static int files_create_symref(const char *ref_target,\n+\t\t\t       const char *refs_heads_master,\n+\t\t\t       const char *logmsg)\n {\n \tconst char *lockpath;\n \tchar ref[1000];\n@@ -3301,6 +3303,12 @@ struct ref_be refs_files = {\n \tfiles_reflog_exists,\n \tfiles_create_reflog,\n \tfiles_delete_reflog,\n+\tfiles_resolve_ref_unsafe,\n+\tfiles_is_refname_available,\n+\tfiles_pack_refs,\n+\tfiles_peel_ref,\n+\tfiles_create_symref,\n+\tfiles_resolve_gitlink_ref,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex 302eb03..ab120c5 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -384,6 +384,19 @@ typedef int (*reflog_exists_fn)(const char *refname);\n typedef int (*create_reflog_fn)(const char *refname);\n typedef int (*delete_reflog_fn)(const char *refname);\n \n+typedef const char *(*resolve_ref_unsafe_fn)(const char *ref,\n+\t\tunsigned char *sha1, int reading, int *flag);\n+\n+typedef int (*is_refname_available_fn)(const char *refname, const char **skip,\n+\t\t\t\t       int skipnum);\n+typedef int (*pack_refs_fn)(unsigned int flags, struct strbuf *err);\n+typedef int (*peel_ref_fn)(const char *refname, unsigned char *sha1);\n+typedef int (*create_symref_fn)(const char *ref_target,\n+\t\t\t\tconst char *refs_heads_master,\n+\t\t\t\tconst char *logmsg);\n+typedef int (*resolve_gitlink_ref_fn)(const char *path, const char *refname,\n+\t\t\t\t      unsigned char *sha1);\n+\n struct ref_be {\n \ttransaction_begin_fn transaction_begin;\n \ttransaction_update_sha1_fn transaction_update_sha1;\n@@ -398,6 +411,12 @@ struct ref_be {\n \treflog_exists_fn reflog_exists;\n \tcreate_reflog_fn create_reflog;\n \tdelete_reflog_fn delete_reflog;\n+\tresolve_ref_unsafe_fn resolve_ref_unsafe;\n+\tis_refname_available_fn is_refname_available;\n+\tpack_refs_fn pack_refs;\n+\tpeel_ref_fn peel_ref;\n+\tcreate_symref_fn create_symref;\n+\tresolve_gitlink_ref_fn resolve_gitlink_ref;\n };\n \n extern struct ref_be *refs;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247688","messageId":"1407960907-18189-22-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 21/23] refs.c: add methods for head_ref*","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:15:05Z","receivedAt":"2014-08-13T20:15:05Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Add methods for the head_ref* functions.\n\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 10 ++++++++++\n refs.c        |  6 ++++--\n refs.h        |  6 ++++++\n 3 files changed, 20 insertions(+), 2 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex d9688e2..f19402b 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -918,3 +918,13 @@ int resolve_gitlink_ref(const char *path, const char *refname,\n {\n \treturn refs->resolve_gitlink_ref(path, refname, sha1);\n }\n+\n+int head_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->head_ref(fn, cb_data);\n+}\n+\n+int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->head_ref_submodule(submodule, fn, cb_data);\n+}\ndiff --git a/refs.c b/refs.c\nindex 9439809..7ad07f1 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1600,12 +1600,12 @@ static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n \treturn 0;\n }\n \n-int head_ref(each_ref_fn fn, void *cb_data)\n+static int files_head_ref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_head_ref(NULL, fn, cb_data);\n }\n \n-int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n+static int files_head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n \treturn do_head_ref(submodule, fn, cb_data);\n }\n@@ -3309,6 +3309,8 @@ struct ref_be refs_files = {\n \tfiles_peel_ref,\n \tfiles_create_symref,\n \tfiles_resolve_gitlink_ref,\n+\tfiles_head_ref,\n+\tfiles_head_ref_submodule,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex ab120c5..420e9b5 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -397,6 +397,10 @@ typedef int (*create_symref_fn)(const char *ref_target,\n typedef int (*resolve_gitlink_ref_fn)(const char *path, const char *refname,\n \t\t\t\t      unsigned char *sha1);\n \n+typedef int (*head_ref_fn)(each_ref_fn fn, void *cb_data);\n+typedef int (*head_ref_submodule_fn)(const char *submodule, each_ref_fn fn,\n+\t\t\t\t     void *cb_data);\n+\n struct ref_be {\n \ttransaction_begin_fn transaction_begin;\n \ttransaction_update_sha1_fn transaction_update_sha1;\n@@ -417,6 +421,8 @@ struct ref_be {\n \tpeel_ref_fn peel_ref;\n \tcreate_symref_fn create_symref;\n \tresolve_gitlink_ref_fn resolve_gitlink_ref;\n+\thead_ref_fn head_ref;\n+\thead_ref_submodule_fn head_ref_submodule;\n };\n \n extern struct ref_be *refs;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247696","messageId":"1407960907-18189-23-git-send-email-sahlberg@google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"[PATCH v2 22/23] refs.c: add methods for the ref iterators","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T20:15:06Z","receivedAt":"2014-08-13T20:15:06Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Signed-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 36 ++++++++++++++++++++++++++++++++++++\n refs.c        | 21 ++++++++++++++-------\n refs.h        | 19 +++++++++++++++++++\n 3 files changed, 69 insertions(+), 7 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex f19402b..3df725d 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -928,3 +928,39 @@ int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n \treturn refs->head_ref_submodule(submodule, fn, cb_data);\n }\n+ \n+int for_each_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_ref(fn, cb_data);\n+}\n+\n+int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_ref_submodule(submodule, fn, cb_data);\n+}\n+\n+int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_ref_in(prefix, fn, cb_data);\n+}\n+\n+int for_each_ref_in_submodule(const char *submodule, const char *prefix,\n+\t\t\t      each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_ref_in_submodule(submodule, prefix, fn, cb_data);\n+}\n+\n+int for_each_rawref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_rawref(fn, cb_data);\n+}\n+\n+int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_namespaced_ref(fn, cb_data);\n+}\n+\n+int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->for_each_replace_ref(fn, cb_data);\n+}\ndiff --git a/refs.c b/refs.c\nindex 7ad07f1..dc0467a 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1610,33 +1610,33 @@ static int files_head_ref_submodule(const char *submodule, each_ref_fn fn, void\n \treturn do_head_ref(submodule, fn, cb_data);\n }\n \n-int for_each_ref(each_ref_fn fn, void *cb_data)\n+static int files_for_each_ref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(&ref_cache, \"\", fn, 0, 0, cb_data);\n }\n \n-int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n+static int files_for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(get_ref_cache(submodule), \"\", fn, 0, 0, cb_data);\n }\n \n-int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)\n+static int files_for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(&ref_cache, prefix, fn, strlen(prefix), 0, cb_data);\n }\n \n-int for_each_ref_in_submodule(const char *submodule, const char *prefix,\n+static int files_for_each_ref_in_submodule(const char *submodule, const char *prefix,\n \t\teach_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(get_ref_cache(submodule), prefix, fn, strlen(prefix), 0, cb_data);\n }\n \n-int for_each_replace_ref(each_ref_fn fn, void *cb_data)\n+static int files_for_each_replace_ref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(&ref_cache, \"refs/replace/\", fn, 13, 0, cb_data);\n }\n \n-int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)\n+static int files_for_each_namespaced_ref(each_ref_fn fn, void *cb_data)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tint ret;\n@@ -1646,7 +1646,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)\n \treturn ret;\n }\n \n-int for_each_rawref(each_ref_fn fn, void *cb_data)\n+static int files_for_each_rawref(each_ref_fn fn, void *cb_data)\n {\n \treturn do_for_each_ref(&ref_cache, \"\", fn, 0,\n \t\t\t       DO_FOR_EACH_INCLUDE_BROKEN, cb_data);\n@@ -3311,6 +3311,13 @@ struct ref_be refs_files = {\n \tfiles_resolve_gitlink_ref,\n \tfiles_head_ref,\n \tfiles_head_ref_submodule,\n+\tfiles_for_each_ref,\n+\tfiles_for_each_ref_submodule,\n+\tfiles_for_each_ref_in,\n+\tfiles_for_each_ref_in_submodule,\n+\tfiles_for_each_rawref,\n+\tfiles_for_each_namespaced_ref,\n+\tfiles_for_each_replace_ref,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex 420e9b5..249a14a 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -401,6 +401,18 @@ typedef int (*head_ref_fn)(each_ref_fn fn, void *cb_data);\n typedef int (*head_ref_submodule_fn)(const char *submodule, each_ref_fn fn,\n \t\t\t\t     void *cb_data);\n \n+typedef int (*for_each_ref_fn)(each_ref_fn fn, void *cb_data);\n+typedef int (*for_each_ref_submodule_fn)(const char *submodule, each_ref_fn fn,\n+\t\t\t\t\t void *cb_data);\n+typedef int (*for_each_ref_in_fn)(const char *prefix, each_ref_fn fn,\n+\t\t\t\t  void *cb_data);\n+typedef int (*for_each_ref_in_submodule_fn)(const char *submodule,\n+\t\t\t\t\t    const char *prefix,\n+\t\t\t\t\t    each_ref_fn fn, void *cb_data);\n+typedef int (*for_each_rawref_fn)(each_ref_fn fn, void *cb_data);\n+typedef int (*for_each_namespaced_ref_fn)(each_ref_fn fn, void *cb_data);\n+typedef int (*for_each_replace_ref_fn)(each_ref_fn fn, void *cb_data);\n+\n struct ref_be {\n \ttransaction_begin_fn transaction_begin;\n \ttransaction_update_sha1_fn transaction_update_sha1;\n@@ -423,6 +435,13 @@ struct ref_be {\n \tresolve_gitlink_ref_fn resolve_gitlink_ref;\n \thead_ref_fn head_ref;\n \thead_ref_submodule_fn head_ref_submodule;\n+\tfor_each_ref_fn for_each_ref;\n+\tfor_each_ref_submodule_fn for_each_ref_submodule;\n+\tfor_each_ref_in_fn for_each_ref_in;\n+\tfor_each_ref_in_submodule_fn for_each_ref_in_submodule;\n+\tfor_each_rawref_fn for_each_rawref;\n+\tfor_each_namespaced_ref_fn for_each_namespaced_ref;\n+\tfor_each_replace_ref_fn for_each_replace_ref;\n };\n \n extern struct ref_be *refs;\n-- \n2.0.1.556.g3edca4c\n"},{"id":"247709","messageId":"xmqqmwb82im7.fsf@gitster.dls.corp.google.com","threadId":"37345","inReplyTo":"1407960907-18189-1-git-send-email-sahlberg@google.com","subject":"Re: [PATCH v2 00/23] backend-struct-db","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-13T21:18:56Z","receivedAt":"2014-08-13T21:18:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ronnie Sahlberg <sahlberg@google.com> writes:\n\n> 15 of the patches, the refs-common.c patches, focuses on moving all backend\n> agnostic refs functions to a common file. This file will contain all\n> backend agnostic refs functions.\n>\n> The last 6 patches adds a backend structure with the methods we need to\n> describe a pluggable backend. Currently we only have one built in backend,\n> the current files based backend. These patches do not change any of the\n> behavior other than that we now call the methods through backend specific\n> wrapper functions rather than calling them directly.\n>\n> At this stage we now have a defined set of methods needed for a refs\n> backend and we can start building and adding new types of ref backends\n> to git.\n\nVery nice ;-).\n\nI would have expected that refs.c would be the generic one and refs-be-*\nwould be the backend specific ones, though; that way you do not have to\nintroduce a new file refs-common.c at all, no?\n"},{"id":"247710","messageId":"CAL=YDWkg1D1JyBhT0Jr4ur+fv3rp9tGm+a-gSYBaixaAHKQ_EQ@mail.gmail.com","threadId":"37345","inReplyTo":"xmqqmwb82im7.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 00/23] backend-struct-db","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-13T21:55:45Z","receivedAt":"2014-08-13T21:55:45Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"On Wed, Aug 13, 2014 at 2:18 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Ronnie Sahlberg <sahlberg@google.com> writes:\n>\n>> 15 of the patches, the refs-common.c patches, focuses on moving all backend\n>> agnostic refs functions to a common file. This file will contain all\n>> backend agnostic refs functions.\n>>\n>> The last 6 patches adds a backend structure with the methods we need to\n>> describe a pluggable backend. Currently we only have one built in backend,\n>> the current files based backend. These patches do not change any of the\n>> behavior other than that we now call the methods through backend specific\n>> wrapper functions rather than calling them directly.\n>>\n>> At this stage we now have a defined set of methods needed for a refs\n>> backend and we can start building and adding new types of ref backends\n>> to git.\n>\n> Very nice ;-).\n>\n> I would have expected that refs.c would be the generic one and refs-be-*\n> would be the backend specific ones, though; that way you do not have to\n> introduce a new file refs-common.c at all, no?\n>\n\nMakes sense.\nLet me do those changes and then I will re-post sometime next week\nonce I get additional feedback on it.\n\n\nregards\nRonnie Sahlberg\n"},{"id":"248347","messageId":"xmqqha0zgcym.fsf@gitster.dls.corp.google.com","threadId":"37345","inReplyTo":"1407960907-18189-19-git-send-email-sahlberg@google.com","subject":"Re: [PATCH v2 18/23] refs.c: add a backend method structure with transaction functions","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-08-26T21:25:53Z","receivedAt":"2014-08-26T21:25:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ronnie Sahlberg <sahlberg@google.com> writes:\n\n> +struct ref_be {\n> +\ttransaction_begin_fn transaction_begin;\n> +\ttransaction_update_sha1_fn transaction_update_sha1;\n> +\ttransaction_create_sha1_fn transaction_create_sha1;\n> +\ttransaction_delete_sha1_fn transaction_delete_sha1;\n> +\ttransaction_update_reflog_fn transaction_update_reflog;\n> +\ttransaction_commit_fn transaction_commit;\n> +\ttransaction_free_fn transaction_free;\n> +};\n> +\n> +extern struct ref_be *refs;\n\nThe overall organization is nice, but please don't use such a short\nname for the systemwide default singleton instance, which should not\nbe accessed by normal code other than via helpers that implicitly\nuse that singleton (e.g. resolve_ref_unsafe() which invokes the\nmethod of the same name on the singleton, passing the parameters it\nreceived[*1*]).  The name will be used for other things (e.g. a\nlocal variable for a collection of refs) by code that do not care\nabout the underlying implementation of the helpers and will cause\nconfusion later.\n\nPerhaps the_refs_backend or something?\n\nAlso does the singleton have to be extern, not a static inside refs.c,\nperhaps with a setter function to switch it or something?\n\n\n[Reference]\n\n*1* A typical helper that uses the singleton looks like this:\n\n+const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1,\n+\t\t\t       int reading, int *flag)\n+{\n+\treturn refs->resolve_ref_unsafe(ref, sha1, reading, flag);\n+}\n"},{"id":"248353","messageId":"CAL=YDWmKvV8oLF=4eqdo8SjLVaFd7PmunN=1VBV3KojFJy+oEA@mail.gmail.com","threadId":"37345","inReplyTo":"xmqqha0zgcym.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 18/23] refs.c: add a backend method structure with transaction functions","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-26T22:11:45Z","receivedAt":"2014-08-26T22:11:45Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"On Tue, Aug 26, 2014 at 2:25 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Ronnie Sahlberg <sahlberg@google.com> writes:\n>\n>> +struct ref_be {\n>> +     transaction_begin_fn transaction_begin;\n>> +     transaction_update_sha1_fn transaction_update_sha1;\n>> +     transaction_create_sha1_fn transaction_create_sha1;\n>> +     transaction_delete_sha1_fn transaction_delete_sha1;\n>> +     transaction_update_reflog_fn transaction_update_reflog;\n>> +     transaction_commit_fn transaction_commit;\n>> +     transaction_free_fn transaction_free;\n>> +};\n>> +\n>> +extern struct ref_be *refs;\n>\n> The overall organization is nice, but please don't use such a short\n> name for the systemwide default singleton instance, which should not\n> be accessed by normal code other than via helpers that implicitly\n> use that singleton (e.g. resolve_ref_unsafe() which invokes the\n> method of the same name on the singleton, passing the parameters it\n> received[*1*]).  The name will be used for other things (e.g. a\n> local variable for a collection of refs) by code that do not care\n> about the underlying implementation of the helpers and will cause\n> confusion later.\n>\n> Perhaps the_refs_backend or something?\n>\n> Also does the singleton have to be extern, not a static inside refs.c,\n> perhaps with a setter function to switch it or something?\n>\n>\n\nThanks!\n\nI did these changes :\n1, rename to the_refs_backend\n2, add a function set_refs_backend()\n\nTo this series and update it at\nhttps://github.com/rsahlberg/git/tree/backend-struct-db\n\n\n\n> [Reference]\n>\n> *1* A typical helper that uses the singleton looks like this:\n>\n> +const char *resolve_ref_unsafe(const char *ref, unsigned char *sha1,\n> +                              int reading, int *flag)\n> +{\n> +       return refs->resolve_ref_unsafe(ref, sha1, reading, flag);\n> +}\n"}]}