Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 16cee5d

Browse files
ethomsoncarlosmn
authored andcommitted
Stage an unregistered submodule in _add_bypath()
1 parent 62a273c commit 16cee5d

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

src/index.c

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,45 @@ int git_index_add_frombuffer(
12281228
return 0;
12291229
}
12301230

1231+
static int add_repo_as_submodule(git_index_entry **out, git_index *index, const char *path)
1232+
{
1233+
git_repository *sub;
1234+
git_buf abspath = GIT_BUF_INIT;
1235+
git_repository *repo = INDEX_OWNER(index);
1236+
git_reference *head;
1237+
git_index_entry *entry;
1238+
struct stat st;
1239+
int error;
1240+
1241+
if (index_entry_create(&entry, INDEX_OWNER(index), path) < 0)
1242+
return -1;
1243+
1244+
if ((error = git_buf_joinpath(&abspath, git_repository_workdir(repo), path)) < 0)
1245+
return error;
1246+
1247+
if ((error = p_stat(abspath.ptr, &st)) < 0) {
1248+
giterr_set(GITERR_OS, "failed to stat repository dir");
1249+
return -1;
1250+
}
1251+
1252+
git_index_entry__init_from_stat(entry, &st, !index->distrust_filemode);
1253+
1254+
if ((error = git_repository_open(&sub, abspath.ptr)) < 0)
1255+
return error;
1256+
1257+
if ((error = git_repository_head(&head, sub)) < 0)
1258+
return error;
1259+
1260+
git_oid_cpy(&entry->id, git_reference_target(head));
1261+
entry->mode = GIT_FILEMODE_COMMIT;
1262+
1263+
git_reference_free(head);
1264+
git_repository_free(sub);
1265+
git_buf_free(&abspath);
1266+
1267+
*out = entry;
1268+
return 0;
1269+
}
12311270

12321271
int git_index_add_bypath(git_index *index, const char *path)
12331272
{
@@ -1252,12 +1291,26 @@ int git_index_add_bypath(git_index *index, const char *path)
12521291
ret = git_submodule_lookup(&sm, INDEX_OWNER(index), path);
12531292
if (ret == GIT_ENOTFOUND)
12541293
return giterr_restore(&err);
1255-
else
1256-
git__free(err.error_msg.message);
12571294

1258-
ret = git_submodule_add_to_index(sm, false);
1259-
git_submodule_free(sm);
1260-
return ret;
1295+
git__free(err.error_msg.message);
1296+
1297+
/*
1298+
* EEXISTS means that there is a repository at that path, but it's not known
1299+
* as a submodule. We add its HEAD as an entry and don't register it.
1300+
*/
1301+
if (ret == GIT_EEXISTS) {
1302+
if ((ret = add_repo_as_submodule(&entry, index, path)) < 0)
1303+
return ret;
1304+
1305+
if ((ret = index_insert(index, &entry, 1, false)) < 0)
1306+
return ret;
1307+
} else if (ret < 0) {
1308+
return ret;
1309+
} else {
1310+
ret = git_submodule_add_to_index(sm, false);
1311+
git_submodule_free(sm);
1312+
return ret;
1313+
}
12611314
}
12621315

12631316
/* Adding implies conflict was resolved, move conflict entries to REUC */

tests/index/bypath.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,16 @@ void test_index_bypath__add_submodule(void)
3333
cl_git_pass(git_submodule_status(&status, g_repo, sm_name, 0));
3434
cl_assert_equal_i(0, status & GIT_SUBMODULE_STATUS_WD_MODIFIED);
3535
}
36+
37+
void test_index_bypath__add_submodule_unregistered(void)
38+
{
39+
const char *sm_name = "not-submodule";
40+
const char *sm_head = "68e92c611b80ee1ed8f38314ff9577f0d15b2444";
41+
const git_index_entry *entry;
42+
43+
cl_git_pass(git_index_add_bypath(g_idx, sm_name));
44+
45+
cl_assert(entry = git_index_get_bypath(g_idx, sm_name, 0));
46+
cl_assert_equal_s(sm_head, git_oid_tostr_s(&entry->id));
47+
cl_assert_equal_s(sm_name, entry->path);
48+
}

0 commit comments

Comments
 (0)