[PATCH v20 15/21] Read FETCH_HEAD as loose ref

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Han-Wen Nienhuys <hanwen@xxxxxxxxxx>

FETCH_HEAD is a loose ref (either symref or OID), followed by further
metadata. It can therefore not be read through a ref backend
normally. Special case this in reftable-backend.c.

This functionality is shared between all backends, but the ref backend
interface doesn't have a method to retrieve the repository directory,
hence this functionality must be pushed down to the backend
implementation.

Signed-off-by: Han-Wen Nienhuys <hanwen@xxxxxxxxxx>
---
 refs/reftable-backend.c | 31 +++++++++++++++++++++++++++++++
 t/t0031-reftable.sh     |  9 ++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c
index 93f3d337b6..8d30f3ea61 100644
--- a/refs/reftable-backend.c
+++ b/refs/reftable-backend.c
@@ -1304,6 +1304,33 @@ git_reftable_reflog_expire(struct ref_store *ref_store, const char *refname,
 	return err;
 }
 
+static int read_fetch_head(struct git_reftable_ref_store *refs,
+			   const char *refname, struct object_id *oid,
+			   struct strbuf *referent, unsigned int *type)
+{
+	struct strbuf sb = STRBUF_INIT;
+	struct strbuf path_sb = STRBUF_INIT;
+	int ret = -1;
+	int fd;
+	strbuf_addf(&path_sb, "%s/%s", refs->repo_dir, refname);
+	fd = open(path_sb.buf, O_RDONLY);
+	if (fd < 0) {
+		goto out;
+	}
+	strbuf_reset(&sb);
+	if (strbuf_read(&sb, fd, 256) < 0) {
+		ret = -1;
+	}
+	strbuf_rtrim(&sb);
+
+	ret = parse_loose_ref_contents(sb.buf, oid, referent, type);
+out:
+	close(fd);
+	strbuf_release(&sb);
+	strbuf_release(&path_sb);
+	return ret;
+}
+
 static int git_reftable_read_raw_ref(struct ref_store *ref_store,
 				     const char *refname, struct object_id *oid,
 				     struct strbuf *referent,
@@ -1319,6 +1346,10 @@ static int git_reftable_read_raw_ref(struct ref_store *ref_store,
 		return refs->err;
 	}
 
+	if (!strcmp(refname, "FETCH_HEAD")) {
+		return read_fetch_head(refs, refname, oid, referent, type);
+	}
+
 	/* This is usually not needed, but Git doesn't signal to ref backend if
 	   a subprocess updated the ref DB.  So we always check.
 	*/
diff --git a/t/t0031-reftable.sh b/t/t0031-reftable.sh
index a6634bc882..9f90c10030 100755
--- a/t/t0031-reftable.sh
+++ b/t/t0031-reftable.sh
@@ -169,5 +169,12 @@ test_expect_success 'worktrees 2' '
 	git worktree add --detach existing_empty master
 '
 
-test_done
+test_expect_success 'FETCH_HEAD' '
+        initialize &&
+	test_commit one &&
+	(git init sub && cd sub && test_commit two) &&
+	git fetch sub &&
+	git checkout FETCH_HEAD
+'
 
+test_done
-- 
gitgitgadget




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux