* [PATCH 0/4] Handle FETCH_HEAD generically
@ 2020-08-17 15:39 Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 1/4] Split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
` (5 more replies)
0 siblings, 6 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-17 15:39 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys
This moves the FETCH_HEAD handling into refs.c as discussed in
https://public-inbox.org/git/xmqq5z9pav01.fsf@gitster.c.googlers.com/
Han-Wen Nienhuys (4):
Split off reading loose ref data in separate function
refs: fix comment about submodule ref_stores
refs: move gitdir into base ref_store
refs: read FETCH_HEAD generically
refs.c | 27 +++++++++++++++++++++++-
refs/files-backend.c | 49 ++++++++++++++++++++++---------------------
refs/packed-backend.c | 1 +
refs/refs-internal.h | 11 +++++++++-
4 files changed, 62 insertions(+), 26 deletions(-)
base-commit: dc04167d378fb29d30e1647ff6ff51dd182bc9a3
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-705%2Fhanwen%2Ffetch-head-generically-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-705/hanwen/fetch-head-generically-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/705
--
gitgitgadget
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/4] Split off reading loose ref data in separate function
2020-08-17 15:39 [PATCH 0/4] Handle FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
@ 2020-08-17 15:39 ` Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 2/4] refs: fix comment about submodule ref_stores Han-Wen Nienhuys via GitGitGadget
` (4 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-17 15:39 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
This prepares for handling FETCH_HEAD (which is not a regular ref)
separately from the ref backend.
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs/files-backend.c | 34 +++++++++++++++++++---------------
refs/refs-internal.h | 6 ++++++
2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 985631f33e..3a3573986f 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -360,7 +360,6 @@ static int files_read_raw_ref(struct ref_store *ref_store,
struct strbuf sb_path = STRBUF_INIT;
const char *path;
const char *buf;
- const char *p;
struct stat st;
int fd;
int ret = -1;
@@ -465,6 +464,21 @@ static int files_read_raw_ref(struct ref_store *ref_store,
close(fd);
strbuf_rtrim(&sb_contents);
buf = sb_contents.buf;
+
+ ret = parse_loose_ref_contents(buf, oid, referent, type);
+
+out:
+ save_errno = errno;
+ strbuf_release(&sb_path);
+ strbuf_release(&sb_contents);
+ errno = save_errno;
+ return ret;
+}
+
+int parse_loose_ref_contents(const char *buf, struct object_id *oid,
+ struct strbuf *referent, unsigned int *type)
+{
+ const char *p;
if (skip_prefix(buf, "ref:", &buf)) {
while (isspace(*buf))
buf++;
@@ -472,29 +486,19 @@ static int files_read_raw_ref(struct ref_store *ref_store,
strbuf_reset(referent);
strbuf_addstr(referent, buf);
*type |= REF_ISSYMREF;
- ret = 0;
- goto out;
+ return 0;
}
/*
- * Please note that FETCH_HEAD has additional
- * data after the sha.
+ * FETCH_HEAD has additional data after the sha.
*/
if (parse_oid_hex(buf, oid, &p) ||
(*p != '\0' && !isspace(*p))) {
*type |= REF_ISBROKEN;
errno = EINVAL;
- goto out;
+ return -1;
}
-
- ret = 0;
-
-out:
- save_errno = errno;
- strbuf_release(&sb_path);
- strbuf_release(&sb_contents);
- errno = save_errno;
- return ret;
+ return 0;
}
static void unlock_ref(struct ref_lock *lock)
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 357359a0be..24d79fb5c1 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -674,6 +674,12 @@ struct ref_store {
const struct ref_storage_be *be;
};
+/*
+ * Parse contents of a loose ref file.
+ */
+int parse_loose_ref_contents(const char *buf, struct object_id *oid,
+ struct strbuf *referent, unsigned int *type);
+
/*
* Fill in the generic part of refs and add it to our collection of
* reference stores.
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/4] refs: fix comment about submodule ref_stores
2020-08-17 15:39 [PATCH 0/4] Handle FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 1/4] Split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
@ 2020-08-17 15:39 ` Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 3/4] refs: move gitdir into base ref_store Han-Wen Nienhuys via GitGitGadget
` (3 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-17 15:39 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs/refs-internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 24d79fb5c1..9188ddbec2 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -667,7 +667,7 @@ extern struct ref_storage_be refs_be_packed;
/*
* A representation of the reference store for the main repository or
* a submodule. The ref_store instances for submodules are kept in a
- * linked list.
+ * hash map; see get_submodule_ref_store() for more info.
*/
struct ref_store {
/* The backend describing this ref_store's storage scheme: */
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/4] refs: move gitdir into base ref_store
2020-08-17 15:39 [PATCH 0/4] Handle FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 1/4] Split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 2/4] refs: fix comment about submodule ref_stores Han-Wen Nienhuys via GitGitGadget
@ 2020-08-17 15:39 ` Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 4/4] refs: read FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
` (2 subsequent siblings)
5 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-17 15:39 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs/files-backend.c | 15 ++++++---------
refs/packed-backend.c | 1 +
refs/refs-internal.h | 3 +++
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 3a3573986f..dd712e47f4 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -67,7 +67,6 @@ struct files_ref_store {
struct ref_store base;
unsigned int store_flags;
- char *gitdir;
char *gitcommondir;
struct ref_cache *loose;
@@ -94,18 +93,17 @@ static struct ref_store *files_ref_store_create(const char *gitdir,
struct ref_store *ref_store = (struct ref_store *)refs;
struct strbuf sb = STRBUF_INIT;
+ ref_store->gitdir = xstrdup(gitdir);
base_ref_store_init(ref_store, &refs_be_files);
refs->store_flags = flags;
- refs->gitdir = xstrdup(gitdir);
get_common_dir_noenv(&sb, gitdir);
refs->gitcommondir = strbuf_detach(&sb, NULL);
strbuf_addf(&sb, "%s/packed-refs", refs->gitcommondir);
refs->packed_ref_store = packed_ref_store_create(sb.buf, flags);
strbuf_release(&sb);
- chdir_notify_reparent("files-backend $GIT_DIR",
- &refs->gitdir);
+ chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir);
chdir_notify_reparent("files-backend $GIT_COMMONDIR",
&refs->gitcommondir);
@@ -176,7 +174,7 @@ static void files_reflog_path(struct files_ref_store *refs,
switch (ref_type(refname)) {
case REF_TYPE_PER_WORKTREE:
case REF_TYPE_PSEUDOREF:
- strbuf_addf(sb, "%s/logs/%s", refs->gitdir, refname);
+ strbuf_addf(sb, "%s/logs/%s", refs->base.gitdir, refname);
break;
case REF_TYPE_OTHER_PSEUDOREF:
case REF_TYPE_MAIN_PSEUDOREF:
@@ -198,7 +196,7 @@ static void files_ref_path(struct files_ref_store *refs,
switch (ref_type(refname)) {
case REF_TYPE_PER_WORKTREE:
case REF_TYPE_PSEUDOREF:
- strbuf_addf(sb, "%s/%s", refs->gitdir, refname);
+ strbuf_addf(sb, "%s/%s", refs->base.gitdir, refname);
break;
case REF_TYPE_MAIN_PSEUDOREF:
if (!skip_prefix(refname, "main-worktree/", &refname))
@@ -2203,12 +2201,11 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st
files_downcast(ref_store, REF_STORE_READ,
"reflog_iterator_begin");
- if (!strcmp(refs->gitdir, refs->gitcommondir)) {
+ if (!strcmp(refs->base.gitdir, refs->gitcommondir)) {
return reflog_iterator_begin(ref_store, refs->gitcommondir);
} else {
return merge_ref_iterator_begin(
- 0,
- reflog_iterator_begin(ref_store, refs->gitdir),
+ 0, reflog_iterator_begin(ref_store, refs->base.gitdir),
reflog_iterator_begin(ref_store, refs->gitcommondir),
reflog_iterator_select, refs);
}
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 4458a0f69c..b912f2505f 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -200,6 +200,7 @@ struct ref_store *packed_ref_store_create(const char *path,
struct ref_store *ref_store = (struct ref_store *)refs;
base_ref_store_init(ref_store, &refs_be_packed);
+ ref_store->gitdir = xstrdup(path);
refs->store_flags = store_flags;
refs->path = xstrdup(path);
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 9188ddbec2..527b0a6e2e 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -672,6 +672,9 @@ extern struct ref_storage_be refs_be_packed;
struct ref_store {
/* The backend describing this ref_store's storage scheme: */
const struct ref_storage_be *be;
+
+ /* The gitdir that this ref_store applies to: */
+ char *gitdir;
};
/*
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/4] refs: read FETCH_HEAD generically
2020-08-17 15:39 [PATCH 0/4] Handle FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
` (2 preceding siblings ...)
2020-08-17 15:39 ` [PATCH 3/4] refs: move gitdir into base ref_store Han-Wen Nienhuys via GitGitGadget
@ 2020-08-17 15:39 ` Han-Wen Nienhuys via GitGitGadget
2020-08-17 19:40 ` [PATCH 0/4] Handle " Junio C Hamano
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
5 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-17 15:39 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
The FETCH_HEAD ref must be stored in a file, regardless of the type of
ref backend. This is because it can hold more than just a single ref.
To accomodate FETCH_HEAD for alternate ref backends, read FETCH_HEAD
from a file generically in refs_read_raw_ref()
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/refs.c b/refs.c
index 2dd851fe81..ab7d62e237 100644
--- a/refs.c
+++ b/refs.c
@@ -1634,11 +1634,36 @@ int for_each_rawref(each_ref_fn fn, void *cb_data)
return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
}
+static int refs_read_fetch_head(struct ref_store *ref_store,
+ struct object_id *oid, struct strbuf *referent,
+ unsigned int *type)
+{
+ struct strbuf full_path = STRBUF_INIT;
+ struct strbuf content = STRBUF_INIT;
+ int result = -1;
+ strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, "FETCH_HEAD");
+
+ if (strbuf_read_file(&content, full_path.buf, 0) < 0)
+ goto done;
+
+ result = parse_loose_ref_contents(content.buf, oid, referent, type);
+
+done:
+ strbuf_release(&full_path);
+ strbuf_release(&content);
+ return result;
+}
+
int refs_read_raw_ref(struct ref_store *ref_store,
const char *refname, struct object_id *oid,
struct strbuf *referent, unsigned int *type)
{
- return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type);
+ if (!strcmp(refname, "FETCH_HEAD")) {
+ return refs_read_fetch_head(ref_store, oid, referent, type);
+ }
+
+ return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
+ type);
}
/* This function needs to return a meaningful errno on failure */
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 0/4] Handle FETCH_HEAD generically
2020-08-17 15:39 [PATCH 0/4] Handle FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
` (3 preceding siblings ...)
2020-08-17 15:39 ` [PATCH 4/4] refs: read FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
@ 2020-08-17 19:40 ` Junio C Hamano
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
5 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2020-08-17 19:40 UTC (permalink / raw)
To: Han-Wen Nienhuys via GitGitGadget; +Cc: git, Han-Wen Nienhuys
"Han-Wen Nienhuys via GitGitGadget" <gitgitgadget@gmail.com> writes:
> This moves the FETCH_HEAD handling into refs.c as discussed in
> https://public-inbox.org/git/xmqq5z9pav01.fsf@gitster.c.googlers.com/
>
> Han-Wen Nienhuys (4):
> Split off reading loose ref data in separate function
> refs: fix comment about submodule ref_stores
> refs: move gitdir into base ref_store
> refs: read FETCH_HEAD generically
>
> refs.c | 27 +++++++++++++++++++++++-
> refs/files-backend.c | 49 ++++++++++++++++++++++---------------------
> refs/packed-backend.c | 1 +
> refs/refs-internal.h | 11 +++++++++-
> 4 files changed, 62 insertions(+), 26 deletions(-)
Nice. Quite cleanly done.
Will queue; thanks.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically
2020-08-17 15:39 [PATCH 0/4] Handle FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
` (4 preceding siblings ...)
2020-08-17 19:40 ` [PATCH 0/4] Handle " Junio C Hamano
@ 2020-08-19 14:27 ` Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 1/4] refs: split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
` (4 more replies)
5 siblings, 5 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-19 14:27 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys
This moves the FETCH_HEAD handling into refs.c as discussed in
https://public-inbox.org/git/xmqq5z9pav01.fsf@gitster.c.googlers.com/
Han-Wen Nienhuys (4):
refs: split off reading loose ref data in separate function
refs: fix comment about submodule ref_stores
refs: move gitdir into base ref_store
refs: read FETCH_HEAD and MERGE_HEAD generically
refs.c | 28 ++++++++++++++++++++++++-
refs/files-backend.c | 49 ++++++++++++++++++++++---------------------
refs/packed-backend.c | 1 +
refs/refs-internal.h | 11 +++++++++-
4 files changed, 63 insertions(+), 26 deletions(-)
base-commit: 2befe97201e1f3175cce557866c5822793624b5a
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-705%2Fhanwen%2Ffetch-head-generically-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-705/hanwen/fetch-head-generically-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/705
Range-diff vs v1:
1: 10b333695e ! 1: 557727064d Split off reading loose ref data in separate function
@@ Metadata
Author: Han-Wen Nienhuys <hanwen@google.com>
## Commit message ##
- Split off reading loose ref data in separate function
+ refs: split off reading loose ref data in separate function
This prepares for handling FETCH_HEAD (which is not a regular ref)
separately from the ref backend.
2: 52b397ec9e = 2: 6da0e62e73 refs: fix comment about submodule ref_stores
3: c624e17dc6 = 3: 6263b4b3f2 refs: move gitdir into base ref_store
4: d4e9c5f499 ! 4: a3e903e4c0 refs: read FETCH_HEAD generically
@@ Metadata
Author: Han-Wen Nienhuys <hanwen@google.com>
## Commit message ##
- refs: read FETCH_HEAD generically
+ refs: read FETCH_HEAD and MERGE_HEAD generically
- The FETCH_HEAD ref must be stored in a file, regardless of the type of
- ref backend. This is because it can hold more than just a single ref.
+ The FETCH_HEAD and MERGE_HEAD refs must be stored in a file, regardless of the
+ type of ref backend. This is because they can hold more than just a single ref.
- To accomodate FETCH_HEAD for alternate ref backends, read FETCH_HEAD
- from a file generically in refs_read_raw_ref()
+ To accomodate them for alternate ref backends, read them from a file generically
+ in refs_read_raw_ref()
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
@@ refs.c: int for_each_rawref(each_ref_fn fn, void *cb_data)
return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
}
-+static int refs_read_fetch_head(struct ref_store *ref_store,
-+ struct object_id *oid, struct strbuf *referent,
-+ unsigned int *type)
++static int refs_read_special_head(struct ref_store *ref_store,
++ const char *refname, struct object_id *oid,
++ struct strbuf *referent, unsigned int *type)
+{
+ struct strbuf full_path = STRBUF_INIT;
+ struct strbuf content = STRBUF_INIT;
+ int result = -1;
-+ strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, "FETCH_HEAD");
++ strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, refname);
+
+ if (strbuf_read_file(&content, full_path.buf, 0) < 0)
+ goto done;
@@ refs.c: int for_each_rawref(each_ref_fn fn, void *cb_data)
struct strbuf *referent, unsigned int *type)
{
- return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type);
-+ if (!strcmp(refname, "FETCH_HEAD")) {
-+ return refs_read_fetch_head(ref_store, oid, referent, type);
++ if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) {
++ return refs_read_special_head(ref_store, refname, oid, referent,
++ type);
+ }
+
+ return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
--
gitgitgadget
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/4] refs: split off reading loose ref data in separate function
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
@ 2020-08-19 14:27 ` Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 2/4] refs: fix comment about submodule ref_stores Han-Wen Nienhuys via GitGitGadget
` (3 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-19 14:27 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
This prepares for handling FETCH_HEAD (which is not a regular ref)
separately from the ref backend.
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs/files-backend.c | 34 +++++++++++++++++++---------------
refs/refs-internal.h | 6 ++++++
2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 985631f33e..3a3573986f 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -360,7 +360,6 @@ static int files_read_raw_ref(struct ref_store *ref_store,
struct strbuf sb_path = STRBUF_INIT;
const char *path;
const char *buf;
- const char *p;
struct stat st;
int fd;
int ret = -1;
@@ -465,6 +464,21 @@ static int files_read_raw_ref(struct ref_store *ref_store,
close(fd);
strbuf_rtrim(&sb_contents);
buf = sb_contents.buf;
+
+ ret = parse_loose_ref_contents(buf, oid, referent, type);
+
+out:
+ save_errno = errno;
+ strbuf_release(&sb_path);
+ strbuf_release(&sb_contents);
+ errno = save_errno;
+ return ret;
+}
+
+int parse_loose_ref_contents(const char *buf, struct object_id *oid,
+ struct strbuf *referent, unsigned int *type)
+{
+ const char *p;
if (skip_prefix(buf, "ref:", &buf)) {
while (isspace(*buf))
buf++;
@@ -472,29 +486,19 @@ static int files_read_raw_ref(struct ref_store *ref_store,
strbuf_reset(referent);
strbuf_addstr(referent, buf);
*type |= REF_ISSYMREF;
- ret = 0;
- goto out;
+ return 0;
}
/*
- * Please note that FETCH_HEAD has additional
- * data after the sha.
+ * FETCH_HEAD has additional data after the sha.
*/
if (parse_oid_hex(buf, oid, &p) ||
(*p != '\0' && !isspace(*p))) {
*type |= REF_ISBROKEN;
errno = EINVAL;
- goto out;
+ return -1;
}
-
- ret = 0;
-
-out:
- save_errno = errno;
- strbuf_release(&sb_path);
- strbuf_release(&sb_contents);
- errno = save_errno;
- return ret;
+ return 0;
}
static void unlock_ref(struct ref_lock *lock)
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 357359a0be..24d79fb5c1 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -674,6 +674,12 @@ struct ref_store {
const struct ref_storage_be *be;
};
+/*
+ * Parse contents of a loose ref file.
+ */
+int parse_loose_ref_contents(const char *buf, struct object_id *oid,
+ struct strbuf *referent, unsigned int *type);
+
/*
* Fill in the generic part of refs and add it to our collection of
* reference stores.
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/4] refs: fix comment about submodule ref_stores
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 1/4] refs: split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
@ 2020-08-19 14:27 ` Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 3/4] refs: move gitdir into base ref_store Han-Wen Nienhuys via GitGitGadget
` (2 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-19 14:27 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs/refs-internal.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 24d79fb5c1..9188ddbec2 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -667,7 +667,7 @@ extern struct ref_storage_be refs_be_packed;
/*
* A representation of the reference store for the main repository or
* a submodule. The ref_store instances for submodules are kept in a
- * linked list.
+ * hash map; see get_submodule_ref_store() for more info.
*/
struct ref_store {
/* The backend describing this ref_store's storage scheme: */
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/4] refs: move gitdir into base ref_store
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 1/4] refs: split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 2/4] refs: fix comment about submodule ref_stores Han-Wen Nienhuys via GitGitGadget
@ 2020-08-19 14:27 ` Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 4/4] refs: read FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-19 21:09 ` [PATCH v2 0/4] Handle " Junio C Hamano
4 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-19 14:27 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs/files-backend.c | 15 ++++++---------
refs/packed-backend.c | 1 +
refs/refs-internal.h | 3 +++
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 3a3573986f..dd712e47f4 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -67,7 +67,6 @@ struct files_ref_store {
struct ref_store base;
unsigned int store_flags;
- char *gitdir;
char *gitcommondir;
struct ref_cache *loose;
@@ -94,18 +93,17 @@ static struct ref_store *files_ref_store_create(const char *gitdir,
struct ref_store *ref_store = (struct ref_store *)refs;
struct strbuf sb = STRBUF_INIT;
+ ref_store->gitdir = xstrdup(gitdir);
base_ref_store_init(ref_store, &refs_be_files);
refs->store_flags = flags;
- refs->gitdir = xstrdup(gitdir);
get_common_dir_noenv(&sb, gitdir);
refs->gitcommondir = strbuf_detach(&sb, NULL);
strbuf_addf(&sb, "%s/packed-refs", refs->gitcommondir);
refs->packed_ref_store = packed_ref_store_create(sb.buf, flags);
strbuf_release(&sb);
- chdir_notify_reparent("files-backend $GIT_DIR",
- &refs->gitdir);
+ chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir);
chdir_notify_reparent("files-backend $GIT_COMMONDIR",
&refs->gitcommondir);
@@ -176,7 +174,7 @@ static void files_reflog_path(struct files_ref_store *refs,
switch (ref_type(refname)) {
case REF_TYPE_PER_WORKTREE:
case REF_TYPE_PSEUDOREF:
- strbuf_addf(sb, "%s/logs/%s", refs->gitdir, refname);
+ strbuf_addf(sb, "%s/logs/%s", refs->base.gitdir, refname);
break;
case REF_TYPE_OTHER_PSEUDOREF:
case REF_TYPE_MAIN_PSEUDOREF:
@@ -198,7 +196,7 @@ static void files_ref_path(struct files_ref_store *refs,
switch (ref_type(refname)) {
case REF_TYPE_PER_WORKTREE:
case REF_TYPE_PSEUDOREF:
- strbuf_addf(sb, "%s/%s", refs->gitdir, refname);
+ strbuf_addf(sb, "%s/%s", refs->base.gitdir, refname);
break;
case REF_TYPE_MAIN_PSEUDOREF:
if (!skip_prefix(refname, "main-worktree/", &refname))
@@ -2203,12 +2201,11 @@ static struct ref_iterator *files_reflog_iterator_begin(struct ref_store *ref_st
files_downcast(ref_store, REF_STORE_READ,
"reflog_iterator_begin");
- if (!strcmp(refs->gitdir, refs->gitcommondir)) {
+ if (!strcmp(refs->base.gitdir, refs->gitcommondir)) {
return reflog_iterator_begin(ref_store, refs->gitcommondir);
} else {
return merge_ref_iterator_begin(
- 0,
- reflog_iterator_begin(ref_store, refs->gitdir),
+ 0, reflog_iterator_begin(ref_store, refs->base.gitdir),
reflog_iterator_begin(ref_store, refs->gitcommondir),
reflog_iterator_select, refs);
}
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index 4458a0f69c..b912f2505f 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -200,6 +200,7 @@ struct ref_store *packed_ref_store_create(const char *path,
struct ref_store *ref_store = (struct ref_store *)refs;
base_ref_store_init(ref_store, &refs_be_packed);
+ ref_store->gitdir = xstrdup(path);
refs->store_flags = store_flags;
refs->path = xstrdup(path);
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 9188ddbec2..527b0a6e2e 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -672,6 +672,9 @@ extern struct ref_storage_be refs_be_packed;
struct ref_store {
/* The backend describing this ref_store's storage scheme: */
const struct ref_storage_be *be;
+
+ /* The gitdir that this ref_store applies to: */
+ char *gitdir;
};
/*
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 4/4] refs: read FETCH_HEAD and MERGE_HEAD generically
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
` (2 preceding siblings ...)
2020-08-19 14:27 ` [PATCH v2 3/4] refs: move gitdir into base ref_store Han-Wen Nienhuys via GitGitGadget
@ 2020-08-19 14:27 ` Han-Wen Nienhuys via GitGitGadget
2020-08-19 21:09 ` [PATCH v2 0/4] Handle " Junio C Hamano
4 siblings, 0 replies; 12+ messages in thread
From: Han-Wen Nienhuys via GitGitGadget @ 2020-08-19 14:27 UTC (permalink / raw)
To: git; +Cc: Han-Wen Nienhuys, Han-Wen Nienhuys
From: Han-Wen Nienhuys <hanwen@google.com>
The FETCH_HEAD and MERGE_HEAD refs must be stored in a file, regardless of the
type of ref backend. This is because they can hold more than just a single ref.
To accomodate them for alternate ref backends, read them from a file generically
in refs_read_raw_ref()
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
refs.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/refs.c b/refs.c
index cf91711968..3ee3afaf41 100644
--- a/refs.c
+++ b/refs.c
@@ -1527,11 +1527,37 @@ int for_each_rawref(each_ref_fn fn, void *cb_data)
return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
}
+static int refs_read_special_head(struct ref_store *ref_store,
+ const char *refname, struct object_id *oid,
+ struct strbuf *referent, unsigned int *type)
+{
+ struct strbuf full_path = STRBUF_INIT;
+ struct strbuf content = STRBUF_INIT;
+ int result = -1;
+ strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, refname);
+
+ if (strbuf_read_file(&content, full_path.buf, 0) < 0)
+ goto done;
+
+ result = parse_loose_ref_contents(content.buf, oid, referent, type);
+
+done:
+ strbuf_release(&full_path);
+ strbuf_release(&content);
+ return result;
+}
+
int refs_read_raw_ref(struct ref_store *ref_store,
const char *refname, struct object_id *oid,
struct strbuf *referent, unsigned int *type)
{
- return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type);
+ if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) {
+ return refs_read_special_head(ref_store, refname, oid, referent,
+ type);
+ }
+
+ return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
+ type);
}
/* This function needs to return a meaningful errno on failure */
--
gitgitgadget
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
` (3 preceding siblings ...)
2020-08-19 14:27 ` [PATCH v2 4/4] refs: read FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
@ 2020-08-19 21:09 ` Junio C Hamano
4 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2020-08-19 21:09 UTC (permalink / raw)
To: Han-Wen Nienhuys via GitGitGadget; +Cc: git, Han-Wen Nienhuys
"Han-Wen Nienhuys via GitGitGadget" <gitgitgadget@gmail.com> writes:
> This moves the FETCH_HEAD handling into refs.c as discussed in
> https://public-inbox.org/git/xmqq5z9pav01.fsf@gitster.c.googlers.com/
Thanks. The way the support for MERGE_HEAD is added to the series
looks very sensible, too.
Will replace.
> -+static int refs_read_fetch_head(struct ref_store *ref_store,
> -+ struct object_id *oid, struct strbuf *referent,
> -+ unsigned int *type)
> ++static int refs_read_special_head(struct ref_store *ref_store,
> ++ const char *refname, struct object_id *oid,
> ++ struct strbuf *referent, unsigned int *type)
> +{
> + struct strbuf full_path = STRBUF_INIT;
> + struct strbuf content = STRBUF_INIT;
> + int result = -1;
> -+ strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, "FETCH_HEAD");
> ++ strbuf_addf(&full_path, "%s/%s", ref_store->gitdir, refname);
> +
> + if (strbuf_read_file(&content, full_path.buf, 0) < 0)
> + goto done;
> @@ refs.c: int for_each_rawref(each_ref_fn fn, void *cb_data)
> struct strbuf *referent, unsigned int *type)
> {
> - return ref_store->be->read_raw_ref(ref_store, refname, oid, referent, type);
> -+ if (!strcmp(refname, "FETCH_HEAD")) {
> -+ return refs_read_fetch_head(ref_store, oid, referent, type);
> ++ if (!strcmp(refname, "FETCH_HEAD") || !strcmp(refname, "MERGE_HEAD")) {
> ++ return refs_read_special_head(ref_store, refname, oid, referent,
> ++ type);
> + }
> +
> + return ref_store->be->read_raw_ref(ref_store, refname, oid, referent,
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2020-08-19 21:09 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-08-17 15:39 [PATCH 0/4] Handle FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 1/4] Split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 2/4] refs: fix comment about submodule ref_stores Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 3/4] refs: move gitdir into base ref_store Han-Wen Nienhuys via GitGitGadget
2020-08-17 15:39 ` [PATCH 4/4] refs: read FETCH_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-17 19:40 ` [PATCH 0/4] Handle " Junio C Hamano
2020-08-19 14:27 ` [PATCH v2 0/4] Handle FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 1/4] refs: split off reading loose ref data in separate function Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 2/4] refs: fix comment about submodule ref_stores Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 3/4] refs: move gitdir into base ref_store Han-Wen Nienhuys via GitGitGadget
2020-08-19 14:27 ` [PATCH v2 4/4] refs: read FETCH_HEAD and MERGE_HEAD generically Han-Wen Nienhuys via GitGitGadget
2020-08-19 21:09 ` [PATCH v2 0/4] Handle " Junio C Hamano
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).