Merge branch 'ao/submodule-wo-gitmodules-checked-out'

The submodule support has been updated to read from the blob at
HEAD:.gitmodules when the .gitmodules file is missing from the
working tree.

* ao/submodule-wo-gitmodules-checked-out:
  t/helper: add test-submodule-nested-repo-config
  submodule: support reading .gitmodules when it's not in the working tree
  submodule: add a helper to check if it is safe to write to .gitmodules
  t7506: clean up .gitmodules properly before setting up new scenario
  submodule: use the 'submodule--helper config' command
  submodule--helper: add a new 'config' subcommand
  t7411: be nicer to future tests and really clean things up
  t7411: merge tests 5 and 6
  submodule: factor out a config_set_in_gitmodules_file_gently function
  submodule: add a print_config_from_gitmodules() helper
This commit is contained in:
Junio C Hamano
2018-11-13 22:37:22 +09:00
16 changed files with 455 additions and 33 deletions

View File

@ -1,4 +1,5 @@
#include "cache.h"
#include "dir.h"
#include "repository.h"
#include "config.h"
#include "submodule-config.h"
@ -613,8 +614,34 @@ static void submodule_cache_check_init(struct repository *repo)
static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void *data)
{
if (repo->worktree) {
char *file = repo_worktree_path(repo, GITMODULES_FILE);
git_config_from_file(fn, file, data);
struct git_config_source config_source = { 0 };
const struct config_options opts = { 0 };
struct object_id oid;
char *file;
file = repo_worktree_path(repo, GITMODULES_FILE);
if (file_exists(file)) {
config_source.file = file;
} else if (repo->submodule_prefix) {
/*
* When get_oid and config_with_options, used below,
* become able to work on a specific repository, this
* warning branch can be removed.
*/
warning("nested submodules without %s in the working tree are not supported yet",
GITMODULES_FILE);
goto out;
} else if (get_oid(GITMODULES_INDEX, &oid) >= 0) {
config_source.blob = GITMODULES_INDEX;
} else if (get_oid(GITMODULES_HEAD, &oid) >= 0) {
config_source.blob = GITMODULES_HEAD;
} else {
goto out;
}
config_with_options(fn, data, &config_source, &opts);
out:
free(file);
}
}
@ -692,6 +719,43 @@ void submodule_free(struct repository *r)
submodule_cache_clear(r->submodule_cache);
}
static int config_print_callback(const char *var, const char *value, void *cb_data)
{
char *wanted_key = cb_data;
if (!strcmp(wanted_key, var))
printf("%s\n", value);
return 0;
}
int print_config_from_gitmodules(struct repository *repo, const char *key)
{
int ret;
char *store_key;
ret = git_config_parse_key(key, &store_key, NULL);
if (ret < 0)
return CONFIG_INVALID_KEY;
config_from_gitmodules(config_print_callback, repo, store_key);
free(store_key);
return 0;
}
int config_set_in_gitmodules_file_gently(const char *key, const char *value)
{
int ret;
ret = git_config_set_in_file_gently(GITMODULES_FILE, key, value);
if (ret < 0)
/* Maybe the user already did that, don't error out here */
warning(_("Could not update .gitmodules entry %s"), key);
return ret;
}
struct fetch_config {
int *max_children;
int *recurse_submodules;