commit - 8371870086b067a4afbd0acf0abeb2aaa520e862
commit + df3352425b599a7ca9e473a9024c6b5333778dc5
blob - fd6801e3bcff1fde109cec45694599f76e632479
blob + 61af730e3e3e103061ccd973a5695d28529aff30
--- lib/fileindex.c
+++ lib/fileindex.c
/* got_fileindex_entry flags */
#define GOT_FILEIDX_F_PATH_LEN 0x00000fff
#define GOT_FILEIDX_F_STAGE 0x0000f000
+#define GOT_FILEIDX_F_STAGE_SHIFT 24
#define GOT_FILEIDX_F_NOT_FLUSHED 0x00010000
#define GOT_FILEIDX_F_NO_BLOB 0x00020000
#define GOT_FILEIDX_F_NO_COMMIT 0x00040000
got_fileindex_entry_path_len(const struct got_fileindex_entry *ie)
{
return (size_t)(ie->flags & GOT_FILEIDX_F_PATH_LEN);
+}
+
+uint32_t
+got_fileindex_entry_stage(const struct got_fileindex_entry *ie)
+{
+ return ((ie->flags & GOT_FILEIDX_F_STAGE) >> GOT_FILEIDX_F_STAGE_SHIFT);
}
int
{
const struct got_error *err;
size_t n;
+ uint32_t stage;
err = write_fileindex_val64(ctx, ie->ctime_sec, outfile);
if (err)
return err;
err = write_fileindex_path(ctx, ie->path, outfile);
- return err;
+ if (err)
+ return err;
+
+ stage = got_fileindex_entry_stage(ie);
+ if (stage == GOT_FILEIDX_STAGE_MODIFY ||
+ stage == GOT_FILEIDX_STAGE_ADD) {
+ SHA1Update(ctx, ie->staged_blob_sha1, SHA1_DIGEST_LENGTH);
+ n = fwrite(ie->staged_blob_sha1, 1, SHA1_DIGEST_LENGTH,
+ outfile);
+ if (n != SHA1_DIGEST_LENGTH)
+ return got_ferror(outfile, GOT_ERR_IO);
+ }
+
+ return NULL;
}
const struct got_error *
static const struct got_error *
read_fileindex_entry(struct got_fileindex_entry **iep, SHA1_CTX *ctx,
- FILE *infile)
+ FILE *infile, uint32_t version)
{
const struct got_error *err;
struct got_fileindex_entry *ie;
goto done;
err = read_fileindex_path(&ie->path, ctx, infile);
+ if (err)
+ goto done;
+
+ if (version >= 2) {
+ uint32_t stage = got_fileindex_entry_stage(ie);
+ if (stage == GOT_FILEIDX_STAGE_MODIFY ||
+ stage == GOT_FILEIDX_STAGE_ADD) {
+ n = fread(ie->staged_blob_sha1, 1, SHA1_DIGEST_LENGTH,
+ infile);
+ if (n != SHA1_DIGEST_LENGTH) {
+ err = got_ferror(infile, GOT_ERR_FILEIDX_BAD);
+ goto done;
+ }
+ SHA1Update(ctx, ie->staged_blob_sha1, SHA1_DIGEST_LENGTH);
+ }
+ } else {
+ /* GOT_FILE_INDEX_VERSION 1 does not support staging. */
+ ie->flags &= ~GOT_FILEIDX_F_STAGE;
+ }
+
done:
if (err)
got_fileindex_entry_free(ie);
if (hdr.signature != GOT_FILE_INDEX_SIGNATURE)
return got_error(GOT_ERR_FILEIDX_SIG);
- if (hdr.version != GOT_FILE_INDEX_VERSION)
+ if (hdr.version > GOT_FILE_INDEX_VERSION)
return got_error(GOT_ERR_FILEIDX_VER);
for (i = 0; i < hdr.nentries; i++) {
- err = read_fileindex_entry(&ie, &ctx, infile);
+ err = read_fileindex_entry(&ie, &ctx, infile, hdr.version);
if (err)
return err;
err = add_entry(fileindex, ie);
blob - b66cb0c03a8223b3d72d0c72b88b83456f4f509c
blob + 33b7f142cf74b87064731e83d2bfd65101294ff3
--- lib/got_lib_fileindex.h
+++ lib/got_lib_fileindex.h
* Variable length, and NUL-padded to a multiple of 8 on disk.
*/
char *path;
+
+ /*
+ * (since GOT_FILE_INDEX_VERSION 2)
+ * SHA1 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.
+ */
+ uint8_t staged_blob_sha1[SHA1_DIGEST_LENGTH];
};
/* Modifications explicitly staged for commit. */
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 1
+#define GOT_FILE_INDEX_VERSION 2
uint32_t nentries; /* big-endian */
/* list of concatenated fileindex entries */
uint8_t sha1[SHA1_DIGEST_LENGTH]; /* checksum of above on-disk data */