Commit Diff


commit - 1e71573ed6f406d76e81bd84089a93e76274d424
commit + 4200573374f974a69490f25c80a01c2e53968db9
blob - 969b659b69337f267299b51146c428e32f004a3a
blob + c45b9460c5134f96d0e145c25ee332de6de5208f
--- lib/worktree.c
+++ lib/worktree.c
@@ -4858,25 +4858,21 @@ done:
 }
 
 static const struct got_error *
-stage_path(const char *path, size_t path_len, const char *path_content,
-    struct got_worktree *worktree, struct got_fileindex *fileindex,
-    struct got_repository *repo,
+stage_path(const char *relpath, const char *ondisk_path,
+    const char *path_content, struct got_worktree *worktree,
+    struct got_fileindex *fileindex, struct got_repository *repo,
     got_worktree_status_cb status_cb, void *status_arg)
 {
 	const struct got_error *err = NULL;
-	char *ondisk_path;
 	struct got_fileindex_entry *ie;
 	unsigned char status;
 	struct stat sb;
 	struct got_object_id *blob_id = NULL;
 	uint32_t stage;
 
-	if (asprintf(&ondisk_path, "%s/%s", worktree->root_path, path) == -1)
-		return got_error_from_errno("asprintf");
-
-	ie = got_fileindex_entry_get(fileindex, path, path_len);
+	ie = got_fileindex_entry_get(fileindex, relpath, strlen(relpath));
 	if (ie == NULL) {
-		err = got_error_path(path, GOT_ERR_FILE_STATUS);
+		err = got_error_path(relpath, GOT_ERR_FILE_STATUS);
 		goto done;
 	}
 
@@ -4902,17 +4898,16 @@ stage_path(const char *path, size_t path_len, const ch
 		stage = GOT_FILEIDX_STAGE_DELETE;
 		break;
 	default:
-		err = got_error_path(path, GOT_ERR_FILE_STATUS);
+		err = got_error_path(relpath, GOT_ERR_FILE_STATUS);
 		goto done;
 	}
 
 	got_fileindex_entry_stage_set(ie, stage);
 
 	/* XXX TODO pass 'staged' status separately */
-	err = (*status_cb)(status_arg, status, path, blob_id, NULL);
+	err = (*status_cb)(status_arg, status, relpath, blob_id, NULL);
 done:
 	free(blob_id);
-	free(ondisk_path);
 	return err;
 }
 
@@ -4936,10 +4931,17 @@ got_worktree_stage(struct got_worktree *worktree,
 		goto done;
 
 	TAILQ_FOREACH(pe, paths, entry) {
-		err = stage_path(pe->path, pe->path_len, (const char *)pe->data,
-		    worktree, fileindex, repo, status_cb, status_arg);
+		char *relpath;
+		err = got_path_skip_common_ancestor(&relpath,
+		    got_worktree_get_root_path(worktree), pe->path);
 		if (err)
 			break;
+		err = stage_path(relpath, pe->path,
+		    (const char *)pe->data, worktree, fileindex, repo,
+		    status_cb, status_arg);
+		free(relpath);
+		if (err)
+			break;
 	}
 
 	sync_err = sync_fileindex(fileindex, fileindex_path);