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:
commit
cda4ba30b1
@ -348,6 +348,9 @@ advice.*::
|
||||
rmHints::
|
||||
In case of failure in the output of linkgit:git-rm[1],
|
||||
show directions on how to proceed from the current state.
|
||||
addEmbeddedRepo::
|
||||
Advice on what to do when you've accidentally added one
|
||||
git repo inside of another.
|
||||
--
|
||||
|
||||
core.fileMode::
|
||||
|
@ -165,6 +165,13 @@ for "git add --no-all <pathspec>...", i.e. ignored removed files.
|
||||
be ignored, no matter if they are already present in the work
|
||||
tree or not.
|
||||
|
||||
--no-warn-embedded-repo::
|
||||
By default, `git add` will warn when adding an embedded
|
||||
repository to the index without using `git submodule add` to
|
||||
create an entry in `.gitmodules`. This option will suppress the
|
||||
warning (e.g., if you are manually performing operations on
|
||||
submodules).
|
||||
|
||||
--chmod=(+|-)x::
|
||||
Override the executable bit of the added files. The executable
|
||||
bit is only changed in the index, the files on disk are left
|
||||
|
2
advice.c
2
advice.c
@ -16,6 +16,7 @@ int advice_detached_head = 1;
|
||||
int advice_set_upstream_failure = 1;
|
||||
int advice_object_name_warning = 1;
|
||||
int advice_rm_hints = 1;
|
||||
int advice_add_embedded_repo = 1;
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
@ -36,6 +37,7 @@ static struct {
|
||||
{ "setupstreamfailure", &advice_set_upstream_failure },
|
||||
{ "objectnamewarning", &advice_object_name_warning },
|
||||
{ "rmhints", &advice_rm_hints },
|
||||
{ "addembeddedrepo", &advice_add_embedded_repo },
|
||||
|
||||
/* make this an alias for backward compatibility */
|
||||
{ "pushnonfastforward", &advice_push_update_rejected }
|
||||
|
1
advice.h
1
advice.h
@ -18,6 +18,7 @@ extern int advice_detached_head;
|
||||
extern int advice_set_upstream_failure;
|
||||
extern int advice_object_name_warning;
|
||||
extern int advice_rm_hints;
|
||||
extern int advice_add_embedded_repo;
|
||||
|
||||
int git_default_advice_config(const char *var, const char *value);
|
||||
__attribute__((format (printf, 1, 2)))
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,8 @@ cmd_add()
|
||||
die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
|
||||
fi
|
||||
|
||||
if test -z "$force" && ! git add --dry-run --ignore-missing "$sm_path" > /dev/null 2>&1
|
||||
if test -z "$force" &&
|
||||
! git add --dry-run --ignore-missing --no-warn-embedded-repo "$sm_path" > /dev/null 2>&1
|
||||
then
|
||||
eval_gettextln "The following path is ignored by one of your .gitignore files:
|
||||
\$sm_path
|
||||
@ -267,7 +268,7 @@ or you are unsure what this means choose another name with the '--name' option."
|
||||
fi
|
||||
git config submodule."$sm_name".url "$realrepo"
|
||||
|
||||
git add $force "$sm_path" ||
|
||||
git add --no-warn-embedded-repo $force "$sm_path" ||
|
||||
die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
|
||||
|
||||
git config -f .gitmodules submodule."$sm_name".path "$sm_path" &&
|
||||
|
@ -430,9 +430,11 @@ test_expect_success 'deleted submodule' '
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_create_repo sm2 &&
|
||||
head7=$(add_file sm2 foo8 foo9) &&
|
||||
git add sm2
|
||||
test_expect_success 'create second submodule' '
|
||||
test_create_repo sm2 &&
|
||||
head7=$(add_file sm2 foo8 foo9) &&
|
||||
git add sm2
|
||||
'
|
||||
|
||||
test_expect_success 'multiple submodules' '
|
||||
git diff-index -p --submodule=log HEAD >actual &&
|
||||
|
@ -643,9 +643,11 @@ test_expect_success 'deleted submodule' '
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
test_create_repo sm2 &&
|
||||
head7=$(add_file sm2 foo8 foo9) &&
|
||||
git add sm2
|
||||
test_expect_success 'create second submodule' '
|
||||
test_create_repo sm2 &&
|
||||
head7=$(add_file sm2 foo8 foo9) &&
|
||||
git add sm2
|
||||
'
|
||||
|
||||
test_expect_success 'multiple submodules' '
|
||||
git diff-index -p --submodule=diff HEAD >actual &&
|
||||
|
@ -241,9 +241,11 @@ EOF
|
||||
test_cmp expected actual
|
||||
"
|
||||
|
||||
test_create_repo sm2 &&
|
||||
head7=$(add_file sm2 foo8 foo9) &&
|
||||
git add sm2
|
||||
test_expect_success 'create second submodule' '
|
||||
test_create_repo sm2 &&
|
||||
head7=$(add_file sm2 foo8 foo9) &&
|
||||
git add sm2
|
||||
'
|
||||
|
||||
test_expect_success 'multiple submodules' "
|
||||
git submodule summary >actual &&
|
||||
|
37
t/t7414-submodule-mistakes.sh
Executable file
37
t/t7414-submodule-mistakes.sh
Executable file
@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='handling of common mistakes people may make with submodules'
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'create embedded repository' '
|
||||
git init embed &&
|
||||
test_commit -C embed one
|
||||
'
|
||||
|
||||
test_expect_success 'git-add on embedded repository warns' '
|
||||
test_when_finished "git rm --cached -f embed" &&
|
||||
git add embed 2>stderr &&
|
||||
test_i18ngrep warning stderr
|
||||
'
|
||||
|
||||
test_expect_success '--no-warn-embedded-repo suppresses warning' '
|
||||
test_when_finished "git rm --cached -f embed" &&
|
||||
git add --no-warn-embedded-repo embed 2>stderr &&
|
||||
test_i18ngrep ! warning stderr
|
||||
'
|
||||
|
||||
test_expect_success 'no warning when updating entry' '
|
||||
test_when_finished "git rm --cached -f embed" &&
|
||||
git add embed &&
|
||||
git -C embed commit --allow-empty -m two &&
|
||||
git add embed 2>stderr &&
|
||||
test_i18ngrep ! warning stderr
|
||||
'
|
||||
|
||||
test_expect_success 'submodule add does not warn' '
|
||||
test_when_finished "git rm -rf submodule .gitmodules" &&
|
||||
git submodule add ./embed submodule 2>stderr &&
|
||||
test_i18ngrep ! warning stderr
|
||||
'
|
||||
|
||||
test_done
|
Loading…
Reference in New Issue
Block a user