{"thread":{"id":"37315","subject":"[PATCH 01/22] refs.c: create a public function for is_refname_available","startedAt":"2014-08-08T16:44:47Z","lastAt":"2014-08-11T15:00:58Z","messageCount":26,"participants":["Ronnie Sahlberg","David Turner"],"isPatch":true,"patchVersion":1,"patchTotal":22},"messages":[{"id":"247487","messageId":"1407516309-27989-1-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":null,"subject":"[PATCH 00/22] backend-struct-db","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:47Z","receivedAt":"2014-08-08T16:44:47Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"List,\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\n\n\nRonnie Sahlberg (22):\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.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 | 3343 +++++++++++++++++++++++++++++++++++++++++++++\n refs-common.c   |  956 +++++++++++++\n refs.c          | 4082 -------------------------------------------------------\n refs.h          |  117 ++\n 5 files changed, 4418 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.553.geee1b3e\n"},{"id":"247485","messageId":"1407516309-27989-2-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 01/22] refs.c: create a public function for is_refname_available","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:48Z","receivedAt":"2014-08-08T16:44:48Z","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..7b59044 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 is a particular refname is available for creation. skip contains\n+ * a list of refnames to exclude from the refname collission 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.553.geee1b3e\n"},{"id":"247503","messageId":"1407516309-27989-3-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 02/22] refs-common.c: create a file to host all common refs code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:49Z","receivedAt":"2014-08-08T16:44:49Z","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.553.geee1b3e\n"},{"id":"247486","messageId":"1407516309-27989-4-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 03/22] refs-common.c: move update_ref to refs-common.c","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:50Z","receivedAt":"2014-08-08T16:44:50Z","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.553.geee1b3e\n"},{"id":"247506","messageId":"1407516309-27989-5-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 04/22] refs-common.c: move delete_ref to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:51Z","receivedAt":"2014-08-08T16:44:51Z","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.553.geee1b3e\n"},{"id":"247502","messageId":"1407516309-27989-6-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 05/22] refs-common.c: move rename_ref to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:52Z","receivedAt":"2014-08-08T16:44:52Z","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.553.geee1b3e\n"},{"id":"247490","messageId":"1407516309-27989-7-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 06/22] refs-common.c: move read_ref_at to the refs common file","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:53Z","receivedAt":"2014-08-08T16:44:53Z","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.553.geee1b3e\n"},{"id":"247489","messageId":"1407516309-27989-8-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 07/22] refs-common.c: move the hidden refs functions to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:54Z","receivedAt":"2014-08-08T16:44:54Z","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.553.geee1b3e\n"},{"id":"247496","messageId":"1407516309-27989-9-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 08/22] refs-common.c: move dwim and friend functions to refs common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:55Z","receivedAt":"2014-08-08T16:44:55Z","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.553.geee1b3e\n"},{"id":"247498","messageId":"1407516309-27989-10-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 09/22] refs-common.c: move warn_if_dangling_symref* to refs-common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:56Z","receivedAt":"2014-08-08T16:44:56Z","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.553.geee1b3e\n"},{"id":"247504","messageId":"1407516309-27989-11-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 10/22] refs-common.c: move read_ref, read_ref_full and ref_exists to common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:57Z","receivedAt":"2014-08-08T16:44:57Z","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.553.geee1b3e\n"},{"id":"247488","messageId":"1407516309-27989-12-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 11/22] refs-common.c: move resolve_refdup to common","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:58Z","receivedAt":"2014-08-08T16:44:58Z","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.553.geee1b3e\n"},{"id":"247492","messageId":"1407516309-27989-13-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 12/22] refs-common.c: move check_refname_component to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:44:59Z","receivedAt":"2014-08-08T16:44:59Z","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.553.geee1b3e\n"},{"id":"247495","messageId":"1407516309-27989-14-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 13/22] refs-common.c: move is_branch to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:00Z","receivedAt":"2014-08-08T16:45: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 | 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.553.geee1b3e\n"},{"id":"247494","messageId":"1407516309-27989-15-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 14/22] refs-common.c: move names_conflict to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:01Z","receivedAt":"2014-08-08T16:45: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 |  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 7b59044..5577824 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.553.geee1b3e\n"},{"id":"247505","messageId":"1407516309-27989-16-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 15/22] refs-common.c: move prettify_refname to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:02Z","receivedAt":"2014-08-08T16:45:02Z","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.553.geee1b3e\n"},{"id":"247500","messageId":"1407516309-27989-17-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 16/22] refs-common.c: move ref iterators to the common code","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:03Z","receivedAt":"2014-08-08T16:45:03Z","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.553.geee1b3e\n"},{"id":"247497","messageId":"1407516309-27989-18-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 17/22] refs.c: add a backend method structure with transaction functions","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:04Z","receivedAt":"2014-08-08T16:45:04Z","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 3b20db3..d4782ad 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -784,3 +784,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 9aa88ef..bfb42d8 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2792,12 +2792,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@@ -2827,13 +2827,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@@ -2880,12 +2880,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@@ -2912,11 +2913,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@@ -2928,11 +2929,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@@ -2974,8 +2976,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@@ -3299,3 +3301,15 @@ cleanup:\n \t\tret = -2;\n \treturn ret;\n }\n+\n+struct ref_be refs_files = {\n+\t.transaction_begin\t\t= files_transaction_begin,\n+\t.transaction_update_sha1\t= files_transaction_update_sha1,\n+\t.transaction_create_sha1\t= files_transaction_create_sha1,\n+\t.transaction_delete_sha1\t= files_transaction_delete_sha1,\n+\t.transaction_update_reflog\t= files_transaction_update_reflog,\n+\t.transaction_commit\t\t= files_transaction_commit,\n+\t.transaction_free\t\t= files_transaction_free,\n+};\n+\n+struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex 5577824..7b92241 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.553.geee1b3e\n"},{"id":"247501","messageId":"1407516309-27989-19-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 18/22] refs.c: add reflog backend methods","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:05Z","receivedAt":"2014-08-08T16:45:05Z","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        | 19 +++++++++++++------\n refs.h        | 18 ++++++++++++++++++\n 3 files changed, 63 insertions(+), 6 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex d4782ad..083964f 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -838,3 +838,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 bfb42d8..49fd360 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -2266,7 +2266,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@@ -2531,7 +2531,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@@ -2539,7 +2539,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@@ -2583,7 +2583,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@@ -2660,7 +2660,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@@ -2721,7 +2721,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@@ -3310,6 +3310,13 @@ struct ref_be refs_files = {\n \t.transaction_update_reflog\t= files_transaction_update_reflog,\n \t.transaction_commit\t\t= files_transaction_commit,\n \t.transaction_free\t\t= files_transaction_free,\n+\n+\t.for_each_reflog_ent\t\t= files_for_each_reflog_ent,\n+\t.for_each_reflog_ent_reverse\t= files_for_each_reflog_ent_reverse,\n+\t.for_each_reflog\t\t= files_for_each_reflog,\n+\t.reflog_exists\t\t\t= files_reflog_exists,\n+\t.create_reflog\t\t\t= files_create_reflog,\n+\t.delete_reflog\t\t\t= files_delete_reflog,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex 7b92241..f630e20 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,13 @@ struct ref_be {\n \ttransaction_update_reflog_fn transaction_update_reflog;\n \ttransaction_commit_fn transaction_commit;\n \ttransaction_free_fn transaction_free;\n+\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.553.geee1b3e\n"},{"id":"247493","messageId":"1407516309-27989-20-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 19/22] refs.c: add methods for misc ref operations","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:06Z","receivedAt":"2014-08-08T16:45:06Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Add ref backend methods for\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\nSigned-off-by: Ronnie Sahlberg <sahlberg@google.com>\n---\n refs-common.c | 33 +++++++++++++++++++++++++++++++++\n refs.c        | 23 ++++++++++++++++-------\n refs.h        | 21 +++++++++++++++++++++\n 3 files changed, 70 insertions(+), 7 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 083964f..45e6fca 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -870,3 +870,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 49fd360..c4076f3 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@@ -2095,7 +2096,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@@ -2468,8 +2469,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@@ -3317,6 +3319,13 @@ struct ref_be refs_files = {\n \t.reflog_exists\t\t\t= files_reflog_exists,\n \t.create_reflog\t\t\t= files_create_reflog,\n \t.delete_reflog\t\t\t= files_delete_reflog,\n+\n+\t.resolve_ref_unsafe\t\t= files_resolve_ref_unsafe,\n+\t.is_refname_available\t\t= files_is_refname_available,\n+\t.pack_refs\t\t\t= files_pack_refs,\n+\t.peel_ref\t\t\t= files_peel_ref,\n+\t.create_symref\t\t\t= files_create_symref,\n+\t.resolve_gitlink_ref\t\t= files_resolve_gitlink_ref,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex f630e20..c56bfcd 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@@ -399,6 +412,14 @@ struct ref_be {\n \treflog_exists_fn reflog_exists;\n \tcreate_reflog_fn create_reflog;\n \tdelete_reflog_fn delete_reflog;\n+\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 \n extern struct ref_be *refs;\n-- \n2.0.1.553.geee1b3e\n"},{"id":"247491","messageId":"1407516309-27989-21-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 20/22] refs.c: add methods for head_ref*","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:07Z","receivedAt":"2014-08-08T16:45:07Z","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 | 15 +++++++++++++++\n refs.c        | 10 +++++++---\n refs.h        |  8 ++++++++\n 3 files changed, 30 insertions(+), 3 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex 45e6fca..d9308a3 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -903,3 +903,18 @@ 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+}\n+\n+int head_ref_namespaced(each_ref_fn fn, void *cb_data)\n+{\n+\treturn refs->head_ref_namespaced(fn, cb_data);\n+}\ndiff --git a/refs.c b/refs.c\nindex c4076f3..94d6160 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@@ -1636,7 +1636,7 @@ 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+static int files_head_ref_namespaced(each_ref_fn fn, void *cb_data)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tint ret = 0;\n@@ -3326,6 +3326,10 @@ struct ref_be refs_files = {\n \t.peel_ref\t\t\t= files_peel_ref,\n \t.create_symref\t\t\t= files_create_symref,\n \t.resolve_gitlink_ref\t\t= files_resolve_gitlink_ref,\n+\n+\t.head_ref\t\t\t= files_head_ref,\n+\t.head_ref_submodule\t       \t= files_head_ref_submodule,\n+\t.head_ref_namespaced\t\t= files_head_ref_namespaced,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex c56bfcd..b35c406 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -397,6 +397,11 @@ 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+typedef int (*head_ref_namespaced_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@@ -420,6 +425,9 @@ struct ref_be {\n \tcreate_symref_fn create_symref;\n \tresolve_gitlink_ref_fn resolve_gitlink_ref;\n \n+\thead_ref_fn head_ref;\n+\thead_ref_submodule_fn head_ref_submodule;\n+\thead_ref_namespaced_fn head_ref_namespaced;\n };\n \n extern struct ref_be *refs;\n-- \n2.0.1.553.geee1b3e\n"},{"id":"247499","messageId":"1407516309-27989-22-git-send-email-sahlberg@google.com","threadId":"37315","inReplyTo":"1407516309-27989-1-git-send-email-sahlberg@google.com","subject":"[PATCH 21/22] refs.c: add methods for the ref iterators","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-08T16:45:08Z","receivedAt":"2014-08-08T16:45:08Z","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        | 22 +++++++++++++++-------\n refs.h        | 20 ++++++++++++++++++++\n 3 files changed, 71 insertions(+), 7 deletions(-)\n\ndiff --git a/refs-common.c b/refs-common.c\nindex d9308a3..11c3660 100644\n--- a/refs-common.c\n+++ b/refs-common.c\n@@ -918,3 +918,39 @@ int head_ref_namespaced(each_ref_fn fn, void *cb_data)\n {\n \treturn refs->head_ref_namespaced(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 94d6160..1b2272d 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1610,28 +1610,28 @@ 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@@ -1651,7 +1651,7 @@ static int files_head_ref_namespaced(each_ref_fn fn, void *cb_data)\n \treturn ret;\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@@ -1661,7 +1661,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@@ -3330,6 +3330,14 @@ struct ref_be refs_files = {\n \t.head_ref\t\t\t= files_head_ref,\n \t.head_ref_submodule\t       \t= files_head_ref_submodule,\n \t.head_ref_namespaced\t\t= files_head_ref_namespaced,\n+\n+\t.for_each_ref\t\t\t= files_for_each_ref,\n+\t.for_each_ref_submodule\t       \t= files_for_each_ref_submodule,\n+\t.for_each_ref_in\t\t= files_for_each_ref_in,\n+\t.for_each_ref_in_submodule\t= files_for_each_ref_in_submodule,\n+\t.for_each_rawref\t\t= files_for_each_rawref,\n+\t.for_each_namespaced_ref\t= files_for_each_namespaced_ref,\n+\t.for_each_replace_ref\t\t= files_for_each_replace_ref,\n };\n \n struct ref_be *refs = &refs_files;\ndiff --git a/refs.h b/refs.h\nindex b35c406..61b6728 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -402,6 +402,18 @@ typedef int (*head_ref_submodule_fn)(const char *submodule, each_ref_fn fn,\n \t\t\t\t     void *cb_data);\n typedef int (*head_ref_namespaced_fn)(each_ref_fn fn, 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@@ -428,6 +440,14 @@ struct ref_be {\n \thead_ref_fn head_ref;\n \thead_ref_submodule_fn head_ref_submodule;\n \thead_ref_namespaced_fn head_ref_namespaced;\n+\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.553.geee1b3e\n"},{"id":"247509","messageId":"1407518873.26542.20.camel@leckie","threadId":"37315","inReplyTo":"1407516309-27989-2-git-send-email-sahlberg@google.com","subject":"Re: [PATCH 01/22] refs.c: create a public function for is_refname_available","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2014-08-08T17:27:53Z","receivedAt":"2014-08-08T17:27:53Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"On Fri, 2014-08-08 at 09:44 -0700, Ronnie Sahlberg wrote:\n> + * Check is a particular refname is available for creation. skip\n> contains\n\ns/Check is/Check that/'\n\n> + * a list of refnames to exclude from the refname collission tests.\n\n\"collision\"\n\n> + */\n> +int is_refname_available(const char *refname, const char **skip, int\n> skipnum);\n> +\n> +/*\n"},{"id":"247521","messageId":"1407521872.26542.21.camel@leckie","threadId":"37315","inReplyTo":"1407516309-27989-18-git-send-email-sahlberg@google.com","subject":"Re: [PATCH 17/22] refs.c: add a backend method structure with transaction functions","fromName":"David Turner","fromEmail":"dturner@twopensource.com","sentAt":"2014-08-08T18:17:52Z","receivedAt":"2014-08-08T18:17:52Z","isPatch":true,"sender":{"key":"novalis@novalis.org","avatar":"https://avatars.githubusercontent.com/u/77003?v=4"},"body":"On Fri, 2014-08-08 at 09:45 -0700, Ronnie Sahlberg wrote:\n\n> +struct ref_be refs_files = {\n> +\t.transaction_begin\t\t= files_transaction_begin,\n> +\t.transaction_update_sha1\t= files_transaction_update_sha1,\n> +\t.transaction_create_sha1\t= files_transaction_create_sha1,\n> +\t.transaction_delete_sha1\t= files_transaction_delete_sha1,\n> +\t.transaction_update_reflog\t= files_transaction_update_reflog,\n> +\t.transaction_commit\t\t= files_transaction_commit,\n> +\t.transaction_free\t\t= files_transaction_free,\n> +};\n\nC99 designated initializers are unfortunately forbidden by\nCodingGuidelines.\n"},{"id":"247582","messageId":"CAL=YDWnbv4XNLny5WTN0b2oKAvDVXAbK536vjRVoTuig98oWFg@mail.gmail.com","threadId":"37315","inReplyTo":"1407521872.26542.21.camel@leckie","subject":"Re: [PATCH 17/22] refs.c: add a backend method structure with transaction functions","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-11T14:56:35Z","receivedAt":"2014-08-11T14:56:35Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"On Fri, Aug 8, 2014 at 11:17 AM, David Turner <dturner@twopensource.com> wrote:\n> On Fri, 2014-08-08 at 09:45 -0700, Ronnie Sahlberg wrote:\n>\n>> +struct ref_be refs_files = {\n>> +     .transaction_begin              = files_transaction_begin,\n>> +     .transaction_update_sha1        = files_transaction_update_sha1,\n>> +     .transaction_create_sha1        = files_transaction_create_sha1,\n>> +     .transaction_delete_sha1        = files_transaction_delete_sha1,\n>> +     .transaction_update_reflog      = files_transaction_update_reflog,\n>> +     .transaction_commit             = files_transaction_commit,\n>> +     .transaction_free               = files_transaction_free,\n>> +};\n>\n> C99 designated initializers are unfortunately forbidden by\n> CodingGuidelines.\n>\n\nRight. Fixed it.\n\nThanks.\n"},{"id":"247583","messageId":"CAL=YDWn=DWBbL24H2Ka5+1yXJ813aokyyfJrBDkFtvVTNO4EbQ@mail.gmail.com","threadId":"37315","inReplyTo":"1407518873.26542.20.camel@leckie","subject":"Re: [PATCH 01/22] refs.c: create a public function for is_refname_available","fromName":"Ronnie Sahlberg","fromEmail":"sahlberg@google.com","sentAt":"2014-08-11T15:00:58Z","receivedAt":"2014-08-11T15:00:58Z","isPatch":true,"sender":{"key":"sahlberg@google.com","avatar":"https://avatars.githubusercontent.com/u/7320636?v=4"},"body":"Fixed. Thanks!\n\n\nOn Fri, Aug 8, 2014 at 10:27 AM, David Turner <dturner@twopensource.com> wrote:\n> On Fri, 2014-08-08 at 09:44 -0700, Ronnie Sahlberg wrote:\n>> + * Check is a particular refname is available for creation. skip\n>> contains\n>\n> s/Check is/Check that/'\n>\n>> + * a list of refnames to exclude from the refname collission tests.\n>\n> \"collision\"\n>\n>> + */\n>> +int is_refname_available(const char *refname, const char **skip, int\n>> skipnum);\n>> +\n>> +/*\n>\n>\n"}]}