{"thread":{"id":"8568","subject":"[PATCH 1/3] Parse and report branch configuration along with remote configuration.","startedAt":"2007-06-12T03:10:43Z","lastAt":"2007-06-12T03:10:43Z","messageCount":1,"participants":["Daniel Barkalow"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"44786","messageId":"Pine.LNX.4.64.0706112306220.5848@iabervon.org","threadId":"8568","inReplyTo":null,"subject":"[PATCH 1/3] Parse and report branch configuration along with remote configuration.","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2007-06-12T03:10:43Z","receivedAt":"2007-06-12T03:10:43Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n remote.c |   92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------\n remote.h |   13 +++++++++\n 2 files changed, 94 insertions(+), 11 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex d904616..1fbceeb 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -5,6 +5,12 @@\n static struct remote **remotes;\n static int allocated_remotes;\n \n+static struct branch **branches;\n+static int allocated_branches;\n+\n+static struct branch *current_branch;\n+static const char *default_remote_name;\n+\n #define BUF_SIZE (2048)\n static char buffer[BUF_SIZE];\n \n@@ -67,6 +73,45 @@ static struct remote *make_remote(const char *name, int len)\n \treturn remotes[empty];\n }\n \n+static struct branch *make_branch(const char *name, int len)\n+{\n+\tint i, empty = -1;\n+\tchar *refname;\n+\n+\tfor (i = 0; i < allocated_branches; i++) {\n+\t\tif (!branches[i]) {\n+\t\t\tif (empty < 0)\n+\t\t\t\tempty = i;\n+\t\t} else {\n+\t\t\tif (len ? (!strncmp(name, branches[i]->name, len) &&\n+\t\t\t\t   !branches[i]->name[len]) :\n+\t\t\t    !strcmp(name, branches[i]->name))\n+\t\t\t\treturn branches[i];\n+\t\t}\n+\t}\n+\n+\tif (empty < 0) {\n+\t\tempty = allocated_branches;\n+\t\tallocated_branches += allocated_branches ? allocated_branches : 1;\n+\t\tbranches = xrealloc(branches,\n+\t\t\t\t   sizeof(*branches) * allocated_branches);\n+\t\tmemset(branches + empty, 0,\n+\t\t       (allocated_branches - empty) * sizeof(*branches));\n+\t}\n+\tbranches[empty] = xcalloc(1, sizeof(struct branch));\n+\tif (len)\n+\t\tbranches[empty]->name = xstrndup(name, len);\n+\telse\n+\t\tbranches[empty]->name = xstrdup(name);\n+\trefname = malloc(strlen(name) + strlen(\"refs/heads/\") + 1);\n+\tstrcpy(refname, \"refs/heads/\");\n+\tstrcpy(refname + strlen(\"refs/heads/\"),\n+\t       branches[empty]->name);\n+\tbranches[empty]->refname = refname;\n+\n+\treturn branches[empty];\n+}\n+\n static void read_remotes_file(struct remote *remote)\n {\n \tFILE *f = fopen(git_path(\"remotes/%s\", remote->name), \"r\");\n@@ -144,20 +189,25 @@ static void read_branches_file(struct remote *remote)\n \tadd_uri(remote, p);\n }\n \n-static char *default_remote_name = NULL;\n-static const char *current_branch = NULL;\n-static int current_branch_len = 0;\n-\n static int handle_config(const char *key, const char *value)\n {\n \tconst char *name;\n \tconst char *subkey;\n \tstruct remote *remote;\n-\tif (!prefixcmp(key, \"branch.\") && current_branch &&\n-\t    !strncmp(key + 7, current_branch, current_branch_len) &&\n-\t    !strcmp(key + 7 + current_branch_len, \".remote\")) {\n-\t\tfree(default_remote_name);\n-\t\tdefault_remote_name = xstrdup(value);\n+\tstruct branch *branch;\n+\tif (!prefixcmp(key, \"branch.\")) {\n+\t\tname = key + 7;\n+\t\tsubkey = strrchr(name, '.');\n+\t\tbranch = make_branch(name, subkey - name);\n+\t\tif (!value)\n+\t\t\treturn 0;\n+\t\tif (!strcmp(subkey, \".remote\")) {\n+\t\t\tbranch->remote_name = xstrdup(value);\n+\t\t\tif (branch == current_branch)\n+\t\t\t\tdefault_remote_name = branch->remote_name;\n+\t\t} else if (!strcmp(subkey, \".merge\"))\n+\t\t\tbranch->merge_name = xstrdup(value);\n+\t\treturn 0;\n \t}\n \tif (prefixcmp(key,  \"remote.\"))\n \t\treturn 0;\n@@ -212,8 +262,8 @@ static void read_config(void)\n \thead_ref = resolve_ref(\"HEAD\", sha1, 0, &flag);\n \tif (head_ref && (flag & REF_ISSYMREF) &&\n \t    !prefixcmp(head_ref, \"refs/heads/\")) {\n-\t\tcurrent_branch = head_ref + strlen(\"refs/heads/\");\n-\t\tcurrent_branch_len = strlen(current_branch);\n+\t\tcurrent_branch =\n+\t\t\tmake_branch(head_ref + strlen(\"refs/heads/\"), 0);\n \t}\n \tgit_config(handle_config);\n }\n@@ -551,3 +601,23 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,\n \t}\n \treturn 0;\n }\n+\n+struct branch *branch_get(const char *name)\n+{\n+\tstruct branch *ret;\n+\n+\tread_config();\n+\tif (!name || !strcmp(name, \"HEAD\"))\n+\t\tret = current_branch;\n+\telse\n+\t\tret = make_branch(name, 0);\n+\tif (ret->remote_name) {\n+\t\tret->remote = remote_get(ret->remote_name);\n+\t\tif (ret->merge_name) {\n+\t\t\tret->merge = malloc(sizeof(*ret->merge));\n+\t\t\tret->merge->src = ret->merge_name;\n+\t\t\tremote_find_tracking(ret->remote, ret->merge);\n+\t\t}\n+\t}\n+\treturn ret;\n+}\ndiff --git a/remote.h b/remote.h\nindex 01dbcef..14615e8 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -38,4 +38,17 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,\n  */\n int remote_find_tracking(struct remote *remote, struct refspec *refspec);\n \n+struct branch {\n+\tconst char *name;\n+\tconst char *refname;\n+\n+\tconst char *remote_name;\n+\tstruct remote *remote;\n+\n+\tconst char *merge_name;\n+\tstruct refspec *merge;\n+};\n+\n+struct branch *branch_get(const char *name);\n+\n #endif\n-- \n1.5.2.901.g27ad4-dirty\n"}]}