Inter-revision diff: cover letter

Comparing v3 (message) to v4 (message)

--- v3
+++ v4
@@ -8,38 +8,45 @@
 "git branch --recurse-submodules" in-process but couldn't figure out how to read
 the remotes of a submodule.
 
-v3 tightens up the interface issues discussed previously ([2] and other v2
-discussion) by adding a "struct remote_state" backpointer to "struct branch" and
-"struct remote". The most notable improvement is that we no longer accept
-"struct {remote_state,repository}" and "struct {branch,remote}" parameters at
-the same time, thus it is impossible to pass the wrong (container, contained)
-object pair. This is especially useful for branch_get_push_1(), where we
-take a "struct branch" and need to get a related "struct remote".
-
-The intention is that this backpointer is only meant to be used by the remotes
-subsystem; it is meant to be an opaque implementation detail that no other
-callers should touch.
-
-I attempted the initial suggestion to include a backpointer from branch->repo
-instead of branch->remote_state and uploaded it to a branch in my own fork [3].
-However, this seems to be the wrong abstraction to me. I am not convinced that
-the contained structs (branch, remote) need to (nor will ever need to) interact
-with parts of the repository outside of remote_state. A symptom of this is that
-internal code ends up using "struct repository" parameters instead of "struct
-remote_state" only to use repo->remote_state repeatedly, violating some of the
-nice layering that we have set up.
-
-There is also a small YAGNI benefit of using a backpointer to the remote_state
-instead of repository. If we eventually decide that branches should
-point to their repository, we can make the change with
-s/remote_state/repo->remote_state, even if external callers start to rely on
-branch->remote_state (even though I don't think they shouldn't rely on it!).
-This property does not hold for branch->repo because external callers might be
-using members other than repository->remote_state.
+v4 reverts the backpointer introduced in v3. In authoring v3, I had
+overlooked the fact that branch == NULL (representing detached HEAD) is
+a valid argument to some branch_* functions and as a result, we cannot
+always rely on branch->remote_state to tell us the remote_state of a
+branch. This was not discovered because of a coding mistake in v3 where
+branch was unconditionally dereferenced, even when it was null [2]. v4
+adds a test that checks the relevant behavior.
+
+The resulting interface is similar to v2, but with Junio's proposed
+safety check [3] - when branch + repository are passed as a pair we
+check that the branch belongs to the repository (i.e. it is in the
+repository's remote_state struct). This check is only implemented for
+non-static functions because the probability of misuse is much higher.
+In static functions, this check is wasteful because we frequently
+operate on the remote_state + {branch, remote} pair in order to maintain
+data consistency and the correct remote_state is often obvious from
+context.
+
+In the long run, I believe that there is room for refactoring/interface changes
+as to avoid these internal correctness issues, but I think this is a good enough
+starting point.
 
 [1] https://lore.kernel.org/git/20210921232529.81811-1-chooglen@google.com/
-[2] https://lore.kernel.org/git/xmqq4k9so15i.fsf@gitster.g/
-[3] https://github.com/git/git/commit/9527d9106ff5a41530e7bfa50a316af296144c99
+[2] https://lore.kernel.org/git/xmqqtuhbo2tn.fsf@gitster.g
+[2] https://lore.kernel.org/git/xmqqfssozk8r.fsf@gitster.g
+
+Changes since v3:
+* Add a test case for pushing to a remote in detached HEAD. This test
+  would have caught the segfault that resulted in this reroll.
+* Remove the NEEDSWORK saying that init_remotes_hash() should be moved
+  into remote_state_new() and just do it.
+* Remove the backpointer to remote_state and add a remote_state
+  parameter instead.
+* In patch 4, add more remotes_* functions. These functions were not
+  needed in v3 because of the backpointer.
+* In patch 5, add a function that checks if a branch is in a repo. Add a
+  branch hashmap that makes this operation fast.
+* In patch 6, add more repo_* functions. These functions were not needed
+  in v3 because of the backpointer.
 
 Changes since v2:
 * Add .remote_state to struct branch and struct remote, changing the
@@ -53,120 +60,167 @@
   "struct repository" away from the remote.c internals.
 
 Changes since v1:
-
 * In v1, we moved static variables into the_repository->remote_state in
   two steps: static variables > static remote_state >
   the_repository->remote_state. In v2, make this change in one step:
   static variables > the_repository->remote_state.
 * Add more instances of repo_* that were missed.
 
-Glen Choo (4):
+Glen Choo (6):
+  t5516: add test case for pushing remote refspecs
   remote: move static variables into per-repository struct
   remote: use remote_state parameter internally
   remote: remove the_repository->remote_state from static methods
+  remote: die if branch is not found in repository
   remote: add struct repository parameter to external functions
 
- remote.c     | 303 +++++++++++++++++++++++++++++++--------------------
- remote.h     |  72 +++++++++++-
- repository.c |   8 ++
- repository.h |   4 +
- 4 files changed, 262 insertions(+), 125 deletions(-)
-
-Range-diff against v2:
-1:  6972ba4dcb ! 1:  1f712c22b4 remote: move static variables into per-repository struct
-    @@ remote.h: enum {
-     +	int instead_of_nr;
-     +	int instead_of_alloc;
-     +};
+ remote.c              | 406 +++++++++++++++++++++++++++++-------------
+ remote.h              | 118 ++++++++++--
+ repository.c          |   8 +
+ repository.h          |   4 +
+ t/t5516-fetch-push.sh |   9 +
+ 5 files changed, 404 insertions(+), 141 deletions(-)
+
+Range-diff against v3:
+-:  ---------- > 1:  9b29ec27c6 t5516: add test case for pushing remote refspecs
+1:  1f712c22b4 ! 2:  ca9b5ab66a remote: move static variables into per-repository struct
+    @@ remote.c: static void add_pushurl(struct remote *remote, const char *pushurl)
+      }
+      
+     @@ remote.c: static int remotes_hash_cmp(const void *unused_cmp_data,
+    + 		return strcmp(a->name, b->name);
+    + }
+      
+    - static inline void init_remotes_hash(void)
+    - {
+    +-static inline void init_remotes_hash(void)
+    +-{
+     -	if (!remotes_hash.cmpfn)
+     -		hashmap_init(&remotes_hash, remotes_hash_cmp, NULL, 0);
+    -+	if (!the_repository->remote_state->remotes_hash.cmpfn)
+    -+		hashmap_init(&the_repository->remote_state->remotes_hash,
+    -+			     remotes_hash_cmp, NULL, 0);
+    - }
+    - 
+    +-}
+    +-
+      static struct remote *make_remote(const char *name, int len)
+    + {
+    + 	struct remote *ret;
+     @@ remote.c: static struct remote *make_remote(const char *name, int len)
+    + 	if (!len)
+    + 		len = strlen(name);
+    + 
+    +-	init_remotes_hash();
+    + 	lookup.str = name;
+      	lookup.len = len;
+      	hashmap_entry_init(&lookup_entry, memhash(name, len));
+      
+    @@ remote.c: void apply_push_cas(struct push_cas_option *cas,
+     +	struct remote_state *r = xmalloc(sizeof(*r));
+     +
+     +	memset(r, 0, sizeof(*r));
     ++
-     +struct rewrites {
-     +	struct rewrite **rewrite;
-     +	int rewrite_alloc;
-    @@ remote.h: enum {
-     +};
+    ++	hashmap_init(&r->remotes_hash, remotes_hash_cmp, NULL, 0);
+     +	return r;
+     +}
      +
-     +struct remote_state {
-    -+	int config_loaded;
-    -+
-     +	struct remote **remotes;
-     +	int remotes_alloc;
-     +	int remotes_nr;
-    @@ remote.h: enum {
-     +	struct rewrites rewrites;
-     +	struct rewrites rewrites_push;
-     +};
-    ++
-     +void remote_state_clear(struct remote_state *remote_state);
-     +struct remote_state *remote_state_new(void);
-     +
-2:  71b1da4389 ! 2:  467247fa9c remote: use remote_state parameter internally
+2:  467247fa9c ! 3:  5d6a245cae remote: use remote_state parameter internally
     @@ Metadata
       ## Commit message ##
          remote: use remote_state parameter internally
      
-    -    In internal-facing functions, replace the_repository->remote_state with
-    -    a struct remote_state parameter, but do not change external-facing
-    -    functions.
-    +    Introduce a struct remote_state member to structs that need to
-    +    'remember' their remote_state. Without changing external-facing
-    +    functions, replace the_repository->remote_state internally by using the
-    +    remote_state member where it is applicable i.e. when a function accepts
-    +    a struct that depends on the remote_state. If it is not applicable, add
-    +    a struct remote_state parameter instead.
+    -    Introduce a struct remote_state member to structs that need to
+    -    'remember' their remote_state. Without changing external-facing
+    -    functions, replace the_repository->remote_state internally by using the
+    -    remote_state member where it is applicable i.e. when a function accepts
+    -    a struct that depends on the remote_state. If it is not applicable, add
+    -    a struct remote_state parameter instead.
+    +    Without changing external-facing functions, replace
+    +    the_repository->remote_state internally by adding a struct remote_state
+    +    parameter.
      
-    -    As a result, most static functions no longer reference
-    +    As a result, external-facing functions are still tied to the_repository,
-    +    but most static functions no longer reference
-         the_repository->remote_state. The exceptions are those that are used in
-         a way that depends on external-facing functions e.g. the callbacks to
-         remote_get_1().
+         As a result, external-facing functions are still tied to the_repository,
+         but most static functions no longer reference
     @@ Commit message
      
       ## remote.c ##
      @@ remote.c: static void add_pushurl(struct remote *remote, const char *pushurl)
-    - 	remote->pushurl[remote->pushurl_nr++] = pushurl;
-    - }
-    - 
-    --static void add_pushurl_alias(struct remote *remote, const char *url)
-    -+static void add_pushurl_alias(struct remote_state *remote_state,
-    -+			      struct remote *remote, const char *url)
-    + static void add_pushurl_alias(struct remote *remote, const char *url)
+    - static void add_pushurl_alias(struct remote *remote, const char *url)
+    + 	remote->pushurl[remote->pushurl_nr++] = pushurl;
+    + }
+    + 
+    +-static void add_pushurl_alias(struct remote *remote, const char *url)
+    ++static void add_pushurl_alias(struct remote_state *remote_state,
+    ++			      struct remote *remote, const char *url)
       {
-    --	const char *pushurl =
-    + 	const char *pushurl =
+    - 	const char *pushurl =
+    +-	const char *pushurl =
      -		alias_url(url, &the_repository->remote_state->rewrites_push);
-    -+	const char *pushurl = alias_url(url, &remote_state->rewrites_push);
-    ++		alias_url(url, &remote->remote_state->rewrites_push);
+    -+		alias_url(url, &remote->remote_state->rewrites_push);
+    ++	const char *pushurl = alias_url(url, &remote_state->rewrites_push);
       	if (pushurl != url)
       		add_pushurl(remote, pushurl);
       }
       
-    --static void add_url_alias(struct remote *remote, const char *url)
-    -+static void add_url_alias(struct remote_state *remote_state,
-    -+			  struct remote *remote, const char *url)
-    + static void add_url_alias(struct remote *remote, const char *url)
+    - static void add_url_alias(struct remote *remote, const char *url)
+    +-static void add_url_alias(struct remote *remote, const char *url)
+    ++static void add_url_alias(struct remote_state *remote_state,
+    ++			  struct remote *remote, const char *url)
       {
      -	add_url(remote,
      -		alias_url(url, &the_repository->remote_state->rewrites));
-    --	add_pushurl_alias(remote, url);
-    -+	add_url(remote, alias_url(url, &remote_state->rewrites));
-    -+	add_pushurl_alias(remote_state, remote, url);
-    ++	add_url(remote, alias_url(url, &remote->remote_state->rewrites));
-    + 	add_pushurl_alias(remote, url);
-      }
-      
-    - struct remotes_hash_key {
+    -+	add_url(remote, alias_url(url, &remote->remote_state->rewrites));
+    - 	add_pushurl_alias(remote, url);
+    +-	add_pushurl_alias(remote, url);
+    ++	add_url(remote, alias_url(url, &remote_state->rewrites));
+    ++	add_pushurl_alias(remote_state, remote, url);
+      }
+      
+    + struct remotes_hash_key {
      @@ remote.c: static int remotes_hash_cmp(const void *unused_cmp_data,
       		return strcmp(a->name, b->name);
       }
+      
+    --static inline void init_remotes_hash(void)
+    -+/**
+    -+ * NEEDSWORK: Now that the hashmap is in a struct, this should probably
+    -+ * just be moved into remote_state_new().
+    -+ */
+    -+static inline void init_remotes_hash(struct remote_state *remote_state)
+    - {
+    --	if (!the_repository->remote_state->remotes_hash.cmpfn)
+    --		hashmap_init(&the_repository->remote_state->remotes_hash,
+    --			     remotes_hash_cmp, NULL, 0);
+    -+	if (!remote_state->remotes_hash.cmpfn)
+    -+		hashmap_init(&remote_state->remotes_hash, remotes_hash_cmp,
+    -+			     NULL, 0);
+    - }
+    - 
+     -static struct remote *make_remote(const char *name, int len)
+     +static struct remote *make_remote(struct remote_state *remote_state,
+     +				  const char *name, int len)
+    @@ remote.c: static int remotes_hash_cmp(const void *unused_cmp_data,
+      	struct remote *ret;
+      	struct remotes_hash_key lookup;
+     @@ remote.c: static struct remote *make_remote(const char *name, int len)
+    - 	if (!len)
+    - 		len = strlen(name);
+    - 
+    --	init_remotes_hash();
+    -+	init_remotes_hash(remote_state);
+    - 	lookup.str = name;
+      	lookup.len = len;
+      	hashmap_entry_init(&lookup_entry, memhash(name, len));
+      
     @@ remote.c: static struct remote *make_remote(const char *name, int len)
       		return container_of(e, struct remote, ent);
       
      @@ remote.c: static struct remote *make_remote(const char *name, int len)
-    + 	ret->prune = -1;  /* unspecified */
-    + 	ret->prune_tags = -1;  /* unspecified */
-    + 	ret->name = xstrndup(name, len);
-    ++	ret->remote_state = remote_state;
+    - 	ret->prune = -1;  /* unspecified */
+    - 	ret->prune_tags = -1;  /* unspecified */
+    - 	ret->name = xstrndup(name, len);
+    -+	ret->remote_state = remote_state;
       	refspec_init(&ret->push, REFSPEC_PUSH);
       	refspec_init(&ret->fetch, REFSPEC_FETCH);
       
@@ -174,48 +228,48 @@
      +	remote_state->branches[remote_state->branches_nr++] = ret;
       	ret->name = xstrndup(name, len);
       	ret->refname = xstrfmt("refs/heads/%s", ret->name);
-    ++	ret->remote_state = remote_state;
-      
-    -@@ remote.c: static const char *skip_spaces(const char *s)
-    - 	return s;
-    - }
-    - 
-    --static void read_remotes_file(struct remote *remote)
-    -+static void read_remotes_file(struct remote_state *remote_state,
-    -+			      struct remote *remote)
-    - {
-    - 	struct strbuf buf = STRBUF_INIT;
-    - 	FILE *f = fopen_or_warn(git_path("remotes/%s", remote->name), "r");
-    -@@ remote.c: static void read_remotes_file(struct remote *remote)
-    - 		strbuf_rtrim(&buf);
-    - 
-    - 		if (skip_prefix(buf.buf, "URL:", &v))
-    --			add_url_alias(remote, xstrdup(skip_spaces(v)));
-    -+			add_url_alias(remote_state, remote,
-    -+				      xstrdup(skip_spaces(v)));
-    - 		else if (skip_prefix(buf.buf, "Push:", &v))
-    - 			refspec_append(&remote->push, skip_spaces(v));
-    - 		else if (skip_prefix(buf.buf, "Pull:", &v))
-    -@@ remote.c: static void read_remotes_file(struct remote *remote)
-    - 	fclose(f);
-    + 	return ret;
-      }
-    - 
-    --static void read_branches_file(struct remote *remote)
-    -+static void read_branches_file(struct remote_state *remote_state,
-    -+			       struct remote *remote)
-    - {
-    - 	char *frag;
-    - 	struct strbuf buf = STRBUF_INIT;
-    -@@ remote.c: static void read_branches_file(struct remote *remote)
-    - 	else
-    - 		frag = (char *)git_default_branch_name(0);
-    - 
-    --	add_url_alias(remote, strbuf_detach(&buf, NULL));
-    -+	add_url_alias(remote_state, remote, strbuf_detach(&buf, NULL));
-    - 	refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
-    - 			frag, remote->name);
-    - 
+    -+	ret->remote_state = remote_state;
+      
+    - 	return ret;
+    +@@ remote.c: static const char *skip_spaces(const char *s)
+    + 	return s;
+      }
+    + 
+    +-static void read_remotes_file(struct remote *remote)
+    ++static void read_remotes_file(struct remote_state *remote_state,
+    ++			      struct remote *remote)
+    + {
+    + 	struct strbuf buf = STRBUF_INIT;
+    + 	FILE *f = fopen_or_warn(git_path("remotes/%s", remote->name), "r");
+    +@@ remote.c: static void read_remotes_file(struct remote *remote)
+    + 		strbuf_rtrim(&buf);
+    + 
+    + 		if (skip_prefix(buf.buf, "URL:", &v))
+    +-			add_url_alias(remote, xstrdup(skip_spaces(v)));
+    ++			add_url_alias(remote_state, remote,
+    ++				      xstrdup(skip_spaces(v)));
+    + 		else if (skip_prefix(buf.buf, "Push:", &v))
+    + 			refspec_append(&remote->push, skip_spaces(v));
+    + 		else if (skip_prefix(buf.buf, "Pull:", &v))
+    +@@ remote.c: static void read_remotes_file(struct remote *remote)
+    + 	fclose(f);
+    + }
+    + 
+    +-static void read_branches_file(struct remote *remote)
+    ++static void read_branches_file(struct remote_state *remote_state,
+    ++			       struct remote *remote)
+    + {
+    + 	char *frag;
+    + 	struct strbuf buf = STRBUF_INIT;
+    +@@ remote.c: static void read_branches_file(struct remote *remote)
+    + 	else
+    + 		frag = (char *)git_default_branch_name(0);
+    + 
+    +-	add_url_alias(remote, strbuf_detach(&buf, NULL));
+    ++	add_url_alias(remote_state, remote, strbuf_detach(&buf, NULL));
+    + 	refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
+    + 			frag, remote->name);
+    + 
      @@ remote.c: static int handle_config(const char *key, const char *value, void *cb)
       	const char *subkey;
       	struct remote *remote;
@@ -223,156 +277,82 @@
      -				->url[j] = alias_url(
      -				the_repository->remote_state->remotes[i]->url[j],
      -				&the_repository->remote_state->rewrites);
-    -+					remote_state, remote_state->remotes[i],
-    ++					remote_state->remotes[i],
+    -+					remote_state->remotes[i],
+    ++					remote_state, remote_state->remotes[i],
      +					remote_state->remotes[i]->url[j]);
      +			remote_state->remotes[i]->url[j] =
      +				alias_url(remote_state->remotes[i]->url[j],
     @@ remote.c: static int handle_config(const char *key, const char *value, void *cb)
       }
       
