Commit Diff


commit - c513d110e1729047bf5918452e5b5a75c00a8e4f
commit + 247140b28268236ea5c77457b01d6dec936ffb51
blob - 266c84543cc2ab3f60caad3f5da7e8ead28697fb
blob + 3c5386e1a28c207eb5c07d3cbbe2ef72e0e7e38e
--- include/got_error.h
+++ include/got_error.h
@@ -73,6 +73,7 @@
 #define GOT_ERR_BAD_REF_DATA	57
 #define GOT_ERR_TREE_DUP_ENTRY	58
 #define GOT_ERR_DIR_DUP_ENTRY	59
+#define GOT_ERR_NOT_WORKTREE	60
 
 static const struct got_error {
 	int code;
@@ -136,6 +137,7 @@ static const struct got_error {
 	{ GOT_ERR_BAD_REF_DATA,	"could not parse reference data" },
 	{ GOT_ERR_TREE_DUP_ENTRY,"duplicate entry in tree object" },
 	{ GOT_ERR_DIR_DUP_ENTRY,"duplicate entry in directory" },
+	{ GOT_ERR_NOT_WORKTREE, "no got work tree found" },
 };
 
 /*
blob - 879b57cd0208cf79072ecdeb708d1ac92b8acef4
blob + eb06c1c83638358bcdb853f29755a94983b589d3
--- include/got_worktree.h
+++ include/got_worktree.h
@@ -39,7 +39,7 @@ const struct got_error *got_worktree_init(const char *
     const char *, struct got_repository *);
 
 /*
- * Attempt to open a worktree at the specified path.
+ * Attempt to open a worktree at or above the specified path.
  * The caller must dispose of it with got_worktree_close().
  */
 const struct got_error *got_worktree_open(struct got_worktree **, const char *);
blob - c5cad3cd070acc1521feb0f2439c10e58fa16aee
blob + 66bb12d1ff6c5832e73f92e7f73928f0892a631a
--- lib/worktree.c
+++ lib/worktree.c
@@ -283,8 +283,8 @@ done:
 	return err;
 }
 
-const struct got_error *
-got_worktree_open(struct got_worktree **worktree, const char *path)
+static const struct got_error *
+open_worktree(struct got_worktree **worktree, const char *path)
 {
 	const struct got_error *err = NULL;
 	char *path_got;
@@ -390,7 +390,24 @@ done:
 
 	return err;
 }
+
+const struct got_error *
+got_worktree_open(struct got_worktree **worktree, const char *path)
+{
+	const struct got_error *err = NULL;
 
+	do {
+		err = open_worktree(worktree, path);
+		if (err && (err->code != GOT_ERR_ERRNO && errno != ENOENT))
+			return err;
+		if (*worktree)
+			return NULL;
+		path = dirname(path);
+	} while (path && !(path[0] == '.' && path[1] == '\0'));
+
+	return got_error(GOT_ERR_NOT_WORKTREE);
+}
+
 void
 got_worktree_close(struct got_worktree *worktree)
 {