got: support adding multiple files at a time make adding files already in the file-index not a fatal error
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
diff --git a/TODO b/TODO
index 0b1f820..cc9cceb 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,6 @@
lib:
- handle checkout of trees which contain submodules by identifying and
ignoring such tree entries; requires a .ini config parser (from isakmpd?)
-- allow adding multiple paths at once for 'got add'
- allow removing multiple paths at once for 'got rm'
- recursive addition: got add -R
- recursive removal: got rm -R
diff --git a/got/got.c b/got/got.c
index 41b8e41..679e74f 100644
--- a/got/got.c
+++ b/got/got.c
@@ -1897,7 +1897,7 @@ cmd_add(int argc, char *argv[])
struct got_repository *repo = NULL;
struct got_worktree *worktree = NULL;
char *cwd = NULL, *path = NULL, *relpath = NULL;
- int ch;
+ int ch, x;
while ((ch = getopt(argc, argv, "")) != -1) {
switch (ch) {
@@ -1910,21 +1910,24 @@ cmd_add(int argc, char *argv[])
argc -= optind;
argv += optind;
- if (argc != 1)
+ if (argc < 1)
usage_add();
- path = realpath(argv[0], NULL);
- if (path == NULL) {
- error = got_error_prefix_errno2("realpath", argv[0]);
- goto done;
+ /* make sure each file exists before doing anything halfway */
+ for (x = 0; x < argc; x++) {
+ path = realpath(argv[x], NULL);
+ if (path == NULL) {
+ error = got_error_prefix_errno2("realpath", argv[x]);
+ goto done;
+ }
}
- got_path_strip_trailing_slashes(path);
cwd = getcwd(NULL, 0);
if (cwd == NULL) {
error = got_error_prefix_errno("getcwd");
goto done;
}
+
error = got_worktree_open(&worktree, cwd);
if (error)
goto done;
@@ -1938,10 +1941,24 @@ cmd_add(int argc, char *argv[])
if (error)
goto done;
- error = got_worktree_schedule_add(worktree, path, print_status, NULL,
- repo);
- if (error)
- goto done;
+ for (x = 0; x < argc; x++) {
+ path = realpath(argv[x], NULL);
+ if (path == NULL) {
+ error = got_error_prefix_errno2("realpath", argv[x]);
+ goto done;
+ }
+
+ got_path_strip_trailing_slashes(path);
+
+ error = got_worktree_schedule_add(worktree, path, print_status,
+ NULL, repo);
+ if (errno == EEXIST) {
+ error = NULL;
+ continue;
+ }
+ else if (error)
+ goto done;
+ }
done:
if (repo)
got_repo_close(repo);
diff --git a/regress/cmdline/add.sh b/regress/cmdline/add.sh
index 07907d1..eba7073 100755
--- a/regress/cmdline/add.sh
+++ b/regress/cmdline/add.sh
@@ -52,20 +52,39 @@ function test_double_add {
echo "new file" > $testroot/wt/foo
(cd $testroot/wt && got add foo > /dev/null)
- echo "got: File exists" > $testroot/stderr.expected
- (cd $testroot/wt && got add foo 2> $testroot/stderr)
+ (cd $testroot/wt && got add foo)
ret="$?"
- if [ "$ret" == "0" ]; then
- echo "got add command succeeded unexpectedly" >&2
+ if [ "$ret" != "0" ]; then
+ echo "got add failed unexpectedly" >&2
test_done "$testroot" 1
return 1
fi
- cmp $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+}
+
+function test_add_multiple {
+ local testroot=`test_init multiple_add`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
ret="$?"
if [ "$ret" != "0" ]; then
- diff -u $testroot/stderr.expected $testroot/stderr
+ test_done "$testroot" "$ret"
+ return 1
fi
+
+ echo "new file" > $testroot/wt/foo
+ echo "new file" > $testroot/wt/bar
+ echo "new file" > $testroot/wt/baz
+ (cd $testroot/wt && got add foo bar baz)
+
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ echo "got add failed unexpectedly" >&2
+ test_done "$testroot" 1
+ return 1
+ fi
+
test_done "$testroot" "$ret"
}