Commit e5dc71984941ad561bd7f953c0cbb88bc5aad0b0

Stefan Sperling 2018-12-29T16:07:41

fix 'same path prefix' check during checkout

diff --git a/got/got.c b/got/got.c
index 00586f4..6c95c16 100644
--- a/got/got.c
+++ b/got/got.c
@@ -206,7 +206,7 @@ cmd_checkout(int argc, char *argv[])
 	char *repo_path = NULL;
 	char *worktree_path = NULL;
 	const char *path_prefix = "";
-	int ch;
+	int ch, same_path_prefix;
 
 	while ((ch = getopt(argc, argv, "p:")) != -1) {
 		switch (ch) {
@@ -283,7 +283,11 @@ cmd_checkout(int argc, char *argv[])
 	if (error != NULL)
 		goto done;
 
-	if (strcmp(path_prefix, got_worktree_get_path_prefix(worktree)) != 0) {
+	error = got_worktree_match_path_prefix(&same_path_prefix, worktree,
+	    path_prefix);
+	if (error != NULL)
+		goto done;
+	if (!same_path_prefix) {
 		error = got_error(GOT_ERR_PATH_PREFIX);
 		goto done;
 	}
diff --git a/include/got_worktree.h b/include/got_worktree.h
index 7ffb70a..49f1b19 100644
--- a/include/got_worktree.h
+++ b/include/got_worktree.h
@@ -51,6 +51,12 @@ const char *got_worktree_get_repo_path(struct got_worktree *);
 const char *got_worktree_get_path_prefix(struct got_worktree *);
 
 /*
+ * Check if a user-provided path prefix matches that of the worktree.
+ */
+const struct got_error *got_worktree_match_path_prefix(int *,
+    struct got_worktree *, const char *);
+
+/*
  * Get the name of a work tree's HEAD reference.
  * The caller must dispose of it with free(3).
  */
diff --git a/lib/worktree.c b/lib/worktree.c
index 461f6ec..174d53d 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -382,6 +382,22 @@ got_worktree_get_path_prefix(struct got_worktree *worktree)
 	return worktree->path_prefix;
 }
 
+const struct got_error *
+got_worktree_match_path_prefix(int *match, struct got_worktree *worktree,
+    const char *path_prefix)
+{
+	char *absprefix = NULL;
+
+	if (!got_path_is_absolute(path_prefix)) {
+		if (asprintf(&absprefix, "/%s", path_prefix) == -1)
+			return got_error_from_errno();
+	}
+	*match = (strcmp(absprefix ? absprefix : path_prefix,
+	    worktree->path_prefix) == 0);
+	free(absprefix);
+	return NULL;
+}
+
 char *
 got_worktree_get_head_ref_name(struct got_worktree *worktree)
 {