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::
|
rmHints::
|
||||||
In case of failure in the output of linkgit:git-rm[1],
|
In case of failure in the output of linkgit:git-rm[1],
|
||||||
show directions on how to proceed from the current state.
|
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::
|
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
|
be ignored, no matter if they are already present in the work
|
||||||
tree or not.
|
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::
|
--chmod=(+|-)x::
|
||||||
Override the executable bit of the added files. The executable
|
Override the executable bit of the added files. The executable
|
||||||
bit is only changed in the index, the files on disk are left
|
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_set_upstream_failure = 1;
|
||||||
int advice_object_name_warning = 1;
|
int advice_object_name_warning = 1;
|
||||||
int advice_rm_hints = 1;
|
int advice_rm_hints = 1;
|
||||||
|
int advice_add_embedded_repo = 1;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -36,6 +37,7 @@ static struct {
|
|||||||
{ "setupstreamfailure", &advice_set_upstream_failure },
|
{ "setupstreamfailure", &advice_set_upstream_failure },
|
||||||
{ "objectnamewarning", &advice_object_name_warning },
|
{ "objectnamewarning", &advice_object_name_warning },
|
||||||
{ "rmhints", &advice_rm_hints },
|
{ "rmhints", &advice_rm_hints },
|
||||||
|
{ "addembeddedrepo", &advice_add_embedded_repo },
|
||||||
|
|
||||||
/* make this an alias for backward compatibility */
|
/* make this an alias for backward compatibility */
|
||||||
{ "pushnonfastforward", &advice_push_update_rejected }
|
{ "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_set_upstream_failure;
|
||||||
extern int advice_object_name_warning;
|
extern int advice_object_name_warning;
|
||||||
extern int advice_rm_hints;
|
extern int advice_rm_hints;
|
||||||
|
extern int advice_add_embedded_repo;
|
||||||
|
|
||||||
int git_default_advice_config(const char *var, const char *value);
|
int git_default_advice_config(const char *var, const char *value);
|
||||||
__attribute__((format (printf, 1, 2)))
|
__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 verbose, show_only, ignored_too, refresh_only;
|
||||||
static int ignore_add_errors, intent_to_add, ignore_missing;
|
static int ignore_add_errors, intent_to_add, ignore_missing;
|
||||||
|
static int warn_on_embedded_repo = 1;
|
||||||
|
|
||||||
#define ADDREMOVE_DEFAULT 1
|
#define ADDREMOVE_DEFAULT 1
|
||||||
static int addremove = ADDREMOVE_DEFAULT;
|
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-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_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_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(),
|
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);
|
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)
|
static int add_files(struct dir_struct *dir, int flags)
|
||||||
{
|
{
|
||||||
int i, exit_status = 0;
|
int i, exit_status = 0;
|
||||||
@ -308,12 +350,14 @@ static int add_files(struct dir_struct *dir, int flags)
|
|||||||
exit_status = 1;
|
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 (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
|
||||||
if (!ignore_add_errors)
|
if (!ignore_add_errors)
|
||||||
die(_("adding files failed"));
|
die(_("adding files failed"));
|
||||||
exit_status = 1;
|
exit_status = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return exit_status;
|
return exit_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +213,8 @@ cmd_add()
|
|||||||
die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
|
die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
|
||||||
fi
|
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
|
then
|
||||||
eval_gettextln "The following path is ignored by one of your .gitignore files:
|
eval_gettextln "The following path is ignored by one of your .gitignore files:
|
||||||
\$sm_path
|
\$sm_path
|
||||||
@ -267,7 +268,7 @@ or you are unsure what this means choose another name with the '--name' option."
|
|||||||
fi
|
fi
|
||||||
git config submodule."$sm_name".url "$realrepo"
|
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'")"
|
die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
|
||||||
|
|
||||||
git config -f .gitmodules submodule."$sm_name".path "$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_cmp expected actual
|
||||||
'
|
'
|
||||||
|
|
||||||
test_create_repo sm2 &&
|
test_expect_success 'create second submodule' '
|
||||||
head7=$(add_file sm2 foo8 foo9) &&
|
test_create_repo sm2 &&
|
||||||
git add sm2
|
head7=$(add_file sm2 foo8 foo9) &&
|
||||||
|
git add sm2
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'multiple submodules' '
|
test_expect_success 'multiple submodules' '
|
||||||
git diff-index -p --submodule=log HEAD >actual &&
|
git diff-index -p --submodule=log HEAD >actual &&
|
||||||
|
@ -643,9 +643,11 @@ test_expect_success 'deleted submodule' '
|
|||||||
test_cmp expected actual
|
test_cmp expected actual
|
||||||
'
|
'
|
||||||
|
|
||||||
test_create_repo sm2 &&
|
test_expect_success 'create second submodule' '
|
||||||
head7=$(add_file sm2 foo8 foo9) &&
|
test_create_repo sm2 &&
|
||||||
git add sm2
|
head7=$(add_file sm2 foo8 foo9) &&
|
||||||
|
git add sm2
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'multiple submodules' '
|
test_expect_success 'multiple submodules' '
|
||||||
git diff-index -p --submodule=diff HEAD >actual &&
|
git diff-index -p --submodule=diff HEAD >actual &&
|
||||||
|
@ -241,9 +241,11 @@ EOF
|
|||||||
test_cmp expected actual
|
test_cmp expected actual
|
||||||
"
|
"
|
||||||
|
|
||||||
test_create_repo sm2 &&
|
test_expect_success 'create second submodule' '
|
||||||
head7=$(add_file sm2 foo8 foo9) &&
|
test_create_repo sm2 &&
|
||||||
git add sm2
|
head7=$(add_file sm2 foo8 foo9) &&
|
||||||
|
git add sm2
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'multiple submodules' "
|
test_expect_success 'multiple submodules' "
|
||||||
git submodule summary >actual &&
|
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