-     -static void read_config(void)
-    -+static void read_config(struct remote_state *remote_state)
-    ++static void read_config(struct repository *repo)
-      {
-    - 	static int loaded;
-    +-	static int loaded;
-      	int flag;
-    -@@ remote.c: static void read_config(void)
-    + 
-    +-	if (loaded)
-    ++	if (repo->remote_state->initialized)
-      		return;
-    - 	loaded = 1;
-    +-	loaded = 1;
-    ++	repo->remote_state->initialized = 1;
-      
-     -	the_repository->remote_state->current_branch = NULL;
-    -+	remote_state->current_branch = NULL;
-    ++	repo->remote_state->current_branch = NULL;
-      	if (startup_info->have_repository) {
-    - 		const char *head_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flag);
-    +-		const char *head_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flag);
-    ++		const char *head_ref = refs_resolve_ref_unsafe(
-    ++			get_main_ref_store(repo), "HEAD", 0, NULL, &flag);
-      		if (head_ref && (flag & REF_ISSYMREF) &&
-      		    skip_prefix(head_ref, "refs/heads/", &head_ref)) {
-     -			the_repository->remote_state->current_branch =
-     -				make_branch(head_ref, strlen(head_ref));
-    -+			remote_state->current_branch = make_branch(
-    -+				remote_state, head_ref, strlen(head_ref));
-    ++			repo->remote_state->current_branch = make_branch(
-    ++				repo->remote_state, head_ref, strlen(head_ref));
-      		}
-      	}
-     -	git_config(handle_config, NULL);
-     -	alias_all_urls();
-    -+	git_config(handle_config, remote_state);
-    -+	alias_all_urls(remote_state);
-    ++	repo_config(repo, handle_config, repo->remote_state);
-    ++	alias_all_urls(repo->remote_state);
-      }
-      
       static int valid_remote_nick(const char *name)
