commit - c5b7833452086e7e8e0866b16a5932430cfe9a79
commit + bb51a5b4af467a42569e19cbeeeeccbb44d946f0
blob - 4099167c32d0a15e7689e9a2b02ba26dcf17d90f
blob + c37e7cad2084f68edcbdff9b1085facc2f646043
--- got/got.1
+++ got/got.1
.It Cm im
Short alias for
.Cm import .
-.It Cm checkout Oo Fl b Ar branch Oc Oo Fl c Ar commit Oc Oo Fl p Ar path-prefix Oc Ar repository-path Op Ar work-tree-path
+.It Cm checkout Oo Fl E Oc Oo Fl b Ar branch Oc Oo Fl c Ar commit OcOo Fl p Ar path-prefix Oc Ar repository-path Op Ar work-tree-path
Copy files from a repository into a new work tree.
+Show the status of each affected file, using the following status codes:
+.Bl -column YXZ description
+.It A Ta new file was added
+.It E Ta file already exists in work tree's meta-data
+.El
+.Pp
If the
.Ar work tree path
is not specified, either use the last component of
.Cm got checkout
are as follows:
.Bl -tag -width Ds
+.It Fl E
+Proceed with the checkout operation even if the directory at
+.Ar work-tree-path
+is not empty.
+Existing files will be left intact.
.It Fl b Ar branch
Check out files from a commit on the specified
.Ar branch .
blob - 5490ed3772d0e6daa9cd31a902f0f3129bb779f5
blob + 9949c5488d778cc0038d5ad03dc24986ac5f059b
--- got/got.c
+++ got/got.c
__dead static void
usage_checkout(void)
{
- fprintf(stderr, "usage: %s checkout [-b branch] [-c commit] "
+ fprintf(stderr, "usage: %s checkout [-E] [-b branch] [-c commit] "
"[-p prefix] repository-path [worktree-path]\n", getprogname());
exit(1);
}
const char *path_prefix = "";
const char *branch_name = GOT_REF_HEAD;
char *commit_id_str = NULL;
- int ch, same_path_prefix;
+ int ch, same_path_prefix, allow_nonempty = 0;
struct got_pathlist_head paths;
struct got_checkout_progress_arg cpa;
TAILQ_INIT(&paths);
- while ((ch = getopt(argc, argv, "b:c:p:")) != -1) {
+ while ((ch = getopt(argc, argv, "b:c:Ep:")) != -1) {
switch (ch) {
case 'b':
branch_name = optarg;
commit_id_str = strdup(optarg);
if (commit_id_str == NULL)
return got_error_from_errno("strdup");
+ break;
+ case 'E':
+ allow_nonempty = 1;
break;
case 'p':
path_prefix = optarg;
if (!(error->code == GOT_ERR_ERRNO && errno == EISDIR) &&
!(error->code == GOT_ERR_ERRNO && errno == EEXIST))
goto done;
- if (!got_path_dir_is_empty(worktree_path)) {
+ if (!allow_nonempty &&
+ !got_path_dir_is_empty(worktree_path)) {
error = got_error_path(worktree_path,
GOT_ERR_DIR_NOT_EMPTY);
goto done;
blob - 756faf8e9b273a128bad4efb6aedef83e1d5426c
blob + 57b823a4f04403e0dfd1d1e79cc8fe80f6dbc79c
--- include/got_path.h
+++ include/got_path.h
/* Utilities for dealing with filesystem paths. */
-#define GOT_DEFAULT_FILE_MODE (S_IRUSR|S_IWUSR | S_IRGRP | S_IROTH)
-#define GOT_DEFAULT_DIR_MODE (S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH)
+#define GOT_DEFAULT_FILE_MODE (S_IFREG | \
+ S_IRUSR|S_IWUSR | S_IRGRP | S_IROTH)
+#define GOT_DEFAULT_DIR_MODE (S_IFDIR | \
+ S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH)
/* Determine whether a path is an absolute path. */
int got_path_is_absolute(const char *);
blob - fcbeadbc09c83ae8ca419b0dd909c62dc50d4d99
blob + 3027c28911360bf6c9f6f2dcdc85e417cf77dc37
--- lib/worktree.c
+++ lib/worktree.c
static const struct got_error *
install_blob(struct got_worktree *worktree, const char *ondisk_path,
- const char *path, uint16_t te_mode, uint16_t st_mode,
+ const char *path, mode_t te_mode, mode_t st_mode,
struct got_blob_object *blob, int restoring_missing_file,
int reverting_versioned_file, struct got_repository *repo,
got_worktree_checkout_cb progress_cb, void *progress_arg)
blob - 34747be3c1c93a3c475b7e42583dca7f4ae844a4
blob + 6859b9bab3ac0176db628a98074b484d5b80364b
--- regress/cmdline/checkout.sh
+++ regress/cmdline/checkout.sh
chmod -R u+w $testroot/repo # make repo cleanup work
test_done "$testroot" "$ret"
}
+
+function test_checkout_into_nonempty_dir {
+ local testroot=`test_init checkout_into_nonempty_dir`
+
+ mkdir -p $testroot/wt
+ make_test_tree $testroot/wt
+
+ got checkout $testroot/repo $testroot/wt > $testroot/stdout \
+ 2> $testroot/stderr
+ ret="$?"
+ if [ "$ret" == "0" ]; then
+ echo "checkout succeeded unexpectedly" >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ echo -n > $testroot/stdout.expected
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "got: $testroot/wt: directory exists and is not empty" \
+ > $testroot/stderr.expected
+ cmp -s $testroot/stderr.expected $testroot/stderr
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "U $testroot/wt/alpha" > $testroot/stdout.expected
+ echo "U $testroot/wt/beta" >> $testroot/stdout.expected
+ echo "U $testroot/wt/epsilon/zeta" >> $testroot/stdout.expected
+ echo "U $testroot/wt/gamma/delta" >> $testroot/stdout.expected
+ echo "Now shut up and hack" >> $testroot/stdout.expected
+ got checkout -E $testroot/repo $testroot/wt > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "E $testroot/wt/alpha" > $testroot/stdout.expected
+ echo "E $testroot/wt/beta" >> $testroot/stdout.expected
+ echo "E $testroot/wt/epsilon/zeta" >> $testroot/stdout.expected
+ echo "E $testroot/wt/gamma/delta" >> $testroot/stdout.expected
+ echo "Now shut up and hack" >> $testroot/stdout.expected
+
+ got checkout -E $testroot/repo $testroot/wt > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "alpha" > $testroot/content.expected
+ echo "beta" >> $testroot/content.expected
+ echo "zeta" >> $testroot/content.expected
+ echo "delta" >> $testroot/content.expected
+ cat $testroot/wt/alpha $testroot/wt/beta $testroot/wt/epsilon/zeta \
+ $testroot/wt/gamma/delta > $testroot/content
+
+ cmp -s $testroot/content.expected $testroot/content
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/content.expected $testroot/content
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "modified alpha" > $testroot/wt/alpha
+
+ echo "E $testroot/wt/alpha" > $testroot/stdout.expected
+ echo "E $testroot/wt/beta" >> $testroot/stdout.expected
+ echo "E $testroot/wt/epsilon/zeta" >> $testroot/stdout.expected
+ echo "E $testroot/wt/gamma/delta" >> $testroot/stdout.expected
+ echo "Now shut up and hack" >> $testroot/stdout.expected
+
+ got checkout -E $testroot/repo $testroot/wt > $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "modified alpha" > $testroot/content.expected
+ echo "beta" >> $testroot/content.expected
+ echo "zeta" >> $testroot/content.expected
+ echo "delta" >> $testroot/content.expected
+ cat $testroot/wt/alpha $testroot/wt/beta $testroot/wt/epsilon/zeta \
+ $testroot/wt/gamma/delta > $testroot/content
+
+ cmp -s $testroot/content.expected $testroot/content
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/content.expected $testroot/content
+ test_done "$testroot" "$ret"
+ return
+ fi
+
+ echo 'M alpha' > $testroot/stdout.expected
+ (cd $testroot/wt && got status > $testroot/stdout)
+
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
run_test test_checkout_basic
run_test test_checkout_dir_exists
run_test test_checkout_dir_not_empty
run_test test_checkout_tag
run_test test_checkout_ignores_submodules
run_test test_checkout_read_only
+run_test test_checkout_into_nonempty_dir