add: error appropriately on repository with no commits
authorKyle Meyer <kyle@kyleam.com>
Tue, 9 Apr 2019 23:07:37 +0000 (19:07 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 10 Apr 2019 03:52:50 +0000 (12:52 +0900)
The previous commit made 'git add' abort when given a repository that
doesn't have a commit checked out. However, the output upon failure
isn't appropriate:

% git add repo
warning: adding embedded git repository: repo
hint: You've added another git repository inside your current repository.
hint: [...]
error: unable to index file 'repo/'
fatal: adding files failed

The hint doesn't apply in this case, and the error message doesn't
tell the user why 'repo' couldn't be added to the index.

Provide better output by teaching add_to_index() to error when given a
git directory where HEAD can't be resolved. To avoid the embedded
repository warning and hint, call check_embedded_repo() only after
add_file_to_index() succeeds because, in general, its output doesn't
make sense if adding to the index fails.

Signed-off-by: Kyle Meyer <kyle@kyleam.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/add.c
read-cache.c
t/t3700-add.sh
index db2dfa43502d0059219189f01731e143982345ab..dd18e5c9b67038307401e8d33970d5c424c03cb7 100644 (file)
@@ -374,11 +374,12 @@ static int add_files(struct dir_struct *dir, int flags)
        }
 
        for (i = 0; i < dir->nr; i++) {
-               check_embedded_repo(dir->entries[i]->name);
                if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
                        if (!ignore_add_errors)
                                die(_("adding files failed"));
                        exit_status = 1;
+               } else {
+                       check_embedded_repo(dir->entries[i]->name);
                }
        }
        return exit_status;
index 0e0c93edc9be5a7af5de1097eafe9d860e7d183e..5511a2b14c8ecf1a4bb7464ccc3ff9ddc0a03f94 100644 (file)
@@ -702,6 +702,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
        int add_option = (ADD_CACHE_OK_TO_ADD|ADD_CACHE_OK_TO_REPLACE|
                          (intent_only ? ADD_CACHE_NEW_ONLY : 0));
        int hash_flags = HASH_WRITE_OBJECT;
+       struct object_id oid;
 
        if (flags & ADD_CACHE_RENORMALIZE)
                hash_flags |= HASH_RENORMALIZE;
@@ -711,6 +712,8 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
 
        namelen = strlen(path);
        if (S_ISDIR(st_mode)) {
+               if (resolve_gitlink_ref(path, "HEAD", &oid) < 0)
+                       return error(_("'%s' does not have a commit checked out"), path);
                while (namelen && path[namelen-1] == '/')
                        namelen--;
        }
index 5a8425962bb91a803dae9781fa94e5ea7199d276..c325167b90318b2f85a9b53e3aea89eb989e6d64 100755 (executable)
@@ -296,6 +296,17 @@ test_expect_success '"git add ." in empty repo' '
        )
 '
 
+test_expect_success 'error on a repository with no commits' '
+       rm -fr empty &&
+       git init empty &&
+       test_must_fail git add empty >actual 2>&1 &&
+       cat >expect <<-EOF &&
+       error: '"'empty/'"' does not have a commit checked out
+       fatal: adding files failed
+       EOF
+       test_i18ncmp expect actual
+'
+
 test_expect_success 'git add --dry-run of existing changed file' "
        echo new >>track-this &&
        git add --dry-run track-this >actual 2>&1 &&