-    +@@ remote.c: const char *pushremote_for_branch(struct branch *branch, int *explicit)
-    + 			*explicit = 1;
-    + 		return branch->pushremote_name;
-    + 	}
-    +-	if (the_repository->remote_state->pushremote_name) {
-    ++	if (branch->remote_state->pushremote_name) {
-    + 		if (explicit)
-    + 			*explicit = 1;
-    +-		return the_repository->remote_state->pushremote_name;
-    ++		return branch->remote_state->pushremote_name;
-    + 	}
-    + 	return remote_for_branch(branch, explicit);
-    + }
+    -@@ remote.c: const char *pushremote_for_branch(struct branch *branch, int *explicit)
+    - 			*explicit = 1;
+    - 		return branch->pushremote_name;
+    - 	}
+    --	if (the_repository->remote_state->pushremote_name) {
+    -+	if (branch->remote_state->pushremote_name) {
+    - 		if (explicit)
+    - 			*explicit = 1;
+    --		return the_repository->remote_state->pushremote_name;
+    -+		return branch->remote_state->pushremote_name;
+    - 	}
+    - 	return remote_for_branch(branch, explicit);
+    - }
      @@ remote.c: static struct remote *remote_get_1(const char *name,
       	struct remote *ret;
       	int name_given = 0;
-      
-     -	read_config();
-    -+	read_config(the_repository->remote_state);
-    ++	read_config(the_repository);
-      
-      	if (name)
-      		name_given = 1;
     @@ remote.c: static struct remote *remote_get_1(const char *name,
      +	ret = make_remote(the_repository->remote_state, name, 0);
       	if (valid_remote_nick(name) && have_git_dir()) {
       		if (!valid_remote(ret))
-    --			read_remotes_file(ret);
-    -+			read_remotes_file(the_repository->remote_state, ret);
-    - 		if (!valid_remote(ret))
-    --			read_branches_file(ret);
-    -+			read_branches_file(the_repository->remote_state, ret);
-    - 	}
-    - 	if (name_given && !valid_remote(ret))
-    --		add_url_alias(ret, name);
-    -+		add_url_alias(the_repository->remote_state, ret, name);
-    - 	if (!valid_remote(ret))
-    - 		return NULL;
-    - 	return ret;
-    + 			read_remotes_file(ret);
+    - 			read_remotes_file(ret);
+    +-			read_remotes_file(ret);
+    ++			read_remotes_file(the_repository->remote_state, ret);
+    + 		if (!valid_remote(ret))
+    +-			read_branches_file(ret);
+    ++			read_branches_file(the_repository->remote_state, ret);
+    + 	}
+    + 	if (name_given && !valid_remote(ret))
+    +-		add_url_alias(ret, name);
+    ++		add_url_alias(the_repository->remote_state, ret, name);
+    + 	if (!valid_remote(ret))
+    + 		return NULL;
+    + 	return ret;
      @@ remote.c: int remote_is_configured(struct remote *remote, int in_repo)
       int for_each_remote(each_remote_fn fn, void *priv)
       {
-      	int i, result = 0;
-     -	read_config();
-    -+	read_config(the_repository->remote_state);
-    ++	read_config(the_repository);
-      	for (i = 0; i < the_repository->remote_state->remotes_nr && !result;
-      	     i++) {
-      		struct remote *remote =
-    @@ remote.c: struct branch *branch_get(const char *name)
-      	struct branch *ret;
-      
-     -	read_config();
-    -+	read_config(the_repository->remote_state);
-    ++	read_config(the_repository);
-      	if (!name || !*name || !strcmp(name, "HEAD"))
-      		ret = the_repository->remote_state->current_branch;
-      	else
-    @@ remote.c: struct branch *branch_get(const char *name)
-      	set_merge(ret);
-      	return ret;
-      }
-    +
-    + ## remote.h ##
-    +@@ remote.h: struct remote_state {
-    + 
-    + 	struct rewrites rewrites;
-    + 	struct rewrites rewrites_push;
-    ++
-    ++	int initialized;
-    + };
-    + 
-    + void remote_state_clear(struct remote_state *remote_state);
-    +@@ remote.h: struct remote {
-    + 
-    + 	/* The method used for authenticating against `http_proxy`. */
-    + 	char *http_proxy_authmethod;
-    ++
-    ++	/** The remote_state that this remote belongs to. This is only meant to
-    ++	 * be used by remote_* functions. */
-    ++	struct remote_state *remote_state;
-    + };
-    + 
-    + /**
-    +@@ remote.h: struct branch {
-    + 	int merge_alloc;
-    + 
-    + 	const char *push_tracking_ref;
-    ++
-    ++	/** The remote_state that this branch belongs to. This is only meant to
-    ++	 * be used by branch_* functions. */
-    ++	struct remote_state *remote_state;
-    + };
-    + 
-    + struct branch *branch_get(const char *name);
-3:  ff12771f06 < -:  ---------- remote: add struct repository parameter to external functions
--:  ---------- > 3:  10fbb84496 remote: remove the_repository->remote_state from static methods
--:  ---------- > 4:  4013f74fd9 remote: add struct repository parameter to external functions
+    @@ remote.h: struct remote_state {
+      };
+      
+      void remote_state_clear(struct remote_state *remote_state);
+    -@@ remote.h: struct remote {
+    - 
+    - 	/* The method used for authenticating against `http_proxy`. */
+    - 	char *http_proxy_authmethod;
+    -+
+    -+	/** The remote_state that this remote belongs to. This is only meant to
+    -+	 * be used by remote_* functions. */
+    -+	struct remote_state *remote_state;
+    - };
+    - 
+    - /**
+    -@@ remote.h: struct branch {
+    - 	int merge_alloc;
+    - 
+    - 	const char *push_tracking_ref;
+    -+
+    -+	/** The remote_state that this branch belongs to. This is only meant to
+    -+	 * be used by branch_* functions. */
+    -+	struct remote_state *remote_state;
+    - };
+    - 
+    - struct branch *branch_get(const char *name);
+3:  10fbb84496 < -:  ---------- remote: remove the_repository->remote_state from static methods
+4:  4013f74fd9 < -:  ---------- remote: add struct repository parameter to external functions
+-:  ---------- > 4:  53f2e31f72 remote: remove the_repository->remote_state from static methods
+-:  ---------- > 5:  d3281c14eb remote: die if branch is not found in repository
+-:  ---------- > 6:  0974994cc6 remote: add struct repository parameter to external functions
 -- 
 2.33.GIT
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help