"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Omar Polo <op@omarpolo.com>
Subject:
Re: teach worktree and fileindex about sha256
To:
Stefan Sperling <stsp@stsp.name>
Cc:
gameoftrees@openbsd.org
Date:
Sun, 14 Jul 2024 17:57:05 +0200

Download raw body.

Thread
Stefan Sperling <stsp@stsp.name> wrote:
> On Sun, Jul 14, 2024 at 11:43:38AM +0200, Omar Polo wrote:
> > This changes the worktree code and the fileindex so they know about
> > sha256.  It is only to have `got checkout' and `got update' working,
> > there's no code yet to write objects so commit/tag/rebase/merge etc
> > won't work.
> > 
> > The worktree gains a new file, .got/object-format, so that we know what
> > to expect when opening a worktree.  The fileindex version is bumped and
> > it gains a new field for the hashing algorithm, as well as changes to
> > accomodate for sha256 hashes.
> > 
> > Be careful when testing the diff: several got operations will re-create
> > the fileindex and a v3 one will be created.  If we then commit a
> > different diff, the worktree may be unusable.  Also, the worktree will
> > be unusable by previous got version.
> > 
> > I'm changing a few uint8_t *_sha1[SHA1_DIGEST_LENGTH] to structures
> > got_object_id because it makes a lot of things way more easy to handle.
> > 
> > I'm not happy about the way I'm handling the absence of the
> > object-format file.  read_meta_file doesn't really gives us a way to
> > know whether the file is just not there.
> > 
> > ok?
> 
> No, mainly because by adding a new file in .got this patch changes the
> work tree format without bumping the work tree format number (checked
> by open_worktree()).
> 
> I believe the hash algorithm should be stored in the fileindex itself.
> Adding another file in .got creates a risk of inconsistency (both
> this file and fileindex data must agree).
> We could then keep the work tree format the same and only bump the
> fileindex version.

Yeah, actually I like the diff better now that we don't try to add the
object-format to the worktree too.

> Regardless, perhaps both the work tree format number and the fileindex
> format number should be bumped. Otherwise old got clients might assume
> that writing the current sha1-only format is fine.
> However, we currently have no code to upgrade the work tree format since
> it has not yet been changed since got-0.1.

