mirror of
https://github.com/git/git.git
synced 2026-08-09 01:21:47 +00:00
read-cache: submodule add need --force given ignore=all configuration
Submodules configured with ignore=all are now skipped during add operations unless overridden by --force and the submodule path is explicitly specified. A message is printed (like ignored files) guiding the user to use the --force flag if the user explicitly wants to update the submodule reference. The reason for the change is to support branch tracking in submodules with configuration `submdule.<name>.branch` or similar workflows where the user is not interested in tracking each update of the sha1 in the submdule. You can additionally set `submodule.<name>.ignore=all` and the `git status` will state nothing and, with this patch, the `git add` does not either - as the default behaviour. This patch changes the workflow to a more logical behaviour and similar to workflow for ignored files. The patch gives more scenarios for submodules to be used effectively with less friction similar to the "repo" tool. A submodule can be added for many different reasons than a hard dependency. It can be added as loosely coupled dependencies whereas the user wants the latest based on the configuration `submoule.<name>.branch`, but are not interested to track each commit in the `super-repo`. Currently it gives friction of handling conflicts between branches even the sha1's are fast-forward and the user just wants the latest in any way. The user can still add a sha1 explicitly to track updates. Signed-off-by: Claus Schneider(Eficode) <claus.schneider@eficode.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
37196d8995
commit
a16c4a245a
74
read-cache.c
74
read-cache.c
@@ -47,6 +47,9 @@
|
|||||||
#include "csum-file.h"
|
#include "csum-file.h"
|
||||||
#include "promisor-remote.h"
|
#include "promisor-remote.h"
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
|
#include "submodule.h"
|
||||||
|
#include "submodule-config.h"
|
||||||
|
#include "advice.h"
|
||||||
|
|
||||||
/* Mask for the name length in ce_flags in the on-disk index */
|
/* Mask for the name length in ce_flags in the on-disk index */
|
||||||
|
|
||||||
@@ -3907,8 +3910,68 @@ static int fix_unmerged_status(struct diff_filepair *p,
|
|||||||
return DIFF_STATUS_MODIFIED;
|
return DIFF_STATUS_MODIFIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int skip_submodule(const char *path,
|
||||||
|
struct repository *repo,
|
||||||
|
struct pathspec *pathspec,
|
||||||
|
int ignored_too)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
const struct submodule *sub;
|
||||||
|
int pathspec_matches = 0;
|
||||||
|
int ps_i;
|
||||||
|
char *norm_pathspec = NULL;
|
||||||
|
|
||||||
|
/* Only consider if path is a directory */
|
||||||
|
if (lstat(path, &st) || !S_ISDIR(st.st_mode))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Check if it's a submodule with ignore=all */
|
||||||
|
sub = submodule_from_path(repo, null_oid(the_hash_algo), path);
|
||||||
|
if (!sub || !sub->name || !sub->ignore || strcmp(sub->ignore, "all"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
trace_printf("ignore=all: %s\n", path);
|
||||||
|
trace_printf("pathspec %s\n", (pathspec && pathspec->nr)
|
||||||
|
? "has pathspec"
|
||||||
|
: "no pathspec");
|
||||||
|
|
||||||
|
/* Check if submodule path is explicitly mentioned in pathspec */
|
||||||
|
if (pathspec) {
|
||||||
|
for (ps_i = 0; ps_i < pathspec->nr; ps_i++) {
|
||||||
|
const char *m = pathspec->items[ps_i].match;
|
||||||
|
if (!m)
|
||||||
|
continue;
|
||||||
|
norm_pathspec = xstrdup(m);
|
||||||
|
strip_dir_trailing_slashes(norm_pathspec);
|
||||||
|
if (!strcmp(path, norm_pathspec)) {
|
||||||
|
pathspec_matches = 1;
|
||||||
|
FREE_AND_NULL(norm_pathspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
FREE_AND_NULL(norm_pathspec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If explicitly matched and forced, allow adding */
|
||||||
|
if (pathspec_matches) {
|
||||||
|
if (ignored_too && ignored_too > 0) {
|
||||||
|
trace_printf("Add submodule due to --force: %s\n", path);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
advise_if_enabled(ADVICE_ADD_IGNORED_FILE,
|
||||||
|
_("Skipping submodule due to ignore=all: %s\n"
|
||||||
|
"Use --force if you really want to add the submodule."), path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No explicit pathspec match -> skip silently */
|
||||||
|
trace_printf("Pathspec to submodule does not match explicitly: %s\n", path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static void update_callback(struct diff_queue_struct *q,
|
static void update_callback(struct diff_queue_struct *q,
|
||||||
struct diff_options *opt UNUSED, void *cbdata)
|
struct diff_options *opt UNUSED, void *cbdata)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct update_callback_data *data = cbdata;
|
struct update_callback_data *data = cbdata;
|
||||||
@@ -3918,14 +3981,19 @@ static void update_callback(struct diff_queue_struct *q,
|
|||||||
const char *path = p->one->path;
|
const char *path = p->one->path;
|
||||||
|
|
||||||
if (!data->include_sparse &&
|
if (!data->include_sparse &&
|
||||||
!path_in_sparse_checkout(path, data->index))
|
!path_in_sparse_checkout(path, data->index))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (fix_unmerged_status(p, data)) {
|
switch (fix_unmerged_status(p, data)) {
|
||||||
default:
|
default:
|
||||||
die(_("unexpected diff status %c"), p->status);
|
die(_("unexpected diff status %c"), p->status);
|
||||||
case DIFF_STATUS_MODIFIED:
|
case DIFF_STATUS_MODIFIED:
|
||||||
case DIFF_STATUS_TYPE_CHANGED: {
|
case DIFF_STATUS_TYPE_CHANGED:
|
||||||
|
if (skip_submodule(path, data->repo,
|
||||||
|
data->pathspec,
|
||||||
|
data->ignored_too))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (add_file_to_index(data->index, path, data->flags)) {
|
if (add_file_to_index(data->index, path, data->flags)) {
|
||||||
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
|
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
|
||||||
die(_("updating files failed"));
|
die(_("updating files failed"));
|
||||||
|
|||||||
Reference in New Issue
Block a user