add support for checking out a subtree
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
diff --git a/got/got.1 b/got/got.1
index 1a35ccf..c281528 100644
--- a/got/got.1
+++ b/got/got.1
@@ -20,7 +20,7 @@
.Nm got
.Nd simple version control system
.Sh SYNOPSIS
-.Nm
+.Nm
.Ar command
.Op Fl h
.Op Ar arg ...
@@ -39,9 +39,11 @@ Display usage information.
.El
.Pp
The commands are as follows:
-.Bl -tag -width Ds
-.It Cm status
-Show current status of files.
+.Bl -tag -width checkout
+.It Cm checkout
+Copy files from a repository into a new work tree.
+.\".It Cm status
+.\"Show current status of files.
.It Cm log
Display history of the repository.
.El
diff --git a/got/got.c b/got/got.c
index 68caca6..be95ec2 100644
--- a/got/got.c
+++ b/got/got.c
@@ -53,7 +53,7 @@ const struct got_error* cmd_status(int, char *[]);
struct cmd got_commands[] = {
{ "checkout", cmd_checkout, usage_checkout,
- "check out a work tree from a repository" },
+ "check out a new work tree from a repository" },
{ "log", cmd_log, usage_log,
"show repository history" },
#ifdef notyet
@@ -130,8 +130,8 @@ usage(void)
__dead void
usage_checkout(void)
{
- fprintf(stderr, "usage: %s checkout REPO_PATH [WORKTREE_PATH]\n",
- getprogname());
+ fprintf(stderr, "usage: %s checkout [-p prefix] repository-path "
+ "[worktree-path]\n", getprogname());
exit(1);
}
@@ -155,13 +155,30 @@ cmd_checkout(int argc, char *argv[])
struct got_worktree *worktree = NULL;
char *repo_path = NULL;
char *worktree_path = NULL;
+ const char *path_prefix = "";
+ int ch;
+
+ optind = 0;
+ while ((ch = getopt(argc, argv, "p:")) != -1) {
+ switch (ch) {
+ case 'p':
+ path_prefix = optarg;
+ break;
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
if (pledge("stdio rpath wpath cpath flock", NULL) == -1)
err(1, "pledge");
- if (argc == 2) {
+ if (argc == 1) {
char *cwd, *base, *dotgit;
- repo_path = argv[1];
+ repo_path = argv[0];
cwd = getcwd(NULL, 0);
if (cwd == NULL)
err(1, "getcwd");
@@ -176,9 +193,9 @@ cmd_checkout(int argc, char *argv[])
return got_error(GOT_ERR_NO_MEM);
}
free(cwd);
- } else if (argc == 3) {
- repo_path = argv[1];
- worktree_path = strdup(argv[2]);
+ } else if (argc == 2) {
+ repo_path = argv[0];
+ worktree_path = strdup(argv[1]);
if (worktree_path == NULL)
return got_error(GOT_ERR_NO_MEM);
} else
@@ -191,7 +208,7 @@ cmd_checkout(int argc, char *argv[])
if (error != NULL)
goto done;
- error = got_worktree_init(worktree_path, head_ref, "/", repo);
+ error = got_worktree_init(worktree_path, head_ref, path_prefix, repo);
if (error != NULL)
goto done;
@@ -267,7 +284,7 @@ print_commit_object(struct got_object *obj, struct got_object_id *id,
__dead void
usage_log(void)
{
- fprintf(stderr, "usage: %s log [REPO_PATH]\n", getprogname());
+ fprintf(stderr, "usage: %s log [repository-path]\n", getprogname());
exit(1);
}
diff --git a/lib/worktree.c b/lib/worktree.c
index 0df2fb5..a1bff6f 100644
--- a/lib/worktree.c
+++ b/lib/worktree.c
@@ -158,9 +158,12 @@ got_worktree_init(const char *path, struct got_reference *head_ref,
char *refstr = NULL;
char *repo_path = NULL;
char *formatstr = NULL;
+ char *absprefix = NULL;
- if (!got_path_is_absolute(prefix))
- return got_error(GOT_ERR_BAD_PATH);
+ if (!got_path_is_absolute(prefix)) {
+ if (asprintf(&absprefix, "/%s", prefix) == -1)
+ return got_error(GOT_ERR_NO_MEM);
+ }
/* Create top-level directory (may already exist). */
if (mkdir(path, GOT_DEFAULT_DIR_MODE) == -1 && errno != EEXIST) {
@@ -209,7 +212,8 @@ got_worktree_init(const char *path, struct got_reference *head_ref,
goto done;
/* Store in-repository path prefix. */
- err = create_meta_file(path_got, GOT_WORKTREE_PATH_PREFIX, prefix);
+ err = create_meta_file(path_got, GOT_WORKTREE_PATH_PREFIX,
+ absprefix ? absprefix : prefix);
if (err)
goto done;
@@ -227,6 +231,7 @@ done:
free(formatstr);
free(refstr);
free(repo_path);
+ free(absprefix);
return err;
}