{"thread":{"id":"28011","subject":"[PATCH] add technical documentation about ref iteration","startedAt":"2011-08-03T18:03:37Z","lastAt":"2011-08-22T22:01:37Z","messageCount":4,"participants":["Heiko Voigt","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"172787","messageId":"20110803180319.GA13057@sandbox-rc","threadId":"28011","inReplyTo":null,"subject":"[PATCH] add technical documentation about ref iteration","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2011-08-03T18:03:37Z","receivedAt":"2011-08-03T18:03:37Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\n Documentation/technical/api-ref-iteration.txt |   73 +++++++++++++++++++++++++\n 1 files changed, 73 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/technical/api-ref-iteration.txt\n\ndiff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt\nnew file mode 100644\nindex 0000000..0a67e39\n--- /dev/null\n+++ b/Documentation/technical/api-ref-iteration.txt\n@@ -0,0 +1,73 @@\n+ref iteration API\n+=================\n+\n+\n+Iteration of refs is done by using an iterate function which will call a\n+callback function for every ref. The callback function has this\n+signature:\n+\n+\tint handle_one_ref(const char *refname, const unsigned char *sha1,\n+\t\t\t   int flags, void *cb_data);\n+\n+There are different kinds of iterate functions which all take a\n+callback of this type. The callback is then called for each found ref\n+until the callback returns nonzero. The returned value is then also\n+returned by the iterate function.\n+\n+Iteration functions\n+-------------------\n+\n+* `head_ref()` just iterates the head ref.\n+\n+* `for_each_ref()` iterates all refs.\n+\n+* `for_each_ref_in()` iterates all refs which have a defined prefix and\n+  strips that prefix from the passed variable refname.\n+\n+* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`,\n+  `for_each_replace_ref()` iterate refs from the respective area.\n+\n+* `for_each_glob_ref()` iterates all refs that match the specified glob\n+  pattern.\n+\n+* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined.\n+\n+* `head_ref_submodule()`, `for_each_ref_submodule()`,\n+  `for_each_ref_in_submodule()`, `for_each_tag_ref_submodule()`,\n+  `for_each_branch_ref_submodule()`, `for_each_remote_ref_submodule()`\n+  do the same as the functions descibed above but for a specified\n+  submodule.\n+\n+* `for_each_rawref()` can be used to learn about broken ref and symref.\n+\n+* `for_each_reflog()` iterates each reflog file.\n+\n+Submodules\n+----------\n+\n+If you want to iterate the refs of a submodule you first need to call\n+\n+\tadd_submodule_odb(submodule)\n+\n+and test whether that succeeds.\n+\n+Example:\n+--------\n+\n+----\n+static int handle_remote_ref(const char *refname,\n+\t\tconst unsigned char *sha1, int flags, void *cb_data)\n+{\n+\tstruct strbuf *output = cb_data;\n+\tstrbuf_addf(output, \"%s\\n\", refname);\n+\treturn 0;\n+}\n+\n+...\n+\n+\tstruct strbuf output = STRBUF_INIT;\n+\tfor_each_remote_ref(handle_remote_ref, &output);\n+\tprintf(\"%s\", output.buf);\n+----\n+\n+(Heiko Voigt)\n-- \n1.7.6.353.g02057.dirty\n"},{"id":"172795","messageId":"7vei12b9aq.fsf@alter.siamese.dyndns.org","threadId":"28011","inReplyTo":"20110803180319.GA13057@sandbox-rc","subject":"Re: [PATCH] add technical documentation about ref iteration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-03T19:10:37Z","receivedAt":"2011-08-03T19:10:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Heiko Voigt <hvoigt@hvoigt.net> writes:\n\n> Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n> ---\n>  Documentation/technical/api-ref-iteration.txt |   73 +++++++++++++++++++++++++\n>  1 files changed, 73 insertions(+), 0 deletions(-)\n>  create mode 100644 Documentation/technical/api-ref-iteration.txt\n\n> +Submodules\n> +----------\n> +\n> +If you want to iterate the refs of a submodule you first need to call\n> +\n> +\tadd_submodule_odb(submodule)\n> +\n> +and test whether that succeeds.\n\nHmm, this should probably be explained a bit deeper or not at all. For\nexample, what is \"submodule\" here? A path to the submodule directory? The\nname of submodule? What is the unwanted consequence of adding this extra\nobject database into your process (e.g. you can no longer tell if an\nobject exists in the superproject, as it may now come from the submodule's\nobject database)? Can you get rid of it? How does this function signal\nfailures? What is the symptom if you forget this call and used the\niteration in the submodule (e.g. \"we do not see any ref\"; \"we see only\nsome ref but not all\"; \"the call crashes the process\")?\n\n> +\n> +(Heiko Voigt)\n\nPlease drop this line for two reasons.\n\nInitially I added these parenthesized names at the end for placeholder\npages to name people who are responsible for the _code_ the document\ndescribes, so that the ones who help documentation would know who to nag\nto get the necessary information. With your description, people who are\ninterested in documenting this API more would know that for_each_ref() and\nfriends are the topic and can find out whom to harrass.\n\nBesides, with only two commits to refs.c, I doubt you would want to be the\nprimary source of information for other people to bug in order to enhance\nthe API description in this file.\n\nThanks.\n"},{"id":"174042","messageId":"20110822203645.GD11745@sandbox-rc","threadId":"28011","inReplyTo":"7vei12b9aq.fsf@alter.siamese.dyndns.org","subject":"[PATCH v2] add technical documentation about ref iteration","fromName":"Heiko Voigt","fromEmail":"hvoigt@hvoigt.net","sentAt":"2011-08-22T20:36:45Z","receivedAt":"2011-08-22T20:36:45Z","isPatch":true,"sender":{"key":"hvoigt@hvoigt.net","avatar":"https://avatars.githubusercontent.com/u/184958?v=4"},"body":"Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n---\n\nHi,\n\nthis is an update of the previous doc patch.\n\nOn Wed, Aug 03, 2011 at 12:10:37PM -0700, Junio C Hamano wrote:\n> Heiko Voigt <hvoigt@hvoigt.net> writes:\n> > +Submodules\n> > +----------\n> > +\n> > +If you want to iterate the refs of a submodule you first need to call\n> > +\n> > +\tadd_submodule_odb(submodule)\n> > +\n> > +and test whether that succeeds.\n> \n> Hmm, this should probably be explained a bit deeper or not at all. For\n> example, what is \"submodule\" here? A path to the submodule directory? The\n> name of submodule? What is the unwanted consequence of adding this extra\n> object database into your process (e.g. you can no longer tell if an\n> object exists in the superproject, as it may now come from the submodule's\n> object database)? Can you get rid of it? How does this function signal\n> failures? What is the symptom if you forget this call and used the\n> iteration in the submodule (e.g. \"we do not see any ref\"; \"we see only\n> some ref but not all\"; \"the call crashes the process\")?\n\nI hope I answered all these questions in the patch below.\n\n> \n> > +\n> > +(Heiko Voigt)\n> \n> Please drop this line for two reasons.\n\nDropped.\n\n Documentation/technical/api-ref-iteration.txt |   81 +++++++++++++++++++++++++\n 1 files changed, 81 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/technical/api-ref-iteration.txt\n\ndiff --git a/Documentation/technical/api-ref-iteration.txt b/Documentation/technical/api-ref-iteration.txt\nnew file mode 100644\nindex 0000000..dbbea95\n--- /dev/null\n+++ b/Documentation/technical/api-ref-iteration.txt\n@@ -0,0 +1,81 @@\n+ref iteration API\n+=================\n+\n+\n+Iteration of refs is done by using an iterate function which will call a\n+callback function for every ref. The callback function has this\n+signature:\n+\n+\tint handle_one_ref(const char *refname, const unsigned char *sha1,\n+\t\t\t   int flags, void *cb_data);\n+\n+There are different kinds of iterate functions which all take a\n+callback of this type. The callback is then called for each found ref\n+until the callback returns nonzero. The returned value is then also\n+returned by the iterate function.\n+\n+Iteration functions\n+-------------------\n+\n+* `head_ref()` just iterates the head ref.\n+\n+* `for_each_ref()` iterates all refs.\n+\n+* `for_each_ref_in()` iterates all refs which have a defined prefix and\n+  strips that prefix from the passed variable refname.\n+\n+* `for_each_tag_ref()`, `for_each_branch_ref()`, `for_each_remote_ref()`,\n+  `for_each_replace_ref()` iterate refs from the respective area.\n+\n+* `for_each_glob_ref()` iterates all refs that match the specified glob\n+  pattern.\n+\n+* `for_each_glob_ref_in()` the previous and `for_each_ref_in()` combined.\n+\n+* `head_ref_submodule()`, `for_each_ref_submodule()`,\n+  `for_each_ref_in_submodule()`, `for_each_tag_ref_submodule()`,\n+  `for_each_branch_ref_submodule()`, `for_each_remote_ref_submodule()`\n+  do the same as the functions descibed above but for a specified\n+  submodule.\n+\n+* `for_each_rawref()` can be used to learn about broken ref and symref.\n+\n+* `for_each_reflog()` iterates each reflog file.\n+\n+Submodules\n+----------\n+\n+If you want to iterate the refs of a submodule you first need to add the\n+submodules object database. You can do this by a code-snippet like\n+this:\n+\n+\tconst char *path = \"path/to/submodule\"\n+\tif (!add_submodule_odb(path))\n+\t\tdie(\"Error submodule '%s' not populated.\", path);\n+\n+`add_submodule_odb()` will return an non-zero value on success. If you\n+do not do this you will get an error for each ref that it does not point\n+to a valid object.\n+\n+Note: As a side-effect of this you can not safely assume that all\n+objects you lookup are available in superproject. All submodule objects\n+will be available the same way as the superprojects objects.\n+\n+Example:\n+--------\n+\n+----\n+static int handle_remote_ref(const char *refname,\n+\t\tconst unsigned char *sha1, int flags, void *cb_data)\n+{\n+\tstruct strbuf *output = cb_data;\n+\tstrbuf_addf(output, \"%s\\n\", refname);\n+\treturn 0;\n+}\n+\n+...\n+\n+\tstruct strbuf output = STRBUF_INIT;\n+\tfor_each_remote_ref(handle_remote_ref, &output);\n+\tprintf(\"%s\", output.buf);\n+----\n-- \n1.7.6.351.g9ce65.dirty\n"},{"id":"174049","messageId":"7vhb59umv2.fsf@alter.siamese.dyndns.org","threadId":"28011","inReplyTo":"20110822203645.GD11745@sandbox-rc","subject":"Re: [PATCH v2] add technical documentation about ref iteration","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-08-22T22:01:37Z","receivedAt":"2011-08-22T22:01:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Heiko Voigt <hvoigt@hvoigt.net> writes:\n\n> Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>\n> ---\n>\n> Hi,\n>\n> this is an update of the previous doc patch.\n\nLooks very good; thanks.\n"}]}