Download raw body.
change got_worktree_init, open_worktree to use fds
Here's the updated diff. With regard to committing, am I OK to
commit the initial patch (the one that adds the fd field to got_worktree)
at this point?
On Wed, Dec 9, 2020 at 8:24 AM Yang Zhong <yzhong@freebsdfoundation.org> wrote:
>
> > > + free(relpath); //NOTE add done
> >
> > Hmm. I don't understand what this comment is trying to tell me.
>
> Whoops! That's just an outdated note-to-self.
diff --git a/lib/fileindex.c b/lib/fileindex.c
index b46dbb29..6086d328 100644
--- a/lib/fileindex.c
+++ b/lib/fileindex.c
@@ -88,15 +88,15 @@ got_fileindex_perms_to_st(struct got_fileindex_entry *ie)
const struct got_error *
got_fileindex_entry_update(struct got_fileindex_entry *ie,
- const char *ondisk_path, uint8_t *blob_sha1, uint8_t *commit_sha1,
- int update_timestamps)
+ int wt_fd, const char *ondisk_path, uint8_t *blob_sha1,
+ uint8_t *commit_sha1, int update_timestamps)
{
struct stat sb;
- if (lstat(ondisk_path, &sb) != 0) {
+ if (fstatat(wt_fd, ondisk_path, &sb, AT_SYMLINK_NOFOLLOW) != 0) {
if (!((ie->flags & GOT_FILEIDX_F_NO_FILE_ON_DISK) &&
errno == ENOENT))
- return got_error_from_errno2("lstat", ondisk_path);
+ return got_error_from_errno2("fstatat", ondisk_path);
sb.st_mode = GOT_DEFAULT_FILE_MODE;
} else {
if (sb.st_mode & S_IFDIR)
diff --git a/lib/got_lib_fileindex.h b/lib/got_lib_fileindex.h
index f1005832..537374d7 100644
--- a/lib/got_lib_fileindex.h
+++ b/lib/got_lib_fileindex.h
@@ -108,7 +108,7 @@ 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 *,
- const char *, uint8_t *, uint8_t *, int);
+ int, const char *, uint8_t *, uint8_t *, int);
const struct got_error *got_fileindex_entry_alloc(struct got_fileindex_entry **,
const char *);
void got_fileindex_entry_free(struct got_fileindex_entry *);
diff --git a/lib/worktree.c b/lib/worktree.c
index 8bf4b7ff..72c9e75a 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -1175,7 +1175,7 @@ done:
static const struct got_error *
create_fileindex_entry(struct got_fileindex_entry **new_iep,
struct got_fileindex *fileindex, struct got_object_id *base_commit_id,
- const char *ondisk_path, const char *path, struct got_object_id *blob_id)
+ int wt_fd, const char *path, struct got_object_id *blob_id)
{
const struct got_error *err = NULL;
struct got_fileindex_entry *new_ie;
@@ -1186,7 +1186,7 @@ create_fileindex_entry(struct got_fileindex_entry **new_iep,
if (err)
return err;
- err = got_fileindex_entry_update(new_ie, ondisk_path,
+ err = got_fileindex_entry_update(new_ie, wt_fd, path,
blob_id->sha1, base_commit_id->sha1, 1);
if (err)
goto done;
@@ -1861,11 +1861,11 @@ done:
* we had to run a full content comparison to find out.
*/
static const struct got_error *
-sync_timestamps(char *ondisk_path, unsigned char status,
+sync_timestamps(int wt_fd, const char *path, unsigned char status,
struct got_fileindex_entry *ie, struct stat *sb)
{
if (status == GOT_STATUS_NO_CHANGE && stat_info_differs(ie, sb))
- return got_fileindex_entry_update(ie, ondisk_path,
+ return got_fileindex_entry_update(ie, wt_fd, path,
ie->blob_sha1, ie->commit_sha1, 1);
return NULL;
@@ -1918,7 +1918,8 @@ update_blob(struct got_worktree *worktree,
if (got_fileindex_entry_has_commit(ie) &&
memcmp(ie->commit_sha1, worktree->base_commit_id->sha1,
SHA1_DIGEST_LENGTH) == 0) {
- err = sync_timestamps(ondisk_path, status, ie, &sb);
+ err = sync_timestamps(worktree->root_fd,
+ path, status, ie, &sb);
if (err)
goto done;
err = (*progress_cb)(progress_arg, GOT_STATUS_EXISTS,
@@ -1928,7 +1929,8 @@ update_blob(struct got_worktree *worktree,
if (got_fileindex_entry_has_blob(ie) &&
memcmp(ie->blob_sha1, te->id.sha1,
SHA1_DIGEST_LENGTH) == 0) {
- err = sync_timestamps(ondisk_path, status, ie, &sb);
+ err = sync_timestamps(worktree->root_fd,
+ path, status, ie, &sb);
goto done;
}
}
@@ -1987,17 +1989,17 @@ update_blob(struct got_worktree *worktree,
* Otherwise, a future status walk would treat them as
* unmodified files again.
*/
- err = got_fileindex_entry_update(ie, ondisk_path,
+ err = got_fileindex_entry_update(ie, worktree->root_fd, path,
blob->id.sha1, worktree->base_commit_id->sha1,
update_timestamps);
} else if (status == GOT_STATUS_MODE_CHANGE) {
- err = got_fileindex_entry_update(ie, ondisk_path,
+ err = got_fileindex_entry_update(ie, worktree->root_fd, path,
blob->id.sha1, worktree->base_commit_id->sha1, 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, ondisk_path,
+ err = got_fileindex_entry_update(ie, worktree->root_fd, path,
blob->id.sha1, worktree->base_commit_id->sha1, 0);
if (err)
goto done;
@@ -2020,11 +2022,12 @@ update_blob(struct got_worktree *worktree,
goto done;
if (ie) {
- err = got_fileindex_entry_update(ie, ondisk_path,
- blob->id.sha1, worktree->base_commit_id->sha1, 1);
+ err = got_fileindex_entry_update(ie,
+ worktree->root_fd, path, blob->id.sha1,
+ worktree->base_commit_id->sha1, 1);
} else {
err = create_fileindex_entry(&ie, fileindex,
- worktree->base_commit_id, ondisk_path, path,
+ worktree->base_commit_id, worktree->root_fd, path,
&blob->id);
}
if (err)
@@ -2124,8 +2127,8 @@ delete_blob(struct got_worktree *worktree, struct got_fileindex *fileindex,
* Preserve the working file and change the deleted blob's
* entry into a schedule-add entry.
*/
- err = got_fileindex_entry_update(ie, ondisk_path, NULL, NULL,
- 0);
+ err = got_fileindex_entry_update(ie, worktree->root_fd,
+ ie->path, NULL, NULL, 0);
} else {
err = (*progress_cb)(progress_arg, GOT_STATUS_DELETE, ie->path);
if (err)
@@ -2933,7 +2936,7 @@ merge_file_cb(void *arg, struct got_blob_object *blob1,
goto done;
if (status == GOT_STATUS_DELETE) {
err = got_fileindex_entry_update(ie,
- ondisk_path, blob2->id.sha1,
+ a->worktree->root_fd, path2, blob2->id.sha1,
a->worktree->base_commit_id->sha1, 0);
if (err)
goto done;
@@ -2955,8 +2958,8 @@ merge_file_cb(void *arg, struct got_blob_object *blob1,
err = got_fileindex_entry_alloc(&ie, path2);
if (err)
goto done;
- err = got_fileindex_entry_update(ie, ondisk_path,
- NULL, NULL, 1);
+ err = got_fileindex_entry_update(ie,
+ a->worktree->root_fd, path2, NULL, NULL, 1);
if (err) {
got_fileindex_entry_free(ie);
goto done;
@@ -3775,7 +3778,8 @@ schedule_addition(void *arg, unsigned char status, unsigned char staged_status,
err = got_fileindex_entry_alloc(&ie, relpath);
if (err)
goto done;
- err = got_fileindex_entry_update(ie, ondisk_path, NULL, NULL, 1);
+ err = got_fileindex_entry_update(ie, a->worktree->root_fd,
+ relpath, NULL, NULL, 1);
if (err) {
got_fileindex_entry_free(ie);
goto done;
@@ -4582,7 +4586,8 @@ revert_file(void *arg, unsigned char status, unsigned char staged_status,
if (status == GOT_STATUS_DELETE ||
status == GOT_STATUS_MODE_CHANGE) {
err = got_fileindex_entry_update(ie,
- ondisk_path, blob->id.sha1,
+ a->worktree->root_fd, relpath,
+ blob->id.sha1,
a->worktree->base_commit_id->sha1, 1);
if (err)
goto done;
@@ -5285,18 +5290,26 @@ done:
}
static const struct got_error *
-update_fileindex_after_commit(struct got_pathlist_head *commitable_paths,
- struct got_object_id *new_base_commit_id, struct got_fileindex *fileindex,
- int have_staged_files)
+update_fileindex_after_commit(struct got_worktree *worktree,
+ struct got_pathlist_head *commitable_paths,
+ struct got_object_id *new_base_commit_id,
+ struct got_fileindex *fileindex, int have_staged_files)
{
const struct got_error *err = NULL;
struct got_pathlist_entry *pe;
+ char *relpath = NULL;
TAILQ_FOREACH(pe, commitable_paths, entry) {
struct got_fileindex_entry *ie;
struct got_commitable *ct = pe->data;
ie = got_fileindex_entry_get(fileindex, pe->path, pe->path_len);
+
+ err = got_path_skip_common_ancestor(&relpath,
+ worktree->root_path, ct->ondisk_path);
+ if (err)
+ goto done;
+
if (ie) {
if (ct->status == GOT_STATUS_DELETE ||
ct->staged_status == GOT_STATUS_DELETE) {
@@ -5306,32 +5319,41 @@ update_fileindex_after_commit(struct got_pathlist_head *commitable_paths,
got_fileindex_entry_stage_set(ie,
GOT_FILEIDX_STAGE_NONE);
got_fileindex_entry_staged_filetype_set(ie, 0);
+
err = got_fileindex_entry_update(ie,
- ct->ondisk_path, ct->staged_blob_id->sha1,
+ worktree->root_fd, relpath,
+ ct->staged_blob_id->sha1,
new_base_commit_id->sha1,
!have_staged_files);
} else
err = got_fileindex_entry_update(ie,
- ct->ondisk_path, ct->blob_id->sha1,
+ worktree->root_fd, relpath,
+ ct->blob_id->sha1,
new_base_commit_id->sha1,
!have_staged_files);
} else {
err = got_fileindex_entry_alloc(&ie, pe->path);
if (err)
- break;
- err = got_fileindex_entry_update(ie, ct->ondisk_path,
- ct->blob_id->sha1, new_base_commit_id->sha1, 1);
+ goto done;
+ err = got_fileindex_entry_update(ie,
+ worktree->root_fd, relpath, ct->blob_id->sha1,
+ new_base_commit_id->sha1, 1);
if (err) {
got_fileindex_entry_free(ie);
- break;
+ goto done;
}
err = got_fileindex_entry_add(fileindex, ie);
if (err) {
got_fileindex_entry_free(ie);
- break;
+ goto done;
}
}
+ free(relpath);
+ relpath = NULL;
}
+done:
+ if (relpath)
+ free(relpath);
return err;
}
@@ -5662,8 +5684,8 @@ got_worktree_commit(struct got_object_id **new_commit_id,
if (err)
goto done;
- err = update_fileindex_after_commit(&commitable_paths, *new_commit_id,
- fileindex, have_staged_files);
+ err = update_fileindex_after_commit(worktree, &commitable_paths,
+ *new_commit_id, fileindex, have_staged_files);
sync_err = sync_fileindex(fileindex, fileindex_path);
if (sync_err && err == NULL)
err = sync_err;
@@ -6248,8 +6270,8 @@ rebase_commit(struct got_object_id **new_commit_id,
if (err)
goto done;
- err = update_fileindex_after_commit(&commitable_paths, *new_commit_id,
- fileindex, 0);
+ err = update_fileindex_after_commit(worktree, &commitable_paths,
+ *new_commit_id, fileindex, 0);
sync_err = sync_fileindex(fileindex, fileindex_path);
if (sync_err && err == NULL)
err = sync_err;
change got_worktree_init, open_worktree to use fds