commit - 133d2798cc7d235f7491a2969b2cbb700841d8e8
commit + 7a9df742c247f62cb09b77ae4bd3fb8006636553
blob - 0e9c41091b0428d930e156d856221cc4b93568b9
blob + 155fa1f5fc5510b74867022977ae2fb902fba6a0
--- lib/fileindex.c
+++ lib/fileindex.c
#include "got_lib_path.h"
#include "got_lib_fileindex.h"
-RB_HEAD(got_fileindex_tree, got_fileindex_entry);
-
struct got_fileindex {
struct got_fileindex_tree entries;
int nentries;
#define GOT_FILEIDX_MAX_ENTRIES INT_MAX
};
-static int
-cmp_entries(const struct got_fileindex_entry *e1,
- const struct got_fileindex_entry *e2)
-{
- return got_compare_paths(e1->path, e2->path);
-}
-
-RB_PROTOTYPE(got_fileindex_tree, got_fileindex_entry, entry, cmp_entries);
-
const struct got_error *
got_fileindex_entry_update(struct got_fileindex_entry *entry,
const char *ondisk_path, uint8_t *blob_sha1, uint8_t *commit_sha1)
return NULL;
}
-RB_GENERATE(got_fileindex_tree, got_fileindex_entry, entry, cmp_entries);
+RB_GENERATE(got_fileindex_tree, got_fileindex_entry, entry, got_fileindex_cmp);
blob - a4eea20ed8786fb17ccd6fc5fef8407373f53b8d
blob + 3291b6aed6248fb6f4ab7108567a32208b6bc876
--- lib/got_lib_fileindex.h
+++ lib/got_lib_fileindex.h
struct got_fileindex;
+RB_HEAD(got_fileindex_tree, got_fileindex_entry);
+
+static inline int
+got_fileindex_cmp(const struct got_fileindex_entry *e1,
+ const struct got_fileindex_entry *e2)
+{
+ return got_compare_paths(e1->path, e2->path);
+}
+
+RB_PROTOTYPE(got_fileindex_tree, got_fileindex_entry, entry, got_fileindex_cmp);
+
/* On-disk file index header structure. */
struct got_fileindex_hdr {
uint32_t signature; /* big-endian */
blob - d4cd4a81a07a392be5d29d277af8a84eda0030db
blob + 408e0bd8f8d26ff2e25ef7ee4e2a7533ae792ba6
--- lib/worktree.c
+++ lib/worktree.c
#include "got_lib_worktree.h"
#include "got_lib_path.h"
-#include "got_lib_pathset.h"
#include "got_lib_sha1.h"
#include "got_lib_fileindex.h"
#include "got_lib_inflate.h"
struct collect_missing_entry_args {
struct got_fileindex *fileindex;
const struct got_tree_entries *entries;
- struct got_pathset *missing_entries;
+ struct got_fileindex_tree missing_entries;
const char *current_subdir;
};
}
}
- if (found)
- return NULL;
+ if (!found) {
+ got_fileindex_entry_remove(a->fileindex, entry);
+ RB_INSERT(got_fileindex_tree, &a->missing_entries, entry);
+ }
- return got_pathset_add(a->missing_entries, entry->path, entry);
+ return NULL;
}
-struct remove_missing_file_args {
- const char *root_path;
- struct got_fileindex *fileindex;
- got_worktree_checkout_cb progress_cb;
- void *progress_arg;
- got_worktree_cancel_cb cancel_cb;
- void *cancel_arg;
-};
-
static const struct got_error *
-remove_missing_file(const char *path, void *data, void *arg)
+remove_ondisk_file(const char *root_path, const char *path)
{
const struct got_error *err = NULL;
char *ondisk_path = NULL;
- struct remove_missing_file_args *a = arg;
- struct got_fileindex_entry *entry = data;
- if (a->cancel_cb) {
- err = (*a->cancel_cb)(a->cancel_arg);
- if (err)
- return err;
- }
-
- (*a->progress_cb)(a->progress_arg, GOT_STATUS_DELETE, path);
-
- if (asprintf(&ondisk_path, "%s/%s", a->root_path, path) == -1)
+ if (asprintf(&ondisk_path, "%s/%s", root_path, path) == -1)
return got_error_from_errno();
if (unlink(ondisk_path) == -1)
err = got_error_from_errno();
else {
char *parent = dirname(ondisk_path);
- while (parent && strcmp(parent, a->root_path) != 0) {
+ while (parent && strcmp(parent, root_path) != 0) {
if (rmdir(parent) == -1) {
if (errno != ENOTEMPTY)
err = got_error_from_errno();
}
}
free(ondisk_path);
-
- if (err == NULL) {
- got_fileindex_entry_remove(a->fileindex, entry);
- got_fileindex_entry_free(entry);
- }
return err;
}
{
const struct got_error *err = NULL;
struct collect_missing_entry_args a;
- struct remove_missing_file_args a2;
+ struct got_fileindex_entry *entry, *tmp;
a.fileindex = fileindex;
a.entries = entries;
- a.missing_entries = got_pathset_alloc();
- if (a.missing_entries == NULL)
- return got_error_from_errno();
+ RB_INIT(&a.missing_entries);
a.current_subdir = apply_path_prefix(worktree, path);
err = got_fileindex_for_each_entry_safe(fileindex,
collect_missing_file, &a);
if (err)
return err;
- a2.root_path = worktree->root_path;
- a2.fileindex = fileindex;
- a2.cancel_cb = cancel_cb;
- a2.cancel_arg = cancel_arg;
- a2.progress_cb = progress_cb;
- a2.progress_arg = progress_arg;
- err = got_pathset_for_each_safe(a.missing_entries, remove_missing_file,
- &a2);
- got_pathset_free(a.missing_entries);
+ RB_FOREACH_SAFE(entry, got_fileindex_tree, &a.missing_entries, tmp) {
+ if (cancel_cb) {
+ err = (*cancel_cb)(cancel_arg);
+ if (err)
+ break;
+ }
+
+ (*progress_cb)(progress_arg, GOT_STATUS_DELETE, entry->path);
+ err = remove_ondisk_file(worktree->root_path, entry->path);
+ if (err)
+ break;
+
+ RB_REMOVE(got_fileindex_tree, &a.missing_entries, entry);
+ got_fileindex_entry_free(entry);
+ }
+
+ if (err) {
+ /* Add back any entries which weeren't deleted from disk. */
+ RB_FOREACH(entry, got_fileindex_tree, &a.missing_entries) {
+ if (got_fileindex_entry_add(fileindex, entry) != NULL)
+ break;
+ }
+ }
+
return err;
}