diff options
| author | Russell Belfer <rb@github.com> | 2013-05-15 14:54:02 -0700 |
|---|---|---|
| committer | Russell Belfer <rb@github.com> | 2013-05-15 14:54:02 -0700 |
| commit | dcb0f7c061554de06db5879361b22eab3517a4ee (patch) | |
| tree | 2221b740034cf3bf6236daa60242bb966d7c76cd /src/checkout.c | |
| parent | 55d3a39098bfc513b12ad6cb56658cb2f87e6a91 (diff) | |
| download | libgit2-dcb0f7c061554de06db5879361b22eab3517a4ee.tar.gz | |
Fix checkout of submodules with no .gitmodules
It is possible for there to be a submodule in a repository with
no .gitmodules file (for example, if the user forgot to commit
the .gitmodules file). In this case, core Git will just create
an empty directory as a placeholder for the submodule but
otherwise ignore it. We were generating an error and stopping
the checkout. This makes our behavior match that of core git.
Diffstat (limited to 'src/checkout.c')
| -rw-r--r-- | src/checkout.c | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/src/checkout.c b/src/checkout.c index 4d019dbd1..5820f626a 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -820,6 +820,31 @@ static int checkout_update_index( return git_index_add(data->index, &entry); } +static int checkout_submodule_update_index( + checkout_data *data, + const git_diff_file *file) +{ + struct stat st; + + /* update the index unless prevented */ + if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) != 0) + return 0; + + git_buf_truncate(&data->path, data->workdir_len); + if (git_buf_puts(&data->path, file->path) < 0) + return -1; + + if (p_stat(git_buf_cstr(&data->path), &st) < 0) { + giterr_set( + GITERR_CHECKOUT, "Could not stat submodule %s\n", file->path); + return GIT_ENOTFOUND; + } + + st.st_mode = GIT_FILEMODE_COMMIT; + + return checkout_update_index(data, file, &st); +} + static int checkout_submodule( checkout_data *data, const git_diff_file *file) @@ -836,8 +861,17 @@ static int checkout_submodule( data->opts.dir_mode, GIT_MKDIR_PATH)) < 0) return error; - if ((error = git_submodule_lookup(&sm, data->repo, file->path)) < 0) + if ((error = git_submodule_lookup(&sm, data->repo, file->path)) < 0) { + /* I've observed repos with submodules in the tree that do not + * have a .gitmodules - core Git just makes an empty directory + */ + if (error == GIT_ENOTFOUND) { + giterr_clear(); + return checkout_submodule_update_index(data, file); + } + return error; + } /* TODO: Support checkout_strategy options. Two circumstances: * 1 - submodule already checked out, but we need to move the HEAD @@ -848,26 +882,7 @@ static int checkout_submodule( * command should probably be able to. Do we need a submodule callback? */ - /* update the index unless prevented */ - if ((data->strategy & GIT_CHECKOUT_DONT_UPDATE_INDEX) == 0) { - struct stat st; - - git_buf_truncate(&data->path, data->workdir_len); - if (git_buf_puts(&data->path, file->path) < 0) - return -1; - - if ((error = p_stat(git_buf_cstr(&data->path), &st)) < 0) { - giterr_set( - GITERR_CHECKOUT, "Could not stat submodule %s\n", file->path); - return error; - } - - st.st_mode = GIT_FILEMODE_COMMIT; - - error = checkout_update_index(data, file, &st); - } - - return error; + return checkout_submodule_update_index(data, file); } static void report_progress( |
