From: Felipe Contreras <felipe.contreras@gmail.com>
To: git@vger.kernel.org
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Jeff King" <peff@peff.net>, "Patrick Steinhardt" <ps@pks.im>,
"Jonathan Nieder" <jrnieder@gmail.com>,
"Felipe Contreras" <felipe.contreras@gmail.com>
Subject: [PATCH v2 0/2] Add fetch.updateHead option
Date: Thu, 6 Apr 2023 20:37:34 -0600 [thread overview]
Message-ID: <20230407023736.49190-1-felipe.contreras@gmail.com> (raw)
It's surprising that `git clone` and `git init && git remote add -f` don't
create the same remote state.
Fix this by introducing a new configuration: `fetch.updateHead` which updates
the remote `HEAD` when it's not present with "missing", or always with
"always".
By default it's "never", which retains the current behavior.
This has already been discussed before [1].
Changes since v1:
1. Make `fetch_update_head` a named enum as suggested by Ævar
2. Remove `need_update_head`: use switch case instead, per Ævar
3. Make `update_head` receive `fetch_missing` boolean, instead of enum,
per Ævar
4. Make `update_head` receive an unconsted `struct remote`: worse, but
simplifies the review process
[1] https://lore.kernel.org/git/20201118091219.3341585-1-felipe.contreras@gmail.com/
Felipe Contreras (2):
Add fetch.updateHead option
fetch: add support for HEAD update on mirrors
Documentation/config/fetch.txt | 4 ++
Documentation/config/remote.txt | 3 ++
builtin/fetch.c | 76 ++++++++++++++++++++++++++++++++-
remote.c | 20 +++++++++
remote.h | 12 ++++++
t/t5510-fetch.sh | 49 +++++++++++++++++++++
6 files changed, 163 insertions(+), 1 deletion(-)
Range-diff against v1:
1: 1cb238c83d ! 1: 0b80baba39 Add fetch.updateHead option
@@ Commit message
For the next major version of Git, we might want to change this default.
+ Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
## Documentation/config/fetch.txt ##
@@ builtin/fetch.c: static int fetch_prune_tags_config = -1; /* unspecified */
static int prune_tags = -1; /* unspecified */
#define PRUNE_TAGS_BY_DEFAULT 0 /* do we prune tags by default? */
-+static int fetch_update_head = FETCH_UPDATE_HEAD_DEFAULT;
++static enum fetch_update_head fetch_update_head = FETCH_UPDATE_HEAD_DEFAULT;
+
static int all, append, dry_run, force, keep, multiple, update_head_ok;
static int write_fetch_head = 1;
@@ builtin/fetch.c: static int backfill_tags(struct transport *transport,
return retcode;
}
-+static void update_head(int config, const struct ref *head, const struct remote *remote)
++static void update_head(int fetch_missing, const struct ref *head,
++ struct remote *remote)
+{
+ char *ref, *target;
+ const char *r;
@@ builtin/fetch.c: static int backfill_tags(struct transport *transport,
+ if (!head || !head->symref || !remote)
+ return;
+
-+ ref = apply_refspecs((struct refspec *)&remote->fetch, "refs/heads/HEAD");
-+ target = apply_refspecs((struct refspec *)&remote->fetch, head->symref);
++ ref = apply_refspecs(&remote->fetch, "refs/heads/HEAD");
++ target = apply_refspecs(&remote->fetch, head->symref);
+
+ if (!ref || !target) {
+ warning(_("could not update remote head"));
@@ builtin/fetch.c: static int backfill_tags(struct transport *transport,
+ r = resolve_ref_unsafe(ref, 0, NULL, &flags);
+
+ if (r) {
-+ if (config == FETCH_UPDATE_HEAD_MISSING) {
-+ if (flags & REF_ISSYMREF)
-+ /* already present */
-+ return;
-+ } else if (config == FETCH_UPDATE_HEAD_ALWAYS) {
++ if (!fetch_missing) {
+ if (!strcmp(r, target))
+ /* already up-to-date */
+ return;
-+ } else
-+ /* should never happen */
++ } else if (flags & REF_ISSYMREF)
++ /* already present */
+ return;
+ }
+
@@ builtin/fetch.c: static int do_fetch(struct transport *transport,
int must_list_refs = 1;
struct fetch_head fetch_head = { 0 };
struct strbuf err = STRBUF_INIT;
-+ int need_update_head = 0, update_head_config = 0;
++ enum fetch_update_head update_head_config = FETCH_UPDATE_HEAD_DEFAULT;
if (tags == TAGS_DEFAULT) {
if (transport->remote->fetch_tags == 2)
@@ builtin/fetch.c: static int do_fetch(struct transport *transport,
+ else
+ update_head_config = fetch_update_head;
+
-+ need_update_head = update_head_config && update_head_config != FETCH_UPDATE_HEAD_NEVER;
-+
-+ if (need_update_head)
++ switch (update_head_config) {
++ case FETCH_UPDATE_HEAD_MISSING:
++ case FETCH_UPDATE_HEAD_ALWAYS:
+ strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
++ default:
++ break;
++ }
refspec_ref_prefixes(&transport->remote->fetch,
&transport_ls_refs_options.ref_prefixes);
+ }
@@ builtin/fetch.c: static int do_fetch(struct transport *transport,
commit_fetch_head(&fetch_head);
-+ if (need_update_head)
-+ update_head(update_head_config, find_ref_by_name(remote_refs, "HEAD"), transport->remote);
++ switch (update_head_config) {
++ case FETCH_UPDATE_HEAD_MISSING:
++ case FETCH_UPDATE_HEAD_ALWAYS:
++ update_head(update_head_config == FETCH_UPDATE_HEAD_MISSING,
++ find_ref_by_name(remote_refs, "HEAD"),
++ transport->remote);
++ default:
++ break;
++ }
+
if (set_upstream) {
struct branch *branch = branch_get("HEAD");
@@ remote.c: static void read_branches_file(struct remote_state *remote_state,
remote->fetch_tags = 1; /* always auto-follow */
}
-+int parse_update_head(int *r, const char *var, const char *value)
++int parse_update_head(enum fetch_update_head *r, const char *var,
++ const char *value)
+{
-+ if (!r)
-+ return -1;
-+ else if (!value)
++ if (!value)
+ return config_error_nonbool(var);
+ else if (!strcmp(value, "never"))
+ *r = FETCH_UPDATE_HEAD_NEVER;
@@ remote.h: enum {
REMOTE_BRANCHES
};
-+enum {
++enum fetch_update_head {
+ FETCH_UPDATE_HEAD_DEFAULT = 0,
+ FETCH_UPDATE_HEAD_NEVER,
+ FETCH_UPDATE_HEAD_MISSING,
@@ remote.h: struct remote {
int prune;
int prune_tags;
-+ int update_head;
++ enum fetch_update_head update_head;
+
/**
* The configured helper programs to run on the remote side, for
@@ remote.h: void apply_push_cas(struct push_cas_option *, struct remote *, struct
char *relative_url(const char *remote_url, const char *url,
const char *up_path);
-+int parse_update_head(int *r, const char *var, const char *value);
++int parse_update_head(enum fetch_update_head *r, const char *var,
++ const char *value);
+
#endif
2: fe6d62510b ! 2: 5c0f48b9cc fetch: add support for HEAD update on mirrors
@@ Commit message
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
## builtin/fetch.c ##
-@@ builtin/fetch.c: static void update_head(int config, const struct ref *head, const struct remote
+@@ builtin/fetch.c: static void update_head(int fetch_missing, const struct ref *head,
if (!head || !head->symref || !remote)
return;
-- ref = apply_refspecs((struct refspec *)&remote->fetch, "refs/heads/HEAD");
-- target = apply_refspecs((struct refspec *)&remote->fetch, head->symref);
+- ref = apply_refspecs(&remote->fetch, "refs/heads/HEAD");
+- target = apply_refspecs(&remote->fetch, head->symref);
+ if (!remote->mirror) {
-+ ref = apply_refspecs((struct refspec *)&remote->fetch, "refs/heads/HEAD");
-+ target = apply_refspecs((struct refspec *)&remote->fetch, head->symref);
++ ref = apply_refspecs(&remote->fetch, "refs/heads/HEAD");
++ target = apply_refspecs(&remote->fetch, head->symref);
- if (!ref || !target) {
- warning(_("could not update remote head"));
--
2.40.0+fc1
next reply other threads:[~2023-04-07 2:37 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-07 2:37 Felipe Contreras [this message]
2023-04-07 2:37 ` [PATCH v2 1/2] Add fetch.updateHead option Felipe Contreras
2023-04-07 2:37 ` [PATCH v2 2/2] fetch: add support for HEAD update on mirrors Felipe Contreras
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230407023736.49190-1-felipe.contreras@gmail.com \
--to=felipe.contreras@gmail.com \
--cc=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
--cc=ps@pks.im \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).