"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Yang Zhong <yzhong@freebsdfoundation.org>
Subject:
Re: change got_worktree_init, open_worktree to use fds
To:
Yang Zhong <yzhong@freebsdfoundation.org>, gameoftrees@openbsd.org
Date:
Wed, 9 Dec 2020 09:00:00 -0800

Download raw body.

Thread
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;