commit 0bb8a95e464401b5b664287c73785c6d9d7a5a59 from: Stefan Sperling date: Mon Mar 12 21:00:08 2018 UTC add support for checking out a subtree commit - 291c6f034645a25f5038a952a22e7062a3fcabfd commit + 0bb8a95e464401b5b664287c73785c6d9d7a5a59 blob - 1a35ccf9fdfa3be6a333382ec6f7bc5395dd9f1d blob + c281528136eb3890d4b7799d3a247a888bc36a31 --- got/got.1 +++ 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 blob - 68caca6cbf42002eace6fbd8a3595680de6d5e2d blob + be95ec2118d5261062ef994e8f8d22a4a399606b --- got/got.c +++ 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 __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); } blob - 0df2fb5583b53e04fc7439ed022b3d3cf8b44531 blob + a1bff6f12c13bb8798b16dbca3d47ebeeaefdb6b --- lib/worktree.c +++ lib/worktree.c @@ -158,9 +158,12 @@ got_worktree_init(const char *path, struct got_referen 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_referen 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; }