This series aims to make the remotes subsystem work with non-the_repository, which will allow submodule remotes to be accessed in-process, rather than through child processes. This is accomplished by creating a struct remote_state and adding it to struct repository.
Thanks for the kind review, Jonathan. I've incorporated most of the feedback from v4, except squashing patches 2-4. My reasoning is that those changes are mechanical and keeping them separate makes it more obvious whether or not each step has been done correctly. However, I agree that they are just intermediate steps that touch the same lines, so I am happy to squash them if other reviewers prefer that.
Changes since v4: * Fixed an incorrect description of 'git push' without explicit refspecs * In patch 5, remove the branches array and keep the hashmap (note that I did not make a similar change to remotes) * Drop patch 6 because it is untested in this series (will incorporate into a future series)
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 implementation appropriately. * In patch 2, properly consider the initialized state of remote_state. In v2, I forgot to convert a static inside read_config() into a private member of struct remote_state. Fix this. * In a new patch 3, add helper methods that get a remote via remote_state and the remote name. * Move read_config(repo) calls to the external facing-functions. This keeps "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 (5): 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.c | 368 +++++++++++++++++++++++++++++------------- remote.h | 35 ++++ repository.c | 8 + repository.h | 4 + t/t5516-fetch-push.sh | 9 ++ 5 files changed, 311 insertions(+), 113 deletions(-)
Range-diff against v4:
1: 9b29ec27c6 ! 1: 7e60457e11 t5516: add test case for pushing remote refspecs
@@ Metadata
## Commit message ##
t5516: add test case for pushing remote refspecs
- In detached HEAD, "git push remote-name" should push the refspecs in
- remote.remote-name.push. Since there is no test case that checks this
- behavior, add one.
+ "git push remote-name" (that is, with no refspec given on the command
+ line) should push the refspecs in remote.remote-name.push. There is no
+ test case that checks this behavior in detached HEAD, so add one.
Signed-off-by: Glen Choo <chooglen@google.com>
@@ t/t5516-fetch-push.sh: do
done
-+test_expect_success "push to remote with detached HEAD and config remote.*.push = src:dest" '
++test_expect_success "push to remote with no explicit refspec and config remote.*.push = src:dest" '
+ mk_test testrepo heads/main &&
+ git checkout $the_first_commit &&
+ test_config remote.there.url testrepo &&
2: ca9b5ab66a = 2: ecc637ee74 remote: move static variables into per-repository struct
3: 5d6a245cae = 3: a915155979 remote: use remote_state parameter internally
4: 53f2e31f72 = 4: 8ef43570e9 remote: remove the_repository->remote_state from static methods
5: d3281c14eb ! 5: 8bb7bddda4 remote: die if branch is not found in repository
@@ Commit message
To prevent misuse, add a die_on_missing_branch() helper function that
dies if a given branch is not from a given repository. Speed up the
- existence check by using a new branches_hash hashmap to remote_state,
- and use the hashmap to remove the branch array iteration in
- make_branch().
+ existence check by replacing the branches list with a branches_hash
+ hashmap.
Like read_config(), die_on_missing_branch() is only called from
non-static functions; static functions are less prone to misuse because
@@ remote.c: static void add_merge(struct branch *branch, const char *name)
+ if (ret)
+ return ret;
- ALLOC_GROW(remote_state->branches, remote_state->branches_nr + 1,
- remote_state->branches_alloc);
-@@ remote.c: static struct branch *make_branch(struct remote_state *remote_state,
+- ALLOC_GROW(remote_state->branches, remote_state->branches_nr + 1,
+- remote_state->branches_alloc);
+ CALLOC_ARRAY(ret, 1);
+- remote_state->branches[remote_state->branches_nr++] = ret;
ret->name = xstrndup(name, len);
ret->refname = xstrfmt("refs/heads/%s", ret->name);
@@ remote.c: struct remote_state *remote_state_new(void)
return r;
}
+@@ remote.c: void remote_state_clear(struct remote_state *remote_state)
+ remote_state->remotes_nr = 0;
+
+ hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent);
+-
+- for (i = 0; i < remote_state->branches_nr; i++) {
+- FREE_AND_NULL(remote_state->branches[i]);
+- }
+- FREE_AND_NULL(remote_state->branches);
+- remote_state->branches_alloc = 0;
+- remote_state->branches_nr = 0;
++ hashmap_clear_and_free(&remote_state->branches_hash, struct remote, ent);
+ }
## remote.h ##
@@ remote.h: struct remote_state {
- struct branch **branches;
- int branches_alloc;
- int branches_nr;
+ int remotes_nr;
+ struct hashmap remotes_hash;
+
+- struct branch **branches;
+- int branches_alloc;
+- int branches_nr;
+ struct hashmap branches_hash;
struct branch *current_branch;
6: 0974994cc6 < -: ---------- remote: add struct repository parameter to external functions-- 2.33.GIT