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