Merge branch 'jk/warn-add-gitlink'

Using "git add d/i/r" when d/i/r is the top of the working tree of
a separate repository would create a gitlink in the index, which
would appear as a not-quite-initialized submodule to others.  We
learned to give warnings when this happens.

* jk/warn-add-gitlink:
  t: move "git add submodule" into test blocks
  add: warn when adding an embedded repository
This commit is contained in:
Junio C Hamano
2017-06-24 14:28:41 -07:00
10 changed files with 113 additions and 12 deletions

View File

@ -250,6 +250,7 @@ N_("The following paths are ignored by one of your .gitignore files:\n");
static int verbose, show_only, ignored_too, refresh_only;
static int ignore_add_errors, intent_to_add, ignore_missing;
static int warn_on_embedded_repo = 1;
#define ADDREMOVE_DEFAULT 1
static int addremove = ADDREMOVE_DEFAULT;
@ -283,6 +284,8 @@ static struct option builtin_add_options[] = {
OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")),
OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")),
OPT_STRING( 0 , "chmod", &chmod_arg, N_("(+/-)x"), N_("override the executable bit of the listed files")),
OPT_HIDDEN_BOOL(0, "warn-embedded-repo", &warn_on_embedded_repo,
N_("warn when adding an embedded repository")),
OPT_END(),
};
@ -296,6 +299,45 @@ static int add_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
static const char embedded_advice[] = N_(
"You've added another git repository inside your current repository.\n"
"Clones of the outer repository will not contain the contents of\n"
"the embedded repository and will not know how to obtain it.\n"
"If you meant to add a submodule, use:\n"
"\n"
" git submodule add <url> %s\n"
"\n"
"If you added this path by mistake, you can remove it from the\n"
"index with:\n"
"\n"
" git rm --cached %s\n"
"\n"
"See \"git help submodule\" for more information."
);
static void check_embedded_repo(const char *path)
{
struct strbuf name = STRBUF_INIT;
if (!warn_on_embedded_repo)
return;
if (!ends_with(path, "/"))
return;
/* Drop trailing slash for aesthetics */
strbuf_addstr(&name, path);
strbuf_strip_suffix(&name, "/");
warning(_("adding embedded git repository: %s"), name.buf);
if (advice_add_embedded_repo) {
advise(embedded_advice, name.buf, name.buf);
/* there may be multiple entries; advise only once */
advice_add_embedded_repo = 0;
}
strbuf_release(&name);
}
static int add_files(struct dir_struct *dir, int flags)
{
int i, exit_status = 0;
@ -308,12 +350,14 @@ static int add_files(struct dir_struct *dir, int flags)
exit_status = 1;
}
for (i = 0; i < dir->nr; i++)
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;
}
}
return exit_status;
}