Commit 577ec78f7e6f997c163d0aaa36ca04279d4196f7

Stefan Sperling 2018-03-11T01:15:39

store a path prefix in the worktree; will be used for subtree checkout

diff --git a/include/got_worktree.h b/include/got_worktree.h
index 0925d84..82a6215 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -17,7 +17,7 @@
 struct got_worktree;
 
 const struct got_error *got_worktree_init(const char *, struct got_reference *,
-    struct got_repository *);
+    const char *, struct got_repository *);
 const struct got_error *got_worktree_open(struct got_worktree **, const char *);
 void got_worktree_close(struct got_worktree *);
 char *got_worktree_get_repo_path(struct got_worktree *);
diff --git a/lib/got_worktree_priv.h b/lib/got_worktree_priv.h
index f49af44..39417fc 100644
--- a/lib/got_worktree_priv.h
+++ b/lib/got_worktree_priv.h
@@ -17,11 +17,13 @@
 struct got_worktree {
 	char *path_worktree_root;
 	char *path_repo;
+	char *path_prefix;
 };
 
-#define GOT_WORKTREE_GOT_DIR	".got"
-#define GOT_WORKTREE_FILE_INDEX	"fileindex"
-#define GOT_WORKTREE_REPOSITORY	"repository"
-#define GOT_WORKTREE_FORMAT	"format"
+#define GOT_WORKTREE_GOT_DIR		".got"
+#define GOT_WORKTREE_FILE_INDEX		"fileindex"
+#define GOT_WORKTREE_REPOSITORY		"repository"
+#define GOT_WORKTREE_PATH_PREFIX	"path-prefix"
+#define GOT_WORKTREE_FORMAT		"format"
 
 #define GOT_WORKTREE_FORMAT_VERSION	1
diff --git a/lib/worktree.c b/lib/worktree.c
index cf72425..0d7bf54 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -78,7 +78,7 @@ done:
 
 const struct got_error *
 got_worktree_init(const char *path, struct got_reference *head_ref,
-    struct got_repository *repo)
+    const char *prefix, struct got_repository *repo)
 {
 	const struct got_error *err = NULL;
 	char *abspath = NULL;
@@ -88,6 +88,9 @@ got_worktree_init(const char *path, struct got_reference *head_ref,
 	char *path_repos = NULL;
 	char *formatstr = NULL;
 
+	if (!got_path_is_absolute(prefix))
+		return got_error(GOT_ERR_BAD_PATH);
+
 	if (got_path_is_absolute(path)) {
 		abspath = strdup(path);
 		if (abspath == NULL)
@@ -144,6 +147,11 @@ got_worktree_init(const char *path, struct got_reference *head_ref,
 	if (err)
 		goto done;
 
+	/* Store in-repository path prefix. */
+	err = create_meta_file(gotpath, GOT_WORKTREE_PATH_PREFIX, prefix);
+	if (err)
+		goto done;
+
 	/* Stamp work tree with format file. */
 	if (asprintf(&formatstr, "%d", GOT_WORKTREE_FORMAT_VERSION) == -1) {
 		err = got_error(GOT_ERR_NO_MEM);
diff --git a/regress/worktree/worktree_test.c b/regress/worktree/worktree_test.c
index cad1391..ec99a28 100644
--- a/regress/worktree/worktree_test.c
+++ b/regress/worktree/worktree_test.c
@@ -83,6 +83,7 @@ remove_workdir(const char *worktree_path)
 	remove_meta_file(worktree_path, GOT_REF_HEAD);
 	remove_meta_file(worktree_path, GOT_WORKTREE_FILE_INDEX);
 	remove_meta_file(worktree_path, GOT_WORKTREE_REPOSITORY);
+	remove_meta_file(worktree_path, GOT_WORKTREE_PATH_PREFIX);
 	remove_meta_file(worktree_path, GOT_WORKTREE_FORMAT);
 	remove_got_dir(worktree_path);
 	rmdir(worktree_path);
@@ -125,7 +126,7 @@ worktree_init(const char *repo_path)
 	if (mkdtemp(worktree_path) == NULL)
 		goto done;
 
-	err = got_worktree_init(worktree_path, head_ref, repo);
+	err = got_worktree_init(worktree_path, head_ref, "/", repo);
 	if (err != NULL)
 		goto done;
 
@@ -136,6 +137,8 @@ worktree_init(const char *repo_path)
 		goto done;
 	if (!check_meta_file_exists(worktree_path, GOT_WORKTREE_REPOSITORY))
 		goto done;
+	if (!check_meta_file_exists(worktree_path, GOT_WORKTREE_PATH_PREFIX))
+		goto done;
 	if (!check_meta_file_exists(worktree_path, GOT_WORKTREE_FORMAT))
 		goto done;
 	ok = 1;
@@ -205,7 +208,7 @@ worktree_init_exists(const char *repo_path)
 
 	if (!obstruct_meta_file(&path, worktree_path, GOT_REF_HEAD))
 		goto done;
-	err = got_worktree_init(worktree_path, head_ref, repo);
+	err = got_worktree_init(worktree_path, head_ref, "/", repo);
 	if (err != NULL && err->code == GOT_ERR_ERRNO && errno == EEXIST)
 		ok++;
 	unlink(path);
@@ -213,7 +216,7 @@ worktree_init_exists(const char *repo_path)
 
 	if (!obstruct_meta_file(&path, worktree_path, GOT_WORKTREE_FILE_INDEX))
 		goto done;
-	err = got_worktree_init(worktree_path, head_ref, repo);
+	err = got_worktree_init(worktree_path, head_ref, "/", repo);
 	if (err != NULL && err->code == GOT_ERR_ERRNO && errno == EEXIST)
 		ok++;
 	unlink(path);
@@ -221,7 +224,15 @@ worktree_init_exists(const char *repo_path)
 
 	if (!obstruct_meta_file(&path, worktree_path, GOT_WORKTREE_REPOSITORY))
 		goto done;
-	err = got_worktree_init(worktree_path, head_ref, repo);
+	err = got_worktree_init(worktree_path, head_ref, "/", repo);
+	if (err != NULL && err->code == GOT_ERR_ERRNO && errno == EEXIST)
+		ok++;
+	unlink(path);
+	free(path);
+
+	if (!obstruct_meta_file(&path, worktree_path, GOT_WORKTREE_PATH_PREFIX))
+		goto done;
+	err = got_worktree_init(worktree_path, head_ref, "/", repo);
 	if (err != NULL && err->code == GOT_ERR_ERRNO && errno == EEXIST)
 		ok++;
 	unlink(path);
@@ -229,7 +240,7 @@ worktree_init_exists(const char *repo_path)
 
 	if (!obstruct_meta_file(&path, worktree_path, GOT_WORKTREE_FORMAT))
 		goto done;
-	err = got_worktree_init(worktree_path, head_ref, repo);
+	err = got_worktree_init(worktree_path, head_ref, "/", repo);
 	if (err != NULL && err->code == GOT_ERR_ERRNO && errno == EEXIST)
 		ok++;
 	unlink(path);
@@ -241,9 +252,9 @@ done:
 	if (repo)
 		got_repo_close(repo);
 	free(gotpath);
-	if (ok == 4)
+	if (ok == 5)
 		remove_workdir(worktree_path);
-	return (ok == 4);
+	return (ok == 5);
 }
 
 #define RUN_TEST(expr, name) \