Here's the updated diff then.  The fileindex version is still bumped
(and it's compatible with the one in the previous diff -- there nothing
changed), but instead we require to pass the `repo' down to some more
functions.  This means that cmd_info() now needs to open the repo, but I
don't think it's a tragedy.

(this is because we need to now the wanted algorithm at checkout time,
and due to how the code is structured it's difficult to extract that case
from the others.)


diff /home/op/w/got
commit - 0adc4fa2d86b99cbb48d304a89cd7b5a81c94be6
path + /home/op/w/got
blob - 8371183b94f386e42d65020ff1fed931a40906e3
file + cvg/cvg.c
--- cvg/cvg.c
+++ cvg/cvg.c
@@ -9023,11 +9023,13 @@ static const struct got_error *
 cmd_info(int argc, char *argv[])
 {
 	const struct got_error *error = NULL;
+	struct got_repository *repo = NULL;
 	struct got_worktree *worktree = NULL;
 	char *cwd = NULL, *id_str = NULL;
 	struct got_pathlist_head paths;
 	char *uuidstr = NULL;
 	int ch, show_files = 0;
+	int *pack_fds = NULL;
 
 	TAILQ_INIT(&paths);
 
@@ -9061,6 +9063,15 @@ cmd_info(int argc, char *argv[])
 		goto done;
 	}
 
+	error = got_repo_pack_fds_open(&pack_fds);
+	if (error != NULL)
+		goto done;
+
+	error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), NULL,
+	    pack_fds);
+	if (error)
+		goto done;
+
 #ifndef PROFILE
 	/* Remove "wpath cpath proc exec sendfd" promises. */
 	if (pledge("stdio rpath flock unveil", NULL) == -1)
@@ -9107,7 +9118,7 @@ cmd_info(int argc, char *argv[])
 			 */
 			pe->data = (void *)got_error(GOT_ERR_BAD_PATH);
 		}
-		error = got_worktree_path_info(worktree, &paths,
+		error = got_worktree_path_info(worktree, repo, &paths,
 		    print_path_info, &paths, check_cancelled, NULL);
 		if (error)
 			goto done;
@@ -9125,6 +9136,17 @@ cmd_info(int argc, char *argv[])
 done:
 	if (worktree)
 		got_worktree_close(worktree);
+	if (repo) {
+		const struct got_error *close_err = got_repo_close(repo);
+		if (error == NULL)
+			error = close_err;
+	}
+	if (pack_fds) {
+		const struct got_error *pack_err =
+		    got_repo_pack_fds_close(pack_fds);
+		if (error == NULL)
+			error = pack_err;
+	}
 	got_pathlist_free(&paths, GOT_PATHLIST_FREE_PATH);
 	free(cwd);
 	free(id_str);
blob - 128d0458991aa5cef9680a2b0ca92d02b65c4caf
file + got/got.c
--- got/got.c
+++ got/got.c
@@ -14609,10 +14609,12 @@ static const struct got_error *
 cmd_info(int argc, char *argv[])
 {
 	const struct got_error *error = NULL;
+	struct got_repository *repo = NULL;
 	struct got_worktree *worktree = NULL;
 	char *cwd = NULL, *id_str = NULL;
 	struct got_pathlist_head paths;
 	char *uuidstr = NULL;
+	int *pack_fds = NULL;
 	int ch, show_files = 0;
 
 	TAILQ_INIT(&paths);
@@ -14647,6 +14649,15 @@ cmd_info(int argc, char *argv[])
 		goto done;
 	}
 
+	error = got_repo_pack_fds_open(&pack_fds);
+	if (error != NULL)
+		goto done;
+
+	error = got_repo_open(&repo, got_worktree_get_repo_path(worktree), NULL,
+	    pack_fds);
+	if (error)
+		goto done;
+
 #ifndef PROFILE
 	/* Remove "wpath cpath proc exec sendfd" promises. */
 	if (pledge("stdio rpath flock unveil", NULL) == -1)
@@ -14693,7 +14704,7 @@ cmd_info(int argc, char *argv[])
 			 */
 			pe->data = (void *)got_error(GOT_ERR_BAD_PATH);
 		}
-		error = got_worktree_path_info(worktree, &paths,
+		error = got_worktree_path_info(worktree, repo, &paths,
 		    print_path_info, &paths, check_cancelled, NULL);
 		if (error)
 			goto done;
@@ -14711,6 +14722,17 @@ cmd_info(int argc, char *argv[])
 done:
 	if (worktree)
 		got_worktree_close(worktree);
+	if (repo) {
+		const struct got_error *close_err = got_repo_close(repo);
+		if (error == NULL)
+			error = close_err;
+	}
+	if (pack_fds) {
+		const struct got_error *pack_err =
+		    got_repo_pack_fds_close(pack_fds);
+		if (error == NULL)
+			error = pack_err;
+	}
 	got_pathlist_free(&paths, GOT_PATHLIST_FREE_PATH);
 	free(cwd);
 	free(id_str);
blob - d2b62724acbc48c141e49a60bd36765fe2c58cad
file + include/got_worktree.h
--- include/got_worktree.h
+++ include/got_worktree.h
@@ -590,8 +590,9 @@ typedef const struct got_error *(*got_worktree_path_in
  * a path, and meta-data arguments (see got_worktree_path_info_cb).
  */
 const struct got_error *
-got_worktree_path_info(struct got_worktree *, struct got_pathlist_head *,
-    got_worktree_path_info_cb, void *, got_cancel_cb , void *);
+got_worktree_path_info(struct got_worktree *, struct got_repository *,
+    struct got_pathlist_head *, got_worktree_path_info_cb, void *,
+    got_cancel_cb , void *);
 
 /* References pointing at pre-rebase commit backups. */
 #define GOT_WORKTREE_REBASE_BACKUP_REF_PREFIX "refs/got/backup/rebase"
@@ -604,7 +605,7 @@ got_worktree_path_info(struct got_worktree *, struct g
  */
 const struct got_error *
 got_worktree_patch_prepare(struct got_fileindex **, char **,
-    struct got_worktree *);
+    struct got_worktree *, struct got_repository *);
 
 /*
  * Lookup paths for the "old" and "new" file before patching and check their
blob - 145e81afb23853a38e8678b9912d4d9f5510a5e3
file + lib/fileindex.c
--- lib/fileindex.c
+++ lib/fileindex.c
@@ -55,6 +55,7 @@ struct got_fileindex {
 	struct got_fileindex_tree entries;
 	int nentries; /* Does not include entries marked for removal. */
 #define GOT_FILEIDX_MAX_ENTRIES INT32_MAX
+	enum got_hash_algorithm algo;
 };
 
 mode_t
@@ -90,8 +91,8 @@ got_fileindex_perms_to_st(struct got_fileindex_entry *
 
 const struct got_error *
 got_fileindex_entry_update(struct got_fileindex_entry *ie,
-    int wt_fd, const char *ondisk_path, uint8_t *blob_sha1,
-    uint8_t *commit_sha1, int update_timestamps)
+    int wt_fd, const char *ondisk_path, struct got_object_id *blob,
+    struct got_object_id *commit, int update_timestamps)
 {
 	struct stat sb;
 
@@ -128,14 +129,14 @@ got_fileindex_entry_update(struct got_fileindex_entry 
 		}
 	}
 
-	if (blob_sha1) {
-		memmove(ie->blob_sha1, blob_sha1, SHA1_DIGEST_LENGTH);
+	if (blob) {
+		memmove(&ie->blob, blob, sizeof(ie->blob));
 		ie->flags &= ~GOT_FILEIDX_F_NO_BLOB;
 	} else
 		ie->flags |= GOT_FILEIDX_F_NO_BLOB;
 
-	if (commit_sha1) {
-		memmove(ie->commit_sha1, commit_sha1, SHA1_DIGEST_LENGTH);
+	if (commit) {
+		memmove(&ie->commit, commit, sizeof(ie->commit));
 		ie->flags &= ~GOT_FILEIDX_F_NO_COMMIT;
 	} else
 		ie->flags |= GOT_FILEIDX_F_NO_COMMIT;
@@ -332,7 +333,7 @@ got_fileindex_for_each_entry_safe(struct got_fileindex
 }
 
 struct got_fileindex *
-got_fileindex_alloc(void)
+got_fileindex_alloc(enum got_hash_algorithm algo)
 {
 	struct got_fileindex *fileindex;
 
@@ -340,6 +341,7 @@ got_fileindex_alloc(void)
 	if (fileindex == NULL)
 		return NULL;
 
+	fileindex->algo = algo;
 	RB_INIT(&fileindex->entries);
 	return fileindex;
 }
@@ -425,6 +427,7 @@ write_fileindex_entry(struct got_hash *ctx, struct got
 	const struct got_error *err;
 	size_t n;
 	uint32_t stage;
+	size_t digest_len = got_hash_digest_length(ctx->algo);
 
 	err = write_fileindex_val64(ctx, ie->ctime_sec, outfile);
 	if (err)
@@ -453,14 +456,14 @@ write_fileindex_entry(struct got_hash *ctx, struct got
 	if (err)
 		return err;
 
-	got_hash_update(ctx, ie->blob_sha1, SHA1_DIGEST_LENGTH);
-	n = fwrite(ie->blob_sha1, 1, SHA1_DIGEST_LENGTH, outfile);
-	if (n != SHA1_DIGEST_LENGTH)
+	got_hash_update(ctx, ie->blob.hash, digest_len);
+	n = fwrite(ie->blob.hash, 1, digest_len, outfile);
+	if (n != digest_len)
 		return got_ferror(outfile, GOT_ERR_IO);
 
-	got_hash_update(ctx, ie->commit_sha1, SHA1_DIGEST_LENGTH);
-	n = fwrite(ie->commit_sha1, 1, SHA1_DIGEST_LENGTH, outfile);
-	if (n != SHA1_DIGEST_LENGTH)
+	got_hash_update(ctx, ie->commit.hash, digest_len);
+	n = fwrite(ie->commit.hash, 1, digest_len, outfile);
+	if (n != digest_len)
 		return got_ferror(outfile, GOT_ERR_IO);
 
 	err = write_fileindex_val32(ctx, ie->flags, outfile);
@@ -474,10 +477,10 @@ write_fileindex_entry(struct got_hash *ctx, struct got
 	stage = got_fileindex_entry_stage_get(ie);
 	if (stage == GOT_FILEIDX_STAGE_MODIFY ||
 	    stage == GOT_FILEIDX_STAGE_ADD) {
-		got_hash_update(ctx, ie->staged_blob_sha1, SHA1_DIGEST_LENGTH);
-		n = fwrite(ie->staged_blob_sha1, 1, SHA1_DIGEST_LENGTH,
+		got_hash_update(ctx, ie->staged_blob.hash, digest_len);
+		n = fwrite(ie->staged_blob.hash, 1, digest_len,
 		    outfile);
-		if (n != SHA1_DIGEST_LENGTH)
+		if (n != digest_len)
 			return got_ferror(outfile, GOT_ERR_IO);
 	}
 
@@ -491,18 +494,22 @@ got_fileindex_write(struct got_fileindex *fileindex, F
 	struct got_fileindex_hdr hdr;
 	struct got_hash ctx;
 	uint8_t hash[GOT_HASH_DIGEST_MAXLEN];
-	size_t n;
+	size_t n, digest_len = got_hash_digest_length(fileindex->algo);
 	struct got_fileindex_entry *ie, *tmp;
 
-	got_hash_init(&ctx, GOT_HASH_SHA1);
+	memset(hash, 0, sizeof(hash));
 
+	got_hash_init(&ctx, fileindex->algo);
+
 	hdr.signature = htobe32(GOT_FILE_INDEX_SIGNATURE);
 	hdr.version = htobe32(GOT_FILE_INDEX_VERSION);
 	hdr.nentries = htobe32(fileindex->nentries);
+	hdr.algo = htobe32(fileindex->algo);
 
 	got_hash_update(&ctx, &hdr.signature, sizeof(hdr.signature));
 	got_hash_update(&ctx, &hdr.version, sizeof(hdr.version));
 	got_hash_update(&ctx, &hdr.nentries, sizeof(hdr.nentries));
+	got_hash_update(&ctx, &hdr.algo, sizeof(hdr.algo));
 	n = fwrite(&hdr.signature, 1, sizeof(hdr.signature), outfile);
 	if (n != sizeof(hdr.signature))
 		return got_ferror(outfile, GOT_ERR_IO);
@@ -512,6 +519,9 @@ got_fileindex_write(struct got_fileindex *fileindex, F
 	n = fwrite(&hdr.nentries, 1, sizeof(hdr.nentries), outfile);
 	if (n != sizeof(hdr.nentries))
 		return got_ferror(outfile, GOT_ERR_IO);
+	n = fwrite(&hdr.algo, 1, sizeof(hdr.algo), outfile);
+	if (n != sizeof(hdr.nentries))
+		return got_ferror(outfile, GOT_ERR_IO);
 
 	RB_FOREACH_SAFE(ie, got_fileindex_tree, &fileindex->entries, tmp) {
 		ie->flags &= ~GOT_FILEIDX_F_NOT_FLUSHED;
@@ -527,8 +537,8 @@ got_fileindex_write(struct got_fileindex *fileindex, F
 	}
 
 	got_hash_final(&ctx, hash);
-	n = fwrite(hash, 1, SHA1_DIGEST_LENGTH, outfile);
-	if (n != SHA1_DIGEST_LENGTH)
+	n = fwrite(hash, 1, digest_len, outfile);
+	if (n != digest_len)
 		return got_ferror(outfile, GOT_ERR_IO);
 
 	if (fflush(outfile) != 0)
@@ -603,11 +613,11 @@ read_fileindex_path(char **path, struct got_hash *ctx,
 
 static const struct got_error *
 read_fileindex_entry(struct got_fileindex_entry **iep, struct got_hash *ctx,
-    FILE *infile, uint32_t version)
+    FILE *infile, uint32_t version, enum got_hash_algorithm algo)
 {
 	const struct got_error *err;
 	struct got_fileindex_entry *ie;
-	size_t n;
+	size_t n, digest_len = got_hash_digest_length(algo);
 
 	*iep = NULL;
 
@@ -642,19 +652,21 @@ read_fileindex_entry(struct got_fileindex_entry **iep,
 	if (err)
 		goto done;
 
-	n = fread(ie->blob_sha1, 1, SHA1_DIGEST_LENGTH, infile);
-	if (n != SHA1_DIGEST_LENGTH) {
+	ie->blob.algo = algo;
+	n = fread(ie->blob.hash, 1, digest_len, infile);
+	if (n != digest_len) {
 		err = got_ferror(infile, GOT_ERR_FILEIDX_BAD);
 		goto done;
 	}
-	got_hash_update(ctx, ie->blob_sha1, SHA1_DIGEST_LENGTH);
+	got_hash_update(ctx, ie->blob.hash, digest_len);
 
-	n = fread(ie->commit_sha1, 1, SHA1_DIGEST_LENGTH, infile);
-	if (n != SHA1_DIGEST_LENGTH) {
+	ie->commit.algo = algo;
+	n = fread(ie->commit.hash, 1, digest_len, infile);
+	if (n != digest_len) {
 		err = got_ferror(infile, GOT_ERR_FILEIDX_BAD);
 		goto done;
 	}
-	got_hash_update(ctx, ie->commit_sha1, SHA1_DIGEST_LENGTH);
+	got_hash_update(ctx, ie->commit.hash, digest_len);
 
 	err = read_fileindex_val32(&ie->flags, ctx, infile);
 	if (err)
@@ -668,14 +680,15 @@ read_fileindex_entry(struct got_fileindex_entry **iep,
 		uint32_t stage = got_fileindex_entry_stage_get(ie);
 		if (stage == GOT_FILEIDX_STAGE_MODIFY ||
 		    stage == GOT_FILEIDX_STAGE_ADD) {
-			n = fread(ie->staged_blob_sha1, 1, SHA1_DIGEST_LENGTH,
+			ie->staged_blob.algo = algo;
+			n = fread(ie->staged_blob.hash, 1, digest_len,
 			    infile);
-			if (n != SHA1_DIGEST_LENGTH) {
+			if (n != digest_len) {
 				err = got_ferror(infile, GOT_ERR_FILEIDX_BAD);
 				goto done;
 			}
-			got_hash_update(ctx, ie->staged_blob_sha1,
-			    SHA1_DIGEST_LENGTH);
+			got_hash_update(ctx, ie->staged_blob.hash,
+			    digest_len);
 		}
 	} else {
 		/* GOT_FILE_INDEX_VERSION 1 does not support staging. */
@@ -691,19 +704,20 @@ done:
 }
 
 const struct got_error *
-got_fileindex_read(struct got_fileindex *fileindex, FILE *infile)
+got_fileindex_read(struct got_fileindex *fileindex, FILE *infile,
+    enum got_hash_algorithm repo_algo)
 {
 	const struct got_error *err = NULL;
 	struct got_fileindex_hdr hdr;
 	struct got_hash ctx;
 	struct got_fileindex_entry *ie;
-	uint8_t sha1_expected[SHA1_DIGEST_LENGTH];
-	uint8_t sha1[SHA1_DIGEST_LENGTH];
-	size_t n;
+	enum got_hash_algorithm algo = repo_algo;
+	uint8_t hash_expected[GOT_HASH_DIGEST_MAXLEN];
+	uint8_t hash[GOT_HASH_DIGEST_MAXLEN];
+	size_t n, digest_len;
+	uint32_t version;
 	int i;
 
-	got_hash_init(&ctx, GOT_HASH_SHA1);
-
 	n = fread(&hdr.signature, 1, sizeof(hdr.signature), infile);
 	if (n != sizeof(hdr.signature)) {
 		if (n == 0) /* EOF */
@@ -722,22 +736,44 @@ got_fileindex_read(struct got_fileindex *fileindex, FI
 			return NULL;
 		return got_ferror(infile, GOT_ERR_FILEIDX_BAD);
 	}
+	version = be32toh(hdr.version);
 
+	if (version >= 3) {
+		n = fread(&hdr.algo, 1, sizeof(hdr.algo), infile);
+		if (n != sizeof(hdr.algo)) {
+			if (n == 0) /* EOF */
+				return NULL;
+			return got_ferror(infile, GOT_ERR_FILEIDX_BAD);
+		}
+		algo = be32toh(hdr.algo);
+		if (algo != repo_algo)
+			return got_error_fmt(GOT_ERR_OBJECT_FORMAT,
+			    "unknown object format");
+	}
+
+	digest_len = got_hash_digest_length(algo);
+
+	got_hash_init(&ctx, algo);
 	got_hash_update(&ctx, &hdr.signature, sizeof(hdr.signature));
 	got_hash_update(&ctx, &hdr.version, sizeof(hdr.version));
 	got_hash_update(&ctx, &hdr.nentries, sizeof(hdr.nentries));
+	if (version >= 3)
+		got_hash_update(&ctx, &hdr.algo, sizeof(hdr.algo));
 
 	hdr.signature = be32toh(hdr.signature);
 	hdr.version = be32toh(hdr.version);
 	hdr.nentries = be32toh(hdr.nentries);
+	hdr.algo = algo;
 
 	if (hdr.signature != GOT_FILE_INDEX_SIGNATURE)
 		return got_error(GOT_ERR_FILEIDX_SIG);
 	if (hdr.version > GOT_FILE_INDEX_VERSION)
 		return got_error(GOT_ERR_FILEIDX_VER);
 
+	fileindex->algo = algo;
 	for (i = 0; i < hdr.nentries; i++) {
-		err = read_fileindex_entry(&ie, &ctx, infile, hdr.version);
+		err = read_fileindex_entry(&ie, &ctx, infile, hdr.version,
+		    hdr.algo);
 		if (err)
 			return err;
 		err = add_entry(fileindex, ie);
@@ -747,11 +783,11 @@ got_fileindex_read(struct got_fileindex *fileindex, FI
 		}
 	}
 
-	n = fread(sha1_expected, 1, sizeof(sha1_expected), infile);
-	if (n != sizeof(sha1_expected))
+	n = fread(hash_expected, 1, digest_len, infile);
+	if (n != digest_len)
 		return got_ferror(infile, GOT_ERR_FILEIDX_BAD);
-	got_hash_final(&ctx, sha1);
-	if (memcmp(sha1, sha1_expected, SHA1_DIGEST_LENGTH) != 0)
+	got_hash_final(&ctx, hash);
+	if (got_hash_cmp(algo, hash, hash_expected) != 0)
 		return got_error(GOT_ERR_FILEIDX_CSUM);
 
 	return NULL;
@@ -1243,27 +1279,21 @@ struct got_object_id *
 got_fileindex_entry_get_staged_blob_id(struct got_object_id *id,
     struct got_fileindex_entry *ie)
 {
-	memset(id, 0, sizeof(*id));
-	memcpy(id->hash, ie->staged_blob_sha1, sizeof(ie->staged_blob_sha1));
-	return id;
+	return memcpy(id, &ie->staged_blob, sizeof(*id));
 }
 
 struct got_object_id *
 got_fileindex_entry_get_blob_id(struct got_object_id *id,
     struct got_fileindex_entry *ie)
 {
-	memset(id, 0, sizeof(*id));
-	memcpy(id->hash, ie->blob_sha1, sizeof(ie->blob_sha1));
-	return id;
+	return memcpy(id, &ie->blob, sizeof(*id));
 }
 
 struct got_object_id *
 got_fileindex_entry_get_commit_id(struct got_object_id *id,
     struct got_fileindex_entry *ie)
 {
-	memset(id, 0, sizeof(*id));
-	memcpy(id->hash, ie->commit_sha1, sizeof(ie->commit_sha1));
-	return id;
+	return memcpy(id, &ie->commit, sizeof(*id));
 }
 
 RB_GENERATE(got_fileindex_tree, got_fileindex_entry, entry, got_fileindex_cmp);
blob - 7045733009e3c274bef6f25b589a001bff3de260
file + lib/got_lib_fileindex.h
--- lib/got_lib_fileindex.h
+++ lib/got_lib_fileindex.h
@@ -46,11 +46,17 @@ struct got_fileindex_entry {
 #define GOT_FILEIDX_MODE_PERMS		0xfff0
 #define GOT_FILEIDX_MODE_PERMS_SHIFT	4
 
-	/* SHA1 of corresponding blob in repository. */
-	uint8_t blob_sha1[SHA1_DIGEST_LENGTH];
+	/*
+	 * id of corresponding blob in repository.  only the actual
+	 * hash is written to the disk.
+	 */
+	struct got_object_id blob;
 
-	/* SHA1 of corresponding base commit in repository. */
-	uint8_t commit_sha1[SHA1_DIGEST_LENGTH];
+	/*
+	 * id of corresponding base commit in repository.  only the
+	 * actual hash is written to the disk.
+	 */
+	struct got_object_id commit;
 
 	uint32_t flags;
 
@@ -62,11 +68,12 @@ struct got_fileindex_entry {
 
 	/*
 	 * (since GOT_FILE_INDEX_VERSION 2)
-	 * SHA1 of staged blob in repository if stage equals either
+	 * Hash of staged blob in repository if stage equals either
 	 * GOT_FILEIDX_STAGE_MODIFY or GOT_FILEIDX_STAGE_ADD.
 	 * Otherwise, this field is not written to disk.
+	 * Only the actual hash is written to the disk.
 	 */
-	uint8_t staged_blob_sha1[SHA1_DIGEST_LENGTH];
+	struct got_object_id staged_blob;
 };
 
 /* Modifications explicitly staged for commit. */
@@ -97,10 +104,15 @@ struct got_fileindex_hdr {
 	uint32_t signature;	/* big-endian */
 #define GOT_FILE_INDEX_SIGNATURE	0x676f7449 /* 'g', 'o', 't', 'I' */
 	uint32_t version;	/* big-endian */
-#define GOT_FILE_INDEX_VERSION	2
+#define GOT_FILE_INDEX_VERSION	3
 	uint32_t nentries;	/* big-endian */
+	uint32_t algo;		/* big-endian -- since v3 */
 	/* list of concatenated fileindex entries */
-	uint8_t sha1[SHA1_DIGEST_LENGTH]; /* checksum of above on-disk data */
+	/*
+	 * checksum of above on-disk data, the actual length of the
+	 * hash depends on the algorithm.
+	 */
+	uint8_t hash[GOT_HASH_DIGEST_MAXLEN];
 };
 
 mode_t got_fileindex_entry_perms_get(struct got_fileindex_entry *);
@@ -108,13 +120,13 @@ uint16_t got_fileindex_perms_from_st(struct stat *);
 mode_t got_fileindex_perms_to_st(struct got_fileindex_entry *);
 
 const struct got_error *got_fileindex_entry_update(struct got_fileindex_entry *,
-    int, const char *, uint8_t *, uint8_t *, int);
+    int, const char *, struct got_object_id *, struct got_object_id *, int);
 void got_fileindex_entry_mark_skipped(struct got_fileindex_entry *);
 const struct got_error *got_fileindex_entry_alloc(struct got_fileindex_entry **,
     const char *);
 void got_fileindex_entry_free(struct got_fileindex_entry *);
 
-struct got_fileindex *got_fileindex_alloc(void);
+struct got_fileindex *got_fileindex_alloc(enum got_hash_algorithm);
 void got_fileindex_free(struct got_fileindex *);
 const struct got_error *got_fileindex_write(struct got_fileindex *, FILE *);
 const struct got_error *got_fileindex_entry_add(struct got_fileindex *,
@@ -123,7 +135,8 @@ void got_fileindex_entry_remove(struct got_fileindex *
     struct got_fileindex_entry *);
 struct got_fileindex_entry *got_fileindex_entry_get(struct got_fileindex *,
     const char *, size_t);
-const struct got_error *got_fileindex_read(struct got_fileindex *, FILE *);
+const struct got_error *got_fileindex_read(struct got_fileindex *, FILE *,
+	enum got_hash_algorithm);
 typedef const struct got_error *(*got_fileindex_cb)(void *,
     struct got_fileindex_entry *);
 const struct got_error *got_fileindex_for_each_entry_safe(
blob - 4afb73ee23fb9c7a71b841ff617b0d817f7de341
file + lib/patch.c
--- lib/patch.c
+++ lib/patch.c
@@ -1082,7 +1082,7 @@ got_patch(int fd, struct got_worktree *worktree, struc
 		goto done;
 
 	err = got_worktree_patch_prepare(&fileindex, &fileindex_path,
-	    worktree);
+	    worktree, repo);
 	if (err)
 		goto done;
 
blob - bcfaef17f181af2634bca5eb3d7db41766783487
file + lib/worktree.c
--- lib/worktree.c
+++ lib/worktree.c
@@ -1117,7 +1117,7 @@ create_fileindex_entry(struct got_fileindex_entry **ne
 		return err;
 
 	err = got_fileindex_entry_update(new_ie, wt_fd, path,
-	    blob_id->hash, base_commit_id->hash, update_timestamps);
+	    blob_id, base_commit_id, update_timestamps);
 	if (err)
 		goto done;
 
@@ -1900,7 +1900,7 @@ sync_timestamps(int wt_fd, const char *path, unsigned 
 {
 	if (status == GOT_STATUS_NO_CHANGE && stat_info_differs(ie, sb))
 		return got_fileindex_entry_update(ie, wt_fd, path,
-		    ie->blob_sha1, ie->commit_sha1, 1);
+		    &ie->blob, &ie->commit, 1);
 
 	return NULL;
 }
@@ -2003,8 +2003,8 @@ update_blob(struct got_worktree *worktree,
 		 * updating contents of this file.
 		 */
 		if (got_fileindex_entry_has_commit(ie) &&
-		    memcmp(ie->commit_sha1, worktree->base_commit_id->hash,
-		    SHA1_DIGEST_LENGTH) == 0) {
+		    got_object_id_cmp(&ie->commit,
+		    worktree->base_commit_id) == 0) {
 			/* Same commit. */
 			err = sync_timestamps(worktree->root_fd,
 			    path, status, ie, &sb);
@@ -2015,14 +2015,12 @@ update_blob(struct got_worktree *worktree,
 			goto done;
 		}
 		if (got_fileindex_entry_has_blob(ie) &&
-		    memcmp(ie->blob_sha1, te->id.hash,
-		    SHA1_DIGEST_LENGTH) == 0) {
+		    got_object_id_cmp(&ie->blob, &te->id) == 0) {
 			/* Different commit but the same blob. */
 			if (got_fileindex_entry_has_commit(ie)) {
 				/* Update the base commit ID of this file. */
-				memcpy(ie->commit_sha1,
-				    worktree->base_commit_id->hash,
-				    sizeof(ie->commit_sha1));
+				memcpy(&ie->commit, worktree->base_commit_id,
+				    sizeof(ie->commit));
 			}
 			err = sync_timestamps(worktree->root_fd,
 			    path, status, ie, &sb);
@@ -2060,9 +2058,10 @@ update_blob(struct got_worktree *worktree,
 				goto done;
 		}
 		if (got_fileindex_entry_has_commit(ie)) {
-			char id_str[SHA1_DIGEST_STRING_LENGTH];
-			if (got_sha1_digest_to_str(ie->commit_sha1, id_str,
-			    sizeof(id_str)) == NULL) {
+			char id_str[GOT_HASH_DIGEST_STRING_MAXLEN];
+
+			if (got_hash_digest_to_str(ie->commit.hash, id_str,
+			    sizeof(id_str), ie->commit.algo) == NULL) {
 				err = got_error_path(id_str,
 				    GOT_ERR_BAD_OBJ_ID_STR);
 				goto done;
@@ -2103,17 +2102,16 @@ update_blob(struct got_worktree *worktree,
 		 * unmodified files again.
 		 */
 		err = got_fileindex_entry_update(ie, worktree->root_fd, path,
-		    blob->id.hash, worktree->base_commit_id->hash,
-		    update_timestamps);
+		    &blob->id, worktree->base_commit_id, update_timestamps);
 	} else if (status == GOT_STATUS_MODE_CHANGE) {
 		err = got_fileindex_entry_update(ie, worktree->root_fd, path,
-		    blob->id.hash, worktree->base_commit_id->hash, 0);
+		    &blob->id, worktree->base_commit_id, 0);
 	} else if (status == GOT_STATUS_DELETE) {
 		err = (*progress_cb)(progress_arg, GOT_STATUS_MERGE, path);
 		if (err)
 			goto done;
 		err = got_fileindex_entry_update(ie, worktree->root_fd, path,
-		    blob->id.hash, worktree->base_commit_id->hash, 0);
+		    &blob->id, worktree->base_commit_id, 0);
 		if (err)
 			goto done;
 	} else {
@@ -2137,8 +2135,8 @@ update_blob(struct got_worktree *worktree,
 
 		if (ie) {
 			err = got_fileindex_entry_update(ie,
-			    worktree->root_fd, path, blob->id.hash,
-			    worktree->base_commit_id->hash, 1);
+			    worktree->root_fd, path, &blob->id,
+			    worktree->base_commit_id, 1);
 		} else {
 			err = create_fileindex_entry(&ie, fileindex,
 			    worktree->base_commit_id, worktree->root_fd, path,
@@ -2514,13 +2512,13 @@ get_fileindex_path(char **fileindex_path, struct got_w
 
 static const struct got_error *
 open_fileindex(struct got_fileindex **fileindex, char **fileindex_path,
-    struct got_worktree *worktree)
+    struct got_worktree *worktree, enum got_hash_algorithm algo)
 {
 	const struct got_error *err = NULL;
 	FILE *index = NULL;
 
+	*fileindex = got_fileindex_alloc(algo);
 	*fileindex_path = NULL;
-	*fileindex = got_fileindex_alloc();
 	if (*fileindex == NULL)
 		return got_error_from_errno("got_fileindex_alloc");
 
@@ -2533,7 +2531,7 @@ open_fileindex(struct got_fileindex **fileindex, char 
 		if (errno != ENOENT)
 			err = got_error_from_errno2("fopen", *fileindex_path);
 	} else {
-		err = got_fileindex_read(*fileindex, index);
+		err = got_fileindex_read(*fileindex, index, algo);
 		if (fclose(index) == EOF && err == NULL)
 			err = got_error_from_errno("fclose");
 	}
@@ -2571,8 +2569,7 @@ bump_base_commit_id(void *arg, struct got_fileindex_en
 	if (got_fileindex_entry_was_skipped(ie))
 		return NULL;
 
-	if (memcmp(ie->commit_sha1, a->base_commit_id->hash,
-	    SHA1_DIGEST_LENGTH) == 0)
+	if (got_object_id_cmp(&ie->commit, a->base_commit_id) == 0)
 		return NULL;
 
 	if (a->progress_cb) {
@@ -2581,7 +2578,7 @@ bump_base_commit_id(void *arg, struct got_fileindex_en
 		if (err)
 			return err;
 	}
-	memcpy(ie->commit_sha1, a->base_commit_id->hash, SHA1_DIGEST_LENGTH);
+	memcpy(&ie->commit, a->base_commit_id, sizeof(ie->commit));
 	return NULL;
 }
 
@@ -2870,7 +2867,8 @@ got_worktree_checkout_files(struct got_worktree *workt
 	 * Checking out files is supposed to be an idempotent operation.
 	 * If the on-disk file index is incomplete we will try to complete it.
 	 */
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -2968,8 +2966,8 @@ add_file(struct got_worktree *worktree, struct got_fil
 	} else {
 		/* Re-adding a locally deleted file. */
 		err = got_fileindex_entry_update(ie,
-		    worktree->root_fd, path2, ie->blob_sha1,
-		    worktree->base_commit_id->hash, 0);
+		    worktree->root_fd, path2, &ie->blob,
+		    worktree->base_commit_id, 0);
 		if (err)
 			return err;
 	}
@@ -3322,8 +3320,7 @@ check_mixed_commits(void *arg, struct got_fileindex_en
 
 	/* Reject merges into a work tree with mixed base commits. */
 	if (got_fileindex_entry_has_commit(ie) &&
-	    memcmp(ie->commit_sha1, a->worktree->base_commit_id->hash,
-	    SHA1_DIGEST_LENGTH) != 0)
+	    got_object_id_cmp(&ie->commit, a->worktree->base_commit_id) != 0)
 		return got_error(GOT_ERR_MIXED_COMMITS);
 
 	return NULL;
@@ -3361,7 +3358,8 @@ got_worktree_get_state(char *state, struct got_reposit
 	cma.cancel_arg = cancel_arg;
 
 	if (got_object_id_cmp(base_id, head_id) == 0) {
-		err = open_fileindex(&fileindex, &fileindex_path, worktree);
+		err = open_fileindex(&fileindex, &fileindex_path, worktree,
+		    got_repo_get_object_format(repo));
 		if (err)
 			goto done;
 
@@ -3570,7 +3568,8 @@ got_worktree_merge_files(struct got_worktree *worktree
 	if (err)
 		return err;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -4229,7 +4228,8 @@ got_worktree_status(struct got_worktree *worktree,
 	struct got_fileindex *fileindex = NULL;
 	struct got_pathlist_entry *pe;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		return err;
 
@@ -4447,7 +4447,8 @@ got_worktree_schedule_add(struct got_worktree *worktre
 	if (err)
 		return err;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -4637,7 +4638,8 @@ got_worktree_schedule_delete(struct got_worktree *work
 	if (err)
 		return err;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -5311,8 +5313,7 @@ revert_file(void *arg, unsigned char status, unsigned 
 			    status == GOT_STATUS_MODE_CHANGE) {
 				err = got_fileindex_entry_update(ie,
 				    a->worktree->root_fd, relpath,
-				    blob->id.hash,
-				    a->worktree->base_commit_id->hash, 1);
+				    &blob->id, a->worktree->base_commit_id, 1);
 				if (err)
 					goto done;
 			}
@@ -5361,7 +5362,8 @@ got_worktree_revert(struct got_worktree *worktree,
 	if (err)
 		return err;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -6284,22 +6286,20 @@ update_fileindex_after_commit(struct got_worktree *wor
 
 				err = got_fileindex_entry_update(ie,
 				    worktree->root_fd, relpath,
-				    ct->staged_blob_id->hash,
-				    new_base_commit_id->hash,
+				    ct->staged_blob_id, new_base_commit_id,
 				    !have_staged_files);
 			} else
 				err = got_fileindex_entry_update(ie,
 				    worktree->root_fd, relpath,
-				    ct->blob_id->hash,
-				    new_base_commit_id->hash,
+				    ct->blob_id, new_base_commit_id,
 				    !have_staged_files);
 		} else {
 			err = got_fileindex_entry_alloc(&ie, pe->path);
 			if (err)
 				goto done;
 			err = got_fileindex_entry_update(ie,
-			    worktree->root_fd, relpath, ct->blob_id->hash,
-			    new_base_commit_id->hash, 1);
+			    worktree->root_fd, relpath, ct->blob_id,
+			    new_base_commit_id, 1);
 			if (err) {
 				got_fileindex_entry_free(ie);
 				goto done;
@@ -6611,7 +6611,8 @@ got_worktree_commit(struct got_object_id **new_commit_
 	if (err)
 		goto done;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -6750,8 +6751,7 @@ check_rebase_ok(void *arg, struct got_fileindex_entry 
 	char *ondisk_path;
 
 	/* Reject rebase of a work tree with mixed base commits. */
-	if (memcmp(ie->commit_sha1, a->worktree->base_commit_id->hash,
-	    SHA1_DIGEST_LENGTH))
+	if (got_object_id_cmp(&ie->commit, a->worktree->base_commit_id))
 		return got_error(GOT_ERR_MIXED_COMMITS);
 
 	if (asprintf(&ondisk_path, "%s/%s", a->worktree->root_path, ie->path)
@@ -6794,7 +6794,8 @@ got_worktree_rebase_prepare(struct got_reference **new
 	if (err)
 		return err;
 
-	err = open_fileindex(fileindex, &fileindex_path, worktree);
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -6910,7 +6911,8 @@ got_worktree_rebase_continue(struct got_object_id **co
 	if (err)
 		return err;
 
-	err = open_fileindex(fileindex, &fileindex_path, worktree);
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -7884,7 +7886,8 @@ got_worktree_histedit_prepare(struct got_reference **t
 	if (err)
 		return err;
 
-	err = open_fileindex(fileindex, &fileindex_path, worktree);
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -8020,7 +8023,8 @@ got_worktree_histedit_continue(struct got_object_id **
 	if (err)
 		return err;
 
-	err = open_fileindex(fileindex, &fileindex_path, worktree);
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -8407,7 +8411,8 @@ got_worktree_integrate_prepare(struct got_fileindex **
 		goto done;
 	}
 
-	err = open_fileindex(fileindex, &fileindex_path, worktree);
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -8791,7 +8796,8 @@ const struct got_error *got_worktree_merge_prepare(
 	if (err)
 		return err;
 
-	err = open_fileindex(fileindex, &fileindex_path, worktree);
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -8897,7 +8903,8 @@ got_worktree_merge_continue(char **branch_name,
 	if (err)
 		return err;
 
-	err = open_fileindex(fileindex, &fileindex_path, worktree);
+	err = open_fileindex(fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -9237,8 +9244,8 @@ stage_path(void *arg, unsigned char status,
 		    path_content ? path_content : ondisk_path, a->repo);
 		if (err)
 			break;
-		memcpy(ie->staged_blob_sha1, new_staged_blob_id->hash,
-		    SHA1_DIGEST_LENGTH);
+		memcpy(&ie->staged_blob, new_staged_blob_id,
+		    sizeof(ie->staged_blob));
 		if (status == GOT_STATUS_ADD || staged_status == GOT_STATUS_ADD)
 			stage = GOT_FILEIDX_STAGE_ADD;
 		else
@@ -9290,8 +9297,7 @@ stage_path(void *arg, unsigned char status,
 		 * When staging the reverse of the staged diff,
 		 * implicitly unstage the file.
 		 */
-		if (memcmp(ie->staged_blob_sha1, ie->blob_sha1,
-		    sizeof(ie->blob_sha1)) == 0) {
+		if (got_object_id_cmp(&ie->staged_blob, &ie->blob) == 0) {
 			got_fileindex_entry_stage_set(ie,
 			    GOT_FILEIDX_STAGE_NONE);
 		}
@@ -9369,7 +9375,8 @@ got_worktree_stage(struct got_worktree *worktree,
 	err = got_ref_resolve(&head_commit_id, repo, head_ref);
 	if (err)
 		goto done;
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -9708,8 +9715,8 @@ unstage_hunks(struct got_object_id *staged_blob_id,
 		goto done;
 
 	if (new_staged_blob_id) {
-		memcpy(ie->staged_blob_sha1, new_staged_blob_id->hash,
-		    SHA1_DIGEST_LENGTH);
+		memcpy(&ie->staged_blob, new_staged_blob_id,
+		    sizeof(ie->staged_blob));
 	} else {
 		got_fileindex_entry_stage_set(ie, GOT_FILEIDX_STAGE_NONE);
 		got_fileindex_entry_staged_filetype_set(ie, 0);
@@ -9916,7 +9923,8 @@ got_worktree_unstage(struct got_worktree *worktree,
 	if (err)
 		return err;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -9999,6 +10007,7 @@ report_file_info(void *arg, struct got_fileindex_entry
 
 const struct got_error *
 got_worktree_path_info(struct got_worktree *worktree,
+    struct got_repository *repo,
     struct got_pathlist_head *paths,
     got_worktree_path_info_cb info_cb, void *info_arg,
     got_cancel_cb cancel_cb, void *cancel_arg)
@@ -10013,7 +10022,8 @@ got_worktree_path_info(struct got_worktree *worktree,
 	if (err)
 		return err;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;
 
@@ -10119,9 +10129,11 @@ patch_can_edit(const char *path, unsigned char status,
 
 const struct got_error *
 got_worktree_patch_prepare(struct got_fileindex **fileindex,
-    char **fileindex_path, struct got_worktree *worktree)
+    char **fileindex_path, struct got_worktree *worktree,
+    struct got_repository *repo)
 {
-	return open_fileindex(fileindex, fileindex_path, worktree);
+	return open_fileindex(fileindex, fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 }
 
 const struct got_error *
blob - 84299babeb28ef6e301c8be76710ba7474a4deec
file + lib/worktree_cvg.c
--- lib/worktree_cvg.c
+++ lib/worktree_cvg.c
@@ -563,13 +563,13 @@ get_fileindex_path(char **fileindex_path, struct got_w
 
 static const struct got_error *
 open_fileindex(struct got_fileindex **fileindex, char **fileindex_path,
-    struct got_worktree *worktree)
+    struct got_worktree *worktree, enum got_hash_algorithm algo)
 {
 	const struct got_error *err = NULL;
 	FILE *index = NULL;
 
 	*fileindex_path = NULL;
-	*fileindex = got_fileindex_alloc();
+	*fileindex = got_fileindex_alloc(algo);
 	if (*fileindex == NULL)
 		return got_error_from_errno("got_fileindex_alloc");
 
@@ -582,7 +582,7 @@ open_fileindex(struct got_fileindex **fileindex, char 
 		if (errno != ENOENT)
 			err = got_error_from_errno2("fopen", *fileindex_path);
 	} else {
-		err = got_fileindex_read(*fileindex, index);
+		err = got_fileindex_read(*fileindex, index, algo);
 		if (fclose(index) == EOF && err == NULL)
 			err = got_error_from_errno("fclose");
 	}
@@ -2145,22 +2145,20 @@ update_fileindex_after_commit(struct got_worktree *wor
 
 				err = got_fileindex_entry_update(ie,
 				    worktree->root_fd, relpath,
-				    ct->staged_blob_id->hash,
-				    new_base_commit_id->hash,
+				    ct->staged_blob_id, new_base_commit_id,
 				    !have_staged_files);
 			} else
 				err = got_fileindex_entry_update(ie,
 				    worktree->root_fd, relpath,
-				    ct->blob_id->hash,
-				    new_base_commit_id->hash,
+				    ct->blob_id, new_base_commit_id,
 				    !have_staged_files);
 		} else {
 			err = got_fileindex_entry_alloc(&ie, pe->path);
 			if (err)
 				goto done;
 			err = got_fileindex_entry_update(ie,
-			    worktree->root_fd, relpath, ct->blob_id->hash,
-			    new_base_commit_id->hash, 1);
+			    worktree->root_fd, relpath, ct->blob_id,
+			    new_base_commit_id, 1);
 			if (err) {
 				got_fileindex_entry_free(ie);
 				goto done;
@@ -2969,7 +2967,8 @@ got_worktree_cvg_commit(struct got_object_id **new_com
 	if (err)
 		goto done;
 
-	err = open_fileindex(&fileindex, &fileindex_path, worktree);
+	err = open_fileindex(&fileindex, &fileindex_path, worktree,
+	    got_repo_get_object_format(repo));
 	if (err)
 		goto done;