@@ -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.
*/
@@ -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