{"thread":{"id":"65287","subject":"[GSoC PATCH] object-name: turn INTERPRET_BRANCH_* constants into enum values","startedAt":"2026-03-18T01:09:46Z","lastAt":"2026-03-20T20:12:24Z","messageCount":5,"participants":["Jialong Wang","Junio C Hamano","Karthik Nayak"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"539272","messageId":"20260318003917.84792-1-jerrywang183@yahoo.com","threadId":"65287","inReplyTo":"20260318003917.84792-1-jerrywang183.ref@yahoo.com","subject":"[GSoC PATCH] object-name: turn INTERPRET_BRANCH_* constants into enum values","fromName":"Jialong Wang","fromEmail":"jerrywang183@yahoo.com","sentAt":"2026-03-18T00:39:17Z","receivedAt":"2026-03-18T01:09:46Z","isPatch":true,"sender":{"key":"jerrywang183@yahoo.com","avatar":null},"body":"Replace the INTERPRET_BRANCH_* preprocessor constants with enum values and use the enum type where these flags are stored or passed around.\n\nThis keeps the existing bitmask semantics, but gives the branch-name interpretation flags a dedicated type instead of plain unsigned values.\n---\n builtin/branch.c |  2 +-\n object-name.c    |  7 +++++--\n object-name.h    | 11 +++++++----\n refs.c           |  3 ++-\n refs.h           |  3 ++-\n 5 files changed, 17 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex a1a43380d0..6ef6a7ca0f 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -228,7 +228,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,\n \tint ret = 0;\n \tint remote_branch = 0;\n \tstruct strbuf bname = STRBUF_INIT;\n-\tunsigned allowed_interpret;\n+\tenum interpret_branch_name_allowed allowed_interpret;\n \tstruct string_list refs_to_delete = STRING_LIST_INIT_DUP;\n \tstruct string_list_item *item;\n \tint branch_name_pos;\ndiff --git a/object-name.c b/object-name.c\nindex 7b14c3bf9b..fbf7c5dbf0 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1660,7 +1660,8 @@ static int interpret_empty_at(const char *name, int namelen, int len, struct str\n \n static int reinterpret(struct repository *r,\n \t\t       const char *name, int namelen, int len,\n-\t\t       struct strbuf *buf, unsigned allowed)\n+\t\t       struct strbuf *buf,\n+\t\t       enum interpret_branch_name_allowed allowed)\n {\n \t/* we have extra data, which might need further processing */\n \tstruct strbuf tmp = STRBUF_INIT;\n@@ -1692,7 +1693,9 @@ static void set_shortened_ref(struct repository *r, struct strbuf *buf, const ch\n \tfree(s);\n }\n \n-static int branch_interpret_allowed(const char *refname, unsigned allowed)\n+static int branch_interpret_allowed(\n+\tconst char *refname,\n+\tenum interpret_branch_name_allowed allowed)\n {\n \tif (!allowed)\n \t\treturn 1;\ndiff --git a/object-name.h b/object-name.h\nindex cda4934cd5..a544b65235 100644\n--- a/object-name.h\n+++ b/object-name.h\n@@ -101,9 +101,12 @@ int set_disambiguate_hint_config(const char *var, const char *value);\n  * If the input was ok but there are not N branch switches in the\n  * reflog, it returns 0.\n  */\n-#define INTERPRET_BRANCH_LOCAL (1<<0)\n-#define INTERPRET_BRANCH_REMOTE (1<<1)\n-#define INTERPRET_BRANCH_HEAD (1<<2)\n+enum interpret_branch_name_allowed {\n+\tINTERPRET_BRANCH_LOCAL = (1 << 0),\n+\tINTERPRET_BRANCH_REMOTE = (1 << 1),\n+\tINTERPRET_BRANCH_HEAD = (1 << 2),\n+};\n+\n struct interpret_branch_name_options {\n \t/*\n \t * If \"allowed\" is non-zero, it is a treated as a bitfield of allowable\n@@ -111,7 +114,7 @@ struct interpret_branch_name_options {\n \t * (\"refs/remotes/\"), or \"HEAD\". If no \"allowed\" bits are set, any expansion is\n \t * allowed, even ones to refs outside of those namespaces.\n \t */\n-\tunsigned allowed;\n+\tenum interpret_branch_name_allowed allowed;\n \n \t/*\n \t * If ^{upstream} or ^{push} (or equivalent) is requested, and the\ndiff --git a/refs.c b/refs.c\nindex 6fb8f9d10c..b3b39ce37f 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -740,7 +740,8 @@ static char *substitute_branch_name(struct repository *r,\n \treturn NULL;\n }\n \n-void copy_branchname(struct strbuf *sb, const char *name, unsigned allowed)\n+void copy_branchname(struct strbuf *sb, const char *name,\n+\t\t     enum interpret_branch_name_allowed allowed)\n {\n \tint len = strlen(name);\n \tstruct interpret_branch_name_options options = {\ndiff --git a/refs.h b/refs.h\nindex d98c1fc591..8a5b034f8a 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -1,6 +1,7 @@\n #ifndef REFS_H\n #define REFS_H\n \n+#include \"object-name.h\"\n #include \"commit.h\"\n #include \"repository.h\"\n #include \"repo-settings.h\"\n@@ -225,7 +226,7 @@ char *repo_default_branch_name(struct repository *r, int quiet);\n  * repo_interpret_branch_name() for details.\n  */\n void copy_branchname(struct strbuf *sb, const char *name,\n-\t\t       unsigned allowed);\n+\t\t     enum interpret_branch_name_allowed allowed);\n \n /*\n  * Like copy_branchname() above, but confirm that the result is\n-- \n2.51.0\n\n"},{"id":"539294","messageId":"xmqqjyv9gl2a.fsf@gitster.g","threadId":"65287","inReplyTo":"20260318003917.84792-1-jerrywang183@yahoo.com","subject":"Re: [GSoC PATCH] object-name: turn INTERPRET_BRANCH_* constants into enum values","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-18T16:27:09Z","receivedAt":"2026-03-18T16:27:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jialong Wang <jerrywang183@yahoo.com> writes:\n\n> Replace the INTERPRET_BRANCH_* preprocessor constants with enum values and use the enum type where these flags are stored or passed around.\n>\n> This keeps the existing bitmask semantics, but gives the branch-name interpretation flags a dedicated type instead of plain unsigned values.\n> ---\n\nOverlong lines without sign-off.\n\n> @@ -1660,7 +1660,8 @@ static int interpret_empty_at(const char *name, int namelen, int len, struct str\n>  \n>  static int reinterpret(struct repository *r,\n>  \t\t       const char *name, int namelen, int len,\n> -\t\t       struct strbuf *buf, unsigned allowed)\n> +\t\t       struct strbuf *buf,\n> +\t\t       enum interpret_branch_name_allowed allowed)\n>  {\n>  \t/* we have extra data, which might need further processing */\n>  \tstruct strbuf tmp = STRBUF_INIT;\n> @@ -1692,7 +1693,9 @@ static void set_shortened_ref(struct repository *r, struct strbuf *buf, const ch\n>  \tfree(s);\n>  }\n>  \n> -static int branch_interpret_allowed(const char *refname, unsigned allowed)\n> +static int branch_interpret_allowed(\n> +\tconst char *refname,\n> +\tenum interpret_branch_name_allowed allowed)\n\nA funny way to wrap lines.  Use what you have in the previous hunk\nas a template, perhaps?\n\n> +enum interpret_branch_name_allowed {\n> +\tINTERPRET_BRANCH_LOCAL = (1 << 0),\n> +\tINTERPRET_BRANCH_REMOTE = (1 << 1),\n> +\tINTERPRET_BRANCH_HEAD = (1 << 2),\n> +};\n\nI do not think \"allowed\" matches what this set represents.\n\nThe way \"reinterpret\" uses a parameter of this type (or the bitmask)\nis to specify which _kind_ of branches are _allowed_ to be considered\nfor its output.  The bitset is used to specify the KIND that are\nALLOWED.  The type should identify itself as representing the kinds\nof branches, while the parameter name should reflect what these\nkinds are telling the function to do (i.e., allowed).\n\nI'd name it \"enum interpret_branch_kind\" or somehing, if I were\ndoing this patch.  If the type can stay private to a single C file,\nwe may want to even lose \"interpret_\" prefix, but I do not think\nthat is the case.\n\nBy the way, in the longer term, the set may even want to be possibly\nunified with what \"git branch --list [--remote | --all]\" internally\nuses.  At that point it might even become shorter set that looks\nlike\n\n\tenum branch_kind {\n\t\tBRANCH_LOCAL, BRANCH_REMOTE, BRANCH_HEAD,\n\t};\n\nor \"enum ref_kind\" that also covers different ref hierarchies like\n\"tags\" and \"notes\".\n\nNeedless to say, I do *NOT* want you to be doing this as part of\nthis patch; I do *NOT* want you to drop INTERPRET_ prefix from the\nnames of enum elements in this patch, either.\n"},{"id":"539311","messageId":"20260318190942.22595-1-jerrywang183@yahoo.com","threadId":"65287","inReplyTo":"20260318003917.84792-1-jerrywang183@yahoo.com","subject":"[GSoC PATCH v2] object-name: turn INTERPRET_BRANCH_* constants into enum values","fromName":"Jialong Wang","fromEmail":"jerrywang183@yahoo.com","sentAt":"2026-03-18T19:09:42Z","receivedAt":"2026-03-18T19:09:50Z","isPatch":true,"sender":{"key":"jerrywang183@yahoo.com","avatar":null},"body":"Replace the INTERPRET_BRANCH_* preprocessor constants with enum\nvalues and use that type where these flags are stored or passed\naround.\n\nThese flags describe which kinds of branches may be considered during\nbranch-name interpretation, so represent them as an enum describing\nbranch kinds while keeping the existing bitmask semantics and\nINTERPRET_BRANCH_* element names.\n\nSigned-off-by: Jialong Wang <jerrywang183@yahoo.com>\n---\nv2:\n - rename the enum type to reflect that it describes branch kinds,\n   not the allowed set itself\n - keep the INTERPRET_BRANCH_* enum element names unchanged\n - wrap updated declarations and commit message more conventionally\n\n builtin/branch.c |  2 +-\n object-name.c    |  6 ++++--\n object-name.h    | 11 +++++++----\n refs.c           |  3 ++-\n refs.h           |  3 ++-\n 5 files changed, 16 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex a1a43380d0..1572a4f9ef 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -228,7 +228,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,\n \tint ret = 0;\n \tint remote_branch = 0;\n \tstruct strbuf bname = STRBUF_INIT;\n-\tunsigned allowed_interpret;\n+\tenum interpret_branch_kind allowed_interpret;\n \tstruct string_list refs_to_delete = STRING_LIST_INIT_DUP;\n \tstruct string_list_item *item;\n \tint branch_name_pos;\ndiff --git a/object-name.c b/object-name.c\nindex 7b14c3bf9b..2b2a0435fd 100644\n--- a/object-name.c\n+++ b/object-name.c\n@@ -1660,7 +1660,8 @@ static int interpret_empty_at(const char *name, int namelen, int len, struct str\n \n static int reinterpret(struct repository *r,\n \t\t       const char *name, int namelen, int len,\n-\t\t       struct strbuf *buf, unsigned allowed)\n+\t\t       struct strbuf *buf,\n+\t\t       enum interpret_branch_kind allowed)\n {\n \t/* we have extra data, which might need further processing */\n \tstruct strbuf tmp = STRBUF_INIT;\n@@ -1692,7 +1693,8 @@ static void set_shortened_ref(struct repository *r, struct strbuf *buf, const ch\n \tfree(s);\n }\n \n-static int branch_interpret_allowed(const char *refname, unsigned allowed)\n+static int branch_interpret_allowed(const char *refname,\n+\t\t\t\t    enum interpret_branch_kind allowed)\n {\n \tif (!allowed)\n \t\treturn 1;\ndiff --git a/object-name.h b/object-name.h\nindex cda4934cd5..167a9154ea 100644\n--- a/object-name.h\n+++ b/object-name.h\n@@ -101,9 +101,12 @@ int set_disambiguate_hint_config(const char *var, const char *value);\n  * If the input was ok but there are not N branch switches in the\n  * reflog, it returns 0.\n  */\n-#define INTERPRET_BRANCH_LOCAL (1<<0)\n-#define INTERPRET_BRANCH_REMOTE (1<<1)\n-#define INTERPRET_BRANCH_HEAD (1<<2)\n+enum interpret_branch_kind {\n+\tINTERPRET_BRANCH_LOCAL = (1 << 0),\n+\tINTERPRET_BRANCH_REMOTE = (1 << 1),\n+\tINTERPRET_BRANCH_HEAD = (1 << 2),\n+};\n+\n struct interpret_branch_name_options {\n \t/*\n \t * If \"allowed\" is non-zero, it is a treated as a bitfield of allowable\n@@ -111,7 +114,7 @@ struct interpret_branch_name_options {\n \t * (\"refs/remotes/\"), or \"HEAD\". If no \"allowed\" bits are set, any expansion is\n \t * allowed, even ones to refs outside of those namespaces.\n \t */\n-\tunsigned allowed;\n+\tenum interpret_branch_kind allowed;\n \n \t/*\n \t * If ^{upstream} or ^{push} (or equivalent) is requested, and the\ndiff --git a/refs.c b/refs.c\nindex 6fb8f9d10c..18b28db6d4 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -740,7 +740,8 @@ static char *substitute_branch_name(struct repository *r,\n \treturn NULL;\n }\n \n-void copy_branchname(struct strbuf *sb, const char *name, unsigned allowed)\n+void copy_branchname(struct strbuf *sb, const char *name,\n+\t\t     enum interpret_branch_kind allowed)\n {\n \tint len = strlen(name);\n \tstruct interpret_branch_name_options options = {\ndiff --git a/refs.h b/refs.h\nindex d98c1fc591..d65de6ab5f 100644\n--- a/refs.h\n+++ b/refs.h\n@@ -1,6 +1,7 @@\n #ifndef REFS_H\n #define REFS_H\n \n+#include \"object-name.h\"\n #include \"commit.h\"\n #include \"repository.h\"\n #include \"repo-settings.h\"\n@@ -225,7 +226,7 @@ char *repo_default_branch_name(struct repository *r, int quiet);\n  * repo_interpret_branch_name() for details.\n  */\n void copy_branchname(struct strbuf *sb, const char *name,\n-\t\t       unsigned allowed);\n+\t\t     enum interpret_branch_kind allowed);\n \n /*\n  * Like copy_branchname() above, but confirm that the result is\n-- \n2.51.0\n"},{"id":"539506","messageId":"CAOLa=ZTfL+1wqLYLNES-o1bCMJnms7rp1hG=DN+=YStgc38+vA@mail.gmail.com","threadId":"65287","inReplyTo":"20260318190942.22595-1-jerrywang183@yahoo.com","subject":"Re: [GSoC PATCH v2] object-name: turn INTERPRET_BRANCH_* constants into enum values","fromName":"Karthik Nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2026-03-20T10:25:43Z","receivedAt":"2026-03-20T10:25:45Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Jialong Wang <jerrywang183@yahoo.com> writes:\n\n> Replace the INTERPRET_BRANCH_* preprocessor constants with enum\n> values and use that type where these flags are stored or passed\n> around.\n>\n> These flags describe which kinds of branches may be considered during\n> branch-name interpretation, so represent them as an enum describing\n> branch kinds while keeping the existing bitmask semantics and\n> INTERPRET_BRANCH_* element names.\n>\n> Signed-off-by: Jialong Wang <jerrywang183@yahoo.com>\n\n[snip]\n\n> diff --git a/object-name.h b/object-name.h\n> index cda4934cd5..167a9154ea 100644\n> --- a/object-name.h\n> +++ b/object-name.h\n> @@ -101,9 +101,12 @@ int set_disambiguate_hint_config(const char *var, const char *value);\n>   * If the input was ok but there are not N branch switches in the\n>   * reflog, it returns 0.\n>   */\n> -#define INTERPRET_BRANCH_LOCAL (1<<0)\n> -#define INTERPRET_BRANCH_REMOTE (1<<1)\n> -#define INTERPRET_BRANCH_HEAD (1<<2)\n> +enum interpret_branch_kind {\n> +\tINTERPRET_BRANCH_LOCAL = (1 << 0),\n> +\tINTERPRET_BRANCH_REMOTE = (1 << 1),\n> +\tINTERPRET_BRANCH_HEAD = (1 << 2),\n> +};\n\nGenerally when we use preprocessor constants with bit setting like\n`1 << 0`, we want to use them as flags which aren't mutually exclusive,\nallowing us to do 'INTERPRET_BRANCH_LOCAL | INTERPRET_BRANCH_HEAD' and\nso on.\n\nIs this the case here? If not, maybe we want to mention that explicitly\nand simply use '1, 2....N'?\n\n[snip]\n"},{"id":"539578","messageId":"xmqqh5qadzve.fsf@gitster.g","threadId":"65287","inReplyTo":"CAOLa=ZTfL+1wqLYLNES-o1bCMJnms7rp1hG=DN+=YStgc38+vA@mail.gmail.com","subject":"Re: [GSoC PATCH v2] object-name: turn INTERPRET_BRANCH_* constants into enum values","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-03-20T20:12:21Z","receivedAt":"2026-03-20T20:12:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Karthik Nayak <karthik.188@gmail.com> writes:\n\n>> diff --git a/object-name.h b/object-name.h\n>> index cda4934cd5..167a9154ea 100644\n>> --- a/object-name.h\n>> +++ b/object-name.h\n>> @@ -101,9 +101,12 @@ int set_disambiguate_hint_config(const char *var, const char *value);\n>>   * If the input was ok but there are not N branch switches in the\n>>   * reflog, it returns 0.\n>>   */\n>> -#define INTERPRET_BRANCH_LOCAL (1<<0)\n>> -#define INTERPRET_BRANCH_REMOTE (1<<1)\n>> -#define INTERPRET_BRANCH_HEAD (1<<2)\n>> +enum interpret_branch_kind {\n>> +\tINTERPRET_BRANCH_LOCAL = (1 << 0),\n>> +\tINTERPRET_BRANCH_REMOTE = (1 << 1),\n>> +\tINTERPRET_BRANCH_HEAD = (1 << 2),\n>> +};\n>\n> Generally when we use preprocessor constants with bit setting like\n> `1 << 0`, we want to use them as flags which aren't mutually exclusive,\n> allowing us to do 'INTERPRET_BRANCH_LOCAL | INTERPRET_BRANCH_HEAD' and\n> so on.\n>\n> Is this the case here? If not, maybe we want to mention that explicitly\n> and simply use '1, 2....N'?\n\nTaking a brief look at the way these constants are used, e.g.,\n\n        static int branch_interpret_allowed(const char *refname, unsigned allowed)\n        {\n                if (!allowed)\n                        return 1;\n\n                if ((allowed & INTERPRET_BRANCH_LOCAL) &&\n                    starts_with(refname, \"refs/heads/\"))\n                        return 1;\n                if ((allowed & INTERPRET_BRANCH_REMOTE) &&\n                    starts_with(refname, \"refs/remotes/\"))\n                        return 1;\n\n                return 0;\n        }\n\nit should be obvious that these are not mutually exclusive choices,\nrather they are independent flags that you can flip ON to express\ndwimming a short name to what types of branches are allowed.\n\nBesides, the original assignes one-bit-per-value to these constants;\nit is not a place for this \"CPP macro turned into enum to help those\nwho inspect a running program with gdb\" patch to change assignments\nof values.  That would be a separate topic.\n\n\n"}]}