Skip to content

Commit

Permalink
Merge pull request #3303 from libgit2/cmn/index-add-submodule
Browse files Browse the repository at this point in the history
Allow adding a submodule through git_index_add_bypath
  • Loading branch information
ethomson committed Jul 24, 2015
2 parents 91dad18 + 247d27c commit 759b223
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/git2/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ typedef enum {
GIT_EEOF = -20, /**< Unexpected EOF */
GIT_EINVALID = -21, /**< Invalid operation or input */
GIT_EUNCOMMITTED = -22, /**< Uncommitted changes in index prevented operation */
GIT_EDIRECTORY = -23, /**< The operation is not valid for a directory */

GIT_PASSTHROUGH = -30, /**< Internal only */
GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
Expand Down
6 changes: 6 additions & 0 deletions src/blob.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ int git_blob__create_from_paths(
(error = git_repository_odb(&odb, repo)) < 0)
goto done;

if (S_ISDIR(st.st_mode)) {
giterr_set(GITERR_ODB, "cannot create blob from '%s'; it is a directory", content_path);
error = GIT_EDIRECTORY;
goto done;
}

if (out_st)
memcpy(out_st, &st, sizeof(st));

Expand Down
24 changes: 22 additions & 2 deletions src/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -1236,9 +1236,29 @@ int git_index_add_bypath(git_index *index, const char *path)

assert(index && path);

if ((ret = index_entry_init(&entry, index, path)) < 0 ||
(ret = index_insert(index, &entry, 1, false)) < 0)
if ((ret = index_entry_init(&entry, index, path)) == 0)
ret = index_insert(index, &entry, 1, false);

/* If we were given a directory, let's see if it's a submodule */
if (ret < 0 && ret != GIT_EDIRECTORY)
return ret;

if (ret == GIT_EDIRECTORY) {
git_submodule *sm;
git_error_state err;

giterr_capture(&err, ret);

ret = git_submodule_lookup(&sm, INDEX_OWNER(index), path);
if (ret == GIT_ENOTFOUND)
return giterr_restore(&err);
else
git__free(err.error_msg.message);

ret = git_submodule_add_to_index(sm, false);
git_submodule_free(sm);
return ret;
}

/* Adding implies conflict was resolved, move conflict entries to REUC */
if ((ret = index_conflict_to_reuc(index, path)) < 0 && ret != GIT_ENOTFOUND)
Expand Down
35 changes: 35 additions & 0 deletions tests/index/bypath.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "clar_libgit2.h"
#include "repository.h"
#include "../submodule/submodule_helpers.h"

static git_repository *g_repo;
static git_index *g_idx;

void test_index_bypath__initialize(void)
{
g_repo = setup_fixture_submod2();
cl_git_pass(git_repository_index__weakptr(&g_idx, g_repo));
}

void test_index_bypath__cleanup(void)
{
g_repo = NULL;
g_idx = NULL;
}

void test_index_bypath__add_directory(void)
{
cl_git_fail_with(GIT_EDIRECTORY, git_index_add_bypath(g_idx, "just_a_dir"));
}

void test_index_bypath__add_submodule(void)
{
unsigned int status;
const char *sm_name = "sm_changed_head";

cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
cl_assert_equal_i(GIT_SUBMODULE_STATUS_WD_MODIFIED, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
cl_git_pass(git_index_add_bypath(g_idx, sm_name));
cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
cl_assert_equal_i(0, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
}
1 change: 1 addition & 0 deletions tests/submodule/add.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "submodule_helpers.h"
#include "config/config_helpers.h"
#include "fileops.h"
#include "repository.h"

static git_repository *g_repo = NULL;

Expand Down

0 comments on commit 759b223

Please sign in to comment.