commit - a143fb78680e46194d8a68b0fcd96b57d164a6d0
commit + 515140783dfbb42d9deb4c8edd7d251d9cdf362c
blob - a6bdde165134042c5baf59120676cb60d8c8d153
blob + 0eda1d0481edfd72a67595b0c94a5025155c779a
--- lib/fileindex.c
+++ lib/fileindex.c
#include "got_lib_fileindex.h"
const struct got_error *
-got_fileindex_entry_alloc(struct got_fileindex_entry **entry,
- const char *ondisk_path, const char *relpath, uint8_t *blob_sha1,
- uint8_t *commit_sha1)
+got_fileindex_entry_update(struct got_fileindex_entry *entry,
+ const char *ondisk_path, uint8_t *blob_sha1, uint8_t *commit_sha1)
{
struct stat sb;
- size_t len;
if (lstat(ondisk_path, &sb) != 0)
return got_error_from_errno();
+ entry->ctime_sec = sb.st_ctime;
+ entry->ctime_nsec = sb.st_ctimensec;
+ entry->mtime_sec = sb.st_mtime;
+ entry->mtime_nsec = sb.st_mtimensec;
+ entry->uid = sb.st_uid;
+ entry->gid = sb.st_gid;
+ entry->size = (sb.st_size & 0xffffffff);
+ if (sb.st_mode & S_IFLNK)
+ entry->mode = GOT_INDEX_ENTRY_MODE_SYMLINK;
+ else
+ entry->mode = GOT_INDEX_ENTRY_MODE_REGULAR_FILE;
+ entry->mode |= ((sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) <<
+ GOT_INDEX_ENTRY_MODE_PERMS_SHIFT);
+ memcpy(entry->blob_sha1, blob_sha1, SHA1_DIGEST_LENGTH);
+ memcpy(entry->commit_sha1, commit_sha1, SHA1_DIGEST_LENGTH);
+
+ return NULL;
+}
+
+const struct got_error *
+got_fileindex_entry_alloc(struct got_fileindex_entry **entry,
+ const char *ondisk_path, const char *relpath, uint8_t *blob_sha1,
+ uint8_t *commit_sha1)
+{
+ size_t len;
+
*entry = calloc(1, sizeof(**entry));
if (*entry == NULL)
return got_error_from_errno();
*entry = NULL;
return err;
}
-
- (*entry)->ctime_sec = sb.st_ctime;
- (*entry)->ctime_nsec = sb.st_ctimensec;
- (*entry)->mtime_sec = sb.st_mtime;
- (*entry)->mtime_nsec = sb.st_mtimensec;
- (*entry)->uid = sb.st_uid;
- (*entry)->gid = sb.st_gid;
- (*entry)->size = (sb.st_size & 0xffffffff);
- if (sb.st_mode & S_IFLNK)
- (*entry)->mode = GOT_INDEX_ENTRY_MODE_SYMLINK;
- else
- (*entry)->mode = GOT_INDEX_ENTRY_MODE_REGULAR_FILE;
- (*entry)->mode |= ((sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) <<
- GOT_INDEX_ENTRY_MODE_PERMS_SHIFT);
- memcpy((*entry)->blob_sha1, blob_sha1, SHA1_DIGEST_LENGTH);
- memcpy((*entry)->commit_sha1, commit_sha1, SHA1_DIGEST_LENGTH);
+
len = strlen(relpath);
if (len > GOT_INDEX_ENTRY_F_PATH_LEN)
len = GOT_INDEX_ENTRY_F_PATH_LEN;
(*entry)->flags |= len;
- return NULL;
+ return got_fileindex_entry_update(*entry, ondisk_path, blob_sha1,
+ commit_sha1);
}
void
return NULL;
}
+struct got_fileindex_entry *
+got_fileindex_entry_get(struct got_fileindex *fileindex, const char *path)
+{
+ struct got_fileindex_entry *entry;
+ TAILQ_FOREACH(entry, &fileindex->entries, entry) {
+ if (strcmp(entry->path, path) == 0)
+ return entry;
+ }
+
+ return NULL;
+}
+
struct got_fileindex *
got_fileindex_alloc(void)
{
SHA1Init(&ctx);
n = fread(buf, 1, len, infile);
- if (n != len)
+ if (n != len) {
+ if (n == 0) /* EOF */
+ return NULL;
return got_ferror(infile, GOT_ERR_IO);
+ }
SHA1Update(&ctx, buf, len);
blob - e8716e82b5c7226df522570f9907830e40f4274d
blob + 78770a187a8aeab06554502e2672852c6e8e833b
--- lib/got_lib_fileindex.h
+++ lib/got_lib_fileindex.h
uint8_t sha1[SHA1_DIGEST_LENGTH]; /* checksum of above on-disk data */
};
+const struct got_error *got_fileindex_entry_update(struct got_fileindex_entry *,
+ const char *, uint8_t *, uint8_t *);
const struct got_error *got_fileindex_entry_alloc(struct got_fileindex_entry **,
const char *, const char *, uint8_t *, uint8_t *);
void got_fileindex_entry_free(struct got_fileindex_entry *);
const struct got_error *got_fileindex_write(struct got_fileindex *, FILE *);
const struct got_error *got_fileindex_entry_add(struct got_fileindex *,
struct got_fileindex_entry *);
+struct got_fileindex_entry *got_fileindex_entry_get(struct got_fileindex *,
+ const char *);
const struct got_error *got_fileindex_read(struct got_fileindex *, FILE *);
blob - 65f2e530842a66c066ddafb9f0879a4bc0f8c9f5
blob + f6afe827f9a74a99f9dc08df62881efabab7310d
--- lib/worktree.c
+++ lib/worktree.c
fsync(fd);
- err = got_fileindex_entry_alloc(&entry, ondisk_path,
- apply_path_prefix(worktree, path), blob->id.sha1,
- worktree->base_commit_id->sha1);
- if (err)
- goto done;
-
- err = got_fileindex_entry_add(fileindex, entry);
+ entry = got_fileindex_entry_get(fileindex,
+ apply_path_prefix(worktree, path));
+ if (entry)
+ err = got_fileindex_entry_update(entry, ondisk_path,
+ blob->id.sha1, worktree->base_commit_id->sha1);
+ else {
+ err = got_fileindex_entry_alloc(&entry, ondisk_path,
+ apply_path_prefix(worktree, path), blob->id.sha1,
+ worktree->base_commit_id->sha1);
+ if (err)
+ goto done;
+ err = got_fileindex_entry_add(fileindex, entry);
+ }
if (err)
goto done;
done:
struct got_tree_object *tree = NULL;
char *fileindex_path = NULL, *new_fileindex_path = NULL;
struct got_fileindex *fileindex = NULL;
- FILE *new_index = NULL;
+ FILE *index = NULL, *new_index = NULL;
err = lock_worktree(worktree, LOCK_EX);
if (err)
goto done;
}
+ /*
+ * Read the file index.
+ * Checking out files is supposed to be an idempotent operation.
+ * If the on-disk file index is incomplete we will try to complete it.
+ */
+ index = fopen(fileindex_path, "rb");
+ if (index == NULL) {
+ err = got_error_from_errno();
+ goto done;
+ }
+ err = got_fileindex_read(fileindex, index);
+ fclose(index);
+ if (err)
+ goto done;
+
err = got_opentemp_named(&new_fileindex_path, &new_index,
fileindex_path);
if (err)