Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements. https://git-scm.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
git/submodule.c

2368 lines
62 KiB

#include "cache.h"
#include "repository.h"
#include "config.h"
#include "submodule-config.h"
#include "submodule.h"
#include "dir.h"
#include "diff.h"
#include "commit.h"
#include "revision.h"
#include "run-command.h"
#include "diffcore.h"
#include "refs.h"
Submodules: Add the new "ignore" config option for diff and status The new "ignore" config option controls the default behavior for "git status" and the diff family. It specifies under what circumstances they consider submodules as modified and can be set separately for each submodule. The command line option "--ignore-submodules=" has been extended to accept the new parameter "none" for both status and diff. Users that chose submodules to get rid of long work tree scanning times might want to set the "dirty" option for those submodules. This brings back the pre 1.7.0 behavior, where submodule work trees were never scanned for modifications. By using "--ignore-submodules=none" on the command line the status and diff commands can be told to do a full scan. This option can be set to the following values (which have the same name and meaning as for the "--ignore-submodules" option of status and diff): "all": All changes to the submodule will be ignored. "dirty": Only differences of the commit recorded in the superproject and the submodules HEAD will be considered modifications, all changes to the work tree of the submodule will be ignored. When using this value, the submodule will not be scanned for work tree changes at all, leading to a performance benefit on large submodules. "untracked": Only untracked files in the submodules work tree are ignored, a changed HEAD and/or modified files in the submodule will mark it as modified. "none" (which is the default): Either untracked or modified files in a submodules work tree or a difference between the subdmodules HEAD and the commit recorded in the superproject will make it show up as changed. This value is added as a new parameter for the "--ignore-submodules" option of the diff family and "git status" so the user can override the settings in the configuration. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
12 years ago
#include "string-list.h"
#include "oid-array.h"
#include "strvec.h"
#include "blob.h"
#include "thread-utils.h"
#include "quote.h"
#include "remote.h"
#include "worktree.h"
#include "parse-options.h"
#include "object-store.h"
#include "commit-reach.h"
Submodules: Add the new "ignore" config option for diff and status The new "ignore" config option controls the default behavior for "git status" and the diff family. It specifies under what circumstances they consider submodules as modified and can be set separately for each submodule. The command line option "--ignore-submodules=" has been extended to accept the new parameter "none" for both status and diff. Users that chose submodules to get rid of long work tree scanning times might want to set the "dirty" option for those submodules. This brings back the pre 1.7.0 behavior, where submodule work trees were never scanned for modifications. By using "--ignore-submodules=none" on the command line the status and diff commands can be told to do a full scan. This option can be set to the following values (which have the same name and meaning as for the "--ignore-submodules" option of status and diff): "all": All changes to the submodule will be ignored. "dirty": Only differences of the commit recorded in the superproject and the submodules HEAD will be considered modifications, all changes to the work tree of the submodule will be ignored. When using this value, the submodule will not be scanned for work tree changes at all, leading to a performance benefit on large submodules. "untracked": Only untracked files in the submodules work tree are ignored, a changed HEAD and/or modified files in the submodule will mark it as modified. "none" (which is the default): Either untracked or modified files in a submodules work tree or a difference between the subdmodules HEAD and the commit recorded in the superproject will make it show up as changed. This value is added as a new parameter for the "--ignore-submodules" option of the diff family and "git status" so the user can override the settings in the configuration. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
12 years ago
static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
fetch: avoid quadratic loop checking for updated submodules Recent versions of git can be slow to fetch repositories with a large number of refs (or when they already have a large number of refs). For example, GitHub makes pull-requests available as refs, which can lead to a large number of available refs. This slowness goes away when submodule recursion is turned off: $ git ls-remote git://github.com/rails/rails.git | wc -l 3034 [this takes ~10 seconds of CPU time to complete] git fetch --recurse-submodules=no \ git://github.com/rails/rails.git "refs/*:refs/*" [this still isn't done after 10 _minutes_ of pegging the CPU] git fetch \ git://github.com/rails/rails.git "refs/*:refs/*" You can produce a quicker and simpler test case like this: doit() { head=`git rev-parse HEAD` for i in `seq 1 $1`; do echo $head refs/heads/ref$i done >.git/packed-refs echo "==> $1" rm -rf dest git init -q --bare dest && (cd dest && time git.compile fetch -q .. refs/*:refs/*) } rm -rf repo git init -q repo && cd repo && >file && git add file && git commit -q -m one doit 100 doit 200 doit 400 doit 800 doit 1600 doit 3200 Which yields timings like: # refs seconds of CPU 100 0.06 200 0.24 400 0.95 800 3.39 1600 13.66 3200 54.09 Notice that although the number of refs doubles in each trial, the CPU time spent quadruples. The problem is that the submodule recursion code works something like: - for each ref we fetch - for each commit in git rev-list $new_sha1 --not --all - add modified submodules to list - fetch any newly referenced submodules But that means if we fetch N refs, we start N revision walks. Worse, because we use "--all", the number of refs we must process that constitute "--all" keeps growing, too. And you end up doing O(N^2) ref resolutions. Instead, this patch structures the code like this: - for each sha1 we already have - add $old_sha1 to list $old - for each ref we fetch - add $new_sha1 to list $new - for each commit in git rev-list $new --not $old - add modified submodules to list - fetch any newly referenced submodules This yields timings like: # refs seconds of CPU 100 0.00 200 0.04 400 0.04 800 0.10 1600 0.21 3200 0.39 Note that the amount of effort doubles as the number of refs doubles. Similarly, the fetch of rails.git takes about as much time as it does with --recurse-submodules=no. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
11 years ago
static int initialized_fetch_ref_tips;
static struct oid_array ref_tips_before_fetch;
static struct oid_array ref_tips_after_fetch;
fetch: avoid quadratic loop checking for updated submodules Recent versions of git can be slow to fetch repositories with a large number of refs (or when they already have a large number of refs). For example, GitHub makes pull-requests available as refs, which can lead to a large number of available refs. This slowness goes away when submodule recursion is turned off: $ git ls-remote git://github.com/rails/rails.git | wc -l 3034 [this takes ~10 seconds of CPU time to complete] git fetch --recurse-submodules=no \ git://github.com/rails/rails.git "refs/*:refs/*" [this still isn't done after 10 _minutes_ of pegging the CPU] git fetch \ git://github.com/rails/rails.git "refs/*:refs/*" You can produce a quicker and simpler test case like this: doit() { head=`git rev-parse HEAD` for i in `seq 1 $1`; do echo $head refs/heads/ref$i done >.git/packed-refs echo "==> $1" rm -rf dest git init -q --bare dest && (cd dest && time git.compile fetch -q .. refs/*:refs/*) } rm -rf repo git init -q repo && cd repo && >file && git add file && git commit -q -m one doit 100 doit 200 doit 400 doit 800 doit 1600 doit 3200 Which yields timings like: # refs seconds of CPU 100 0.06 200 0.24 400 0.95 800 3.39 1600 13.66 3200 54.09 Notice that although the number of refs doubles in each trial, the CPU time spent quadruples. The problem is that the submodule recursion code works something like: - for each ref we fetch - for each commit in git rev-list $new_sha1 --not --all - add modified submodules to list - fetch any newly referenced submodules But that means if we fetch N refs, we start N revision walks. Worse, because we use "--all", the number of refs we must process that constitute "--all" keeps growing, too. And you end up doing O(N^2) ref resolutions. Instead, this patch structures the code like this: - for each sha1 we already have - add $old_sha1 to list $old - for each ref we fetch - add $new_sha1 to list $new - for each commit in git rev-list $new --not $old - add modified submodules to list - fetch any newly referenced submodules This yields timings like: # refs seconds of CPU 100 0.00 200 0.04 400 0.04 800 0.10 1600 0.21 3200 0.39 Note that the amount of effort doubles as the number of refs doubles. Similarly, the fetch of rails.git takes about as much time as it does with --recurse-submodules=no. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
11 years ago
/*
* Check if the .gitmodules file is unmerged. Parsing of the .gitmodules file
* will be disabled because we can't guess what might be configured in
* .gitmodules unless the user resolves the conflict.
*/
int is_gitmodules_unmerged(struct index_state *istate)
{
int pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));
if (pos < 0) { /* .gitmodules not found or isn't merged */
pos = -1 - pos;
if (istate->cache_nr > pos) { /* there is a .gitmodules */
const struct cache_entry *ce = istate->cache[pos];
if (ce_namelen(ce) == strlen(GITMODULES_FILE) &&
!strcmp(ce->name, GITMODULES_FILE))
return 1;
}
}
return 0;
}
/*
* Check if the .gitmodules file is safe to write.
*
* Writing to the .gitmodules file requires that the file exists in the
* working tree or, if it doesn't, that a brand new .gitmodules file is going
* to be created (i.e. it's neither in the index nor in the current branch).
*
* It is not safe to write to .gitmodules if it's not in the working tree but
* it is in the index or in the current branch, because writing new values
* (and staging them) would blindly overwrite ALL the old content.
*/
int is_writing_gitmodules_ok(void)
{
struct object_id oid;
return file_exists(GITMODULES_FILE) ||
(get_oid(GITMODULES_INDEX, &oid) < 0 && get_oid(GITMODULES_HEAD, &oid) < 0);
}
/*
* Check if the .gitmodules file has unstaged modifications. This must be
* checked before allowing modifications to the .gitmodules file with the
* intention to stage them later, because when continuing we would stage the
* modifications the user didn't stage herself too. That might change in a
* future version when we learn to stage the changes we do ourselves without
* staging any previous modifications.
*/
int is_staging_gitmodules_ok(struct index_state *istate)
{
int pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));
if ((pos >= 0) && (pos < istate->cache_nr)) {
struct stat st;
if (lstat(GITMODULES_FILE, &st) == 0 &&
ie_modified(istate, istate->cache[pos], &st, 0) & DATA_CHANGED)
return 0;
}
return 1;
}
static int for_each_remote_ref_submodule(const char *submodule,
each_ref_fn fn, void *cb_data)
{
return refs_for_each_remote_ref(get_submodule_ref_store(submodule),
fn, cb_data);
}
/*
* Try to update the "path" entry in the "submodule.<name>" section of the
* .gitmodules file. Return 0 only if a .gitmodules file was found, a section
* with the correct path=<oldpath> setting was found and we could update it.
*/
int update_path_in_gitmodules(const char *oldpath, const char *newpath)
{
struct strbuf entry = STRBUF_INIT;
const struct submodule *submodule;
int ret;
if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */
return -1;
if (is_gitmodules_unmerged(the_repository->index))
die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
submodule = submodule_from_path(the_repository, null_oid(), oldpath);
if (!submodule || !submodule->name) {
warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
return -1;
}
strbuf_addstr(&entry, "submodule.");
strbuf_addstr(&entry, submodule->name);
strbuf_addstr(&entry, ".path");
ret = config_set_in_gitmodules_file_gently(entry.buf, newpath);
strbuf_release(&entry);
return ret;
}
rm: delete .gitmodules entry of submodules removed from the work tree Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index. But the submodule's section in .gitmodules is left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out). Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodules file and stage both. This doesn't happen when the "--cached" option is used, as it would modify the work tree. This also silently does nothing when no .gitmodules file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the .gitmodules file or has already removed the section by hand before issuing the "git rm" command (in which case the warning reminds him that rm would have done that for him). Only when .gitmodules is found and contains merge conflicts the rm command will fail and tell the user to resolve the conflict before trying again. Also extend the man page to inform the user about this new feature. While at it promote the submodule sub-section to a chapter as it made not much sense under "REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM". In t7610 three uses of "git rm submod" had to be replaced with "git rm --cached submod" because that test expects .gitmodules and the work tree to stay untouched. Also in t7400 the tests for the remaining settings in the .gitmodules file had to be changed to assert that these settings are missing. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
9 years ago
/*
* Try to remove the "submodule.<name>" section from .gitmodules where the given
* path is configured. Return 0 only if a .gitmodules file was found, a section
* with the correct path=<path> setting was found and we could remove it.
*/
int remove_path_from_gitmodules(const char *path)
{
struct strbuf sect = STRBUF_INIT;
const struct submodule *submodule;
rm: delete .gitmodules entry of submodules removed from the work tree Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index. But the submodule's section in .gitmodules is left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out). Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodules file and stage both. This doesn't happen when the "--cached" option is used, as it would modify the work tree. This also silently does nothing when no .gitmodules file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the .gitmodules file or has already removed the section by hand before issuing the "git rm" command (in which case the warning reminds him that rm would have done that for him). Only when .gitmodules is found and contains merge conflicts the rm command will fail and tell the user to resolve the conflict before trying again. Also extend the man page to inform the user about this new feature. While at it promote the submodule sub-section to a chapter as it made not much sense under "REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM". In t7610 three uses of "git rm submod" had to be replaced with "git rm --cached submod" because that test expects .gitmodules and the work tree to stay untouched. Also in t7400 the tests for the remaining settings in the .gitmodules file had to be changed to assert that these settings are missing. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
9 years ago
if (!file_exists(GITMODULES_FILE)) /* Do nothing without .gitmodules */
rm: delete .gitmodules entry of submodules removed from the work tree Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index. But the submodule's section in .gitmodules is left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out). Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodules file and stage both. This doesn't happen when the "--cached" option is used, as it would modify the work tree. This also silently does nothing when no .gitmodules file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the .gitmodules file or has already removed the section by hand before issuing the "git rm" command (in which case the warning reminds him that rm would have done that for him). Only when .gitmodules is found and contains merge conflicts the rm command will fail and tell the user to resolve the conflict before trying again. Also extend the man page to inform the user about this new feature. While at it promote the submodule sub-section to a chapter as it made not much sense under "REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM". In t7610 three uses of "git rm submod" had to be replaced with "git rm --cached submod" because that test expects .gitmodules and the work tree to stay untouched. Also in t7400 the tests for the remaining settings in the .gitmodules file had to be changed to assert that these settings are missing. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
9 years ago
return -1;
if (is_gitmodules_unmerged(the_repository->index))
rm: delete .gitmodules entry of submodules removed from the work tree Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index. But the submodule's section in .gitmodules is left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out). Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodules file and stage both. This doesn't happen when the "--cached" option is used, as it would modify the work tree. This also silently does nothing when no .gitmodules file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the .gitmodules file or has already removed the section by hand before issuing the "git rm" command (in which case the warning reminds him that rm would have done that for him). Only when .gitmodules is found and contains merge conflicts the rm command will fail and tell the user to resolve the conflict before trying again. Also extend the man page to inform the user about this new feature. While at it promote the submodule sub-section to a chapter as it made not much sense under "REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM". In t7610 three uses of "git rm submod" had to be replaced with "git rm --cached submod" because that test expects .gitmodules and the work tree to stay untouched. Also in t7400 the tests for the remaining settings in the .gitmodules file had to be changed to assert that these settings are missing. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
9 years ago
die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
submodule = submodule_from_path(the_repository, null_oid(), path);
if (!submodule || !submodule->name) {
rm: delete .gitmodules entry of submodules removed from the work tree Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index. But the submodule's section in .gitmodules is left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out). Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodules file and stage both. This doesn't happen when the "--cached" option is used, as it would modify the work tree. This also silently does nothing when no .gitmodules file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the .gitmodules file or has already removed the section by hand before issuing the "git rm" command (in which case the warning reminds him that rm would have done that for him). Only when .gitmodules is found and contains merge conflicts the rm command will fail and tell the user to resolve the conflict before trying again. Also extend the man page to inform the user about this new feature. While at it promote the submodule sub-section to a chapter as it made not much sense under "REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM". In t7610 three uses of "git rm submod" had to be replaced with "git rm --cached submod" because that test expects .gitmodules and the work tree to stay untouched. Also in t7400 the tests for the remaining settings in the .gitmodules file had to be changed to assert that these settings are missing. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
9 years ago
warning(_("Could not find section in .gitmodules where path=%s"), path);
return -1;
}
strbuf_addstr(&sect, "submodule.");
strbuf_addstr(&sect, submodule->name);
if (git_config_rename_section_in_file(GITMODULES_FILE, sect.buf, NULL) < 0) {
rm: delete .gitmodules entry of submodules removed from the work tree Currently using "git rm" on a submodule removes the submodule's work tree from that of the superproject and the gitlink from the index. But the submodule's section in .gitmodules is left untouched, which is a leftover of the now removed submodule and might irritate users (as opposed to the setting in .git/config, this must stay as a reminder that the user showed interest in this submodule so it will be repopulated later when an older commit is checked out). Let "git rm" help the user by not only removing the submodule from the work tree but by also removing the "submodule.<submodule name>" section from the .gitmodules file and stage both. This doesn't happen when the "--cached" option is used, as it would modify the work tree. This also silently does nothing when no .gitmodules file is found and only issues a warning when it doesn't have a section for this submodule. This is because the user might just use plain gitlinks without the .gitmodules file or has already removed the section by hand before issuing the "git rm" command (in which case the warning reminds him that rm would have done that for him). Only when .gitmodules is found and contains merge conflicts the rm command will fail and tell the user to resolve the conflict before trying again. Also extend the man page to inform the user about this new feature. While at it promote the submodule sub-section to a chapter as it made not much sense under "REMOVING FILES THAT HAVE DISAPPEARED FROM THE FILESYSTEM". In t7610 three uses of "git rm submod" had to be replaced with "git rm --cached submod" because that test expects .gitmodules and the work tree to stay untouched. Also in t7400 the tests for the remaining settings in the .gitmodules file had to be changed to assert that these settings are missing. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
9 years ago
/* Maybe the user already did that, don't error out here */
warning(_("Could not remove .gitmodules entry for %s"), path);
strbuf_release(&sect);
return -1;
}
strbuf_release(&sect);
return 0;
}
void stage_updated_gitmodules(struct index_state *istate)
{
if (add_file_to_index(istate, GITMODULES_FILE, 0))
die(_("staging updated .gitmodules failed"));
}
submodule: lazily add submodule ODBs as alternates Teach Git to add submodule ODBs as alternates to the object store of the_repository only upon the first access of an object not in the_repository, and not when add_submodule_odb() is called. This provides a means of gradually migrating from accessing a submodule's object through alternates to accessing a submodule's object by explicitly passing its repository object. Any Git command can declare that it might access submodule objects by calling add_submodule_odb() (as they do now), but the submodule ODBs themselves will not be added until needed, so individual commands and/or combinations of arguments can be migrated one by one. [The advantage of explicit repository-object passing is code clarity (it is clear which repository an object read is from), performance (there is no need to linearly search through all submodule ODBs whenever an object is accessed from any repository, whether superproject or submodule), and the possibility of future features like partial clone submodules (which right now is not possible because if an object is missing, we do not know which repository to lazy-fetch into).] This commit also introduces an environment variable that a test may set to make the actual registration of alternates fatal, in order to demonstrate that its codepaths do not need this registration. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Emily Shaffer <emilyshaffer@google.com> Reviewed-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 year ago
static struct string_list added_submodule_odb_paths = STRING_LIST_INIT_NODUP;
/* TODO: remove this function, use repo_submodule_init instead. */
int add_submodule_odb(const char *path)
{
struct strbuf objects_directory = STRBUF_INIT;
int ret = 0;
allow do_submodule_path to work even if submodule isn't checked out Currently, do_submodule_path will attempt locating the .git directory by using read_gitfile on <path>/.git. If this fails it just assumes the <path>/.git is actually a git directory. This is good because it allows for handling submodules which were cloned in a regular manner first before being added to the superproject. Unfortunately this fails if the <path> is not actually checked out any longer, such as by removing the directory. Fix this by checking if the directory we found is actually a gitdir. In the case it is not, attempt to lookup the submodule configuration and find the name of where it is stored in the .git/modules/ directory of the superproject. If we can't locate the submodule configuration, this might occur because for example a submodule gitlink was added but the corresponding .gitmodules file was not properly updated. A die() here would not be pleasant to the users of submodule diff formats, so instead, modify do_submodule_path() to return an error code: - git_pathdup_submodule() returns NULL when we fail to find a path. - strbuf_git_path_submodule() propagates the error code to the caller. Modify the callers of these functions to check the error code and fail properly. This ensures we don't attempt to use a bad path that doesn't match the corresponding submodule. Because this change fixes add_submodule_odb() to work even if the submodule is not checked out, update the wording of the submodule log diff format to correctly display that the submodule is "not initialized" instead of "not checked out" Add tests to ensure this change works as expected. Signed-off-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
ret = strbuf_git_path_submodule(&objects_directory, path, "objects/");
if (ret)
goto done;
if (!is_directory(objects_directory.buf)) {
ret = -1;
goto done;
}
submodule: lazily add submodule ODBs as alternates Teach Git to add submodule ODBs as alternates to the object store of the_repository only upon the first access of an object not in the_repository, and not when add_submodule_odb() is called. This provides a means of gradually migrating from accessing a submodule's object through alternates to accessing a submodule's object by explicitly passing its repository object. Any Git command can declare that it might access submodule objects by calling add_submodule_odb() (as they do now), but the submodule ODBs themselves will not be added until needed, so individual commands and/or combinations of arguments can be migrated one by one. [The advantage of explicit repository-object passing is code clarity (it is clear which repository an object read is from), performance (there is no need to linearly search through all submodule ODBs whenever an object is accessed from any repository, whether superproject or submodule), and the possibility of future features like partial clone submodules (which right now is not possible because if an object is missing, we do not know which repository to lazy-fetch into).] This commit also introduces an environment variable that a test may set to make the actual registration of alternates fatal, in order to demonstrate that its codepaths do not need this registration. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Emily Shaffer <emilyshaffer@google.com> Reviewed-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 year ago
string_list_insert(&added_submodule_odb_paths,
strbuf_detach(&objects_directory, NULL));
done:
strbuf_release(&objects_directory);
return ret;
}
void add_submodule_odb_by_path(const char *path)
{
string_list_insert(&added_submodule_odb_paths, xstrdup(path));
}
submodule: lazily add submodule ODBs as alternates Teach Git to add submodule ODBs as alternates to the object store of the_repository only upon the first access of an object not in the_repository, and not when add_submodule_odb() is called. This provides a means of gradually migrating from accessing a submodule's object through alternates to accessing a submodule's object by explicitly passing its repository object. Any Git command can declare that it might access submodule objects by calling add_submodule_odb() (as they do now), but the submodule ODBs themselves will not be added until needed, so individual commands and/or combinations of arguments can be migrated one by one. [The advantage of explicit repository-object passing is code clarity (it is clear which repository an object read is from), performance (there is no need to linearly search through all submodule ODBs whenever an object is accessed from any repository, whether superproject or submodule), and the possibility of future features like partial clone submodules (which right now is not possible because if an object is missing, we do not know which repository to lazy-fetch into).] This commit also introduces an environment variable that a test may set to make the actual registration of alternates fatal, in order to demonstrate that its codepaths do not need this registration. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Emily Shaffer <emilyshaffer@google.com> Reviewed-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 year ago
int register_all_submodule_odb_as_alternates(void)
{
int i;
int ret = added_submodule_odb_paths.nr;
for (i = 0; i < added_submodule_odb_paths.nr; i++)
add_to_alternates_memory(added_submodule_odb_paths.items[i].string);
if (ret) {
string_list_clear(&added_submodule_odb_paths, 0);
trace2_data_intmax("submodule", the_repository,
"register_all_submodule_odb_as_alternates/registered", ret);
submodule: lazily add submodule ODBs as alternates Teach Git to add submodule ODBs as alternates to the object store of the_repository only upon the first access of an object not in the_repository, and not when add_submodule_odb() is called. This provides a means of gradually migrating from accessing a submodule's object through alternates to accessing a submodule's object by explicitly passing its repository object. Any Git command can declare that it might access submodule objects by calling add_submodule_odb() (as they do now), but the submodule ODBs themselves will not be added until needed, so individual commands and/or combinations of arguments can be migrated one by one. [The advantage of explicit repository-object passing is code clarity (it is clear which repository an object read is from), performance (there is no need to linearly search through all submodule ODBs whenever an object is accessed from any repository, whether superproject or submodule), and the possibility of future features like partial clone submodules (which right now is not possible because if an object is missing, we do not know which repository to lazy-fetch into).] This commit also introduces an environment variable that a test may set to make the actual registration of alternates fatal, in order to demonstrate that its codepaths do not need this registration. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Emily Shaffer <emilyshaffer@google.com> Reviewed-by: Matheus Tavares <matheus.bernardino@usp.br> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 year ago
if (git_env_bool("GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB", 0))
BUG("register_all_submodule_odb_as_alternates() called");
}
return ret;
}
Submodules: Add the new "ignore" config option for diff and status The new "ignore" config option controls the default behavior for "git status" and the diff family. It specifies under what circumstances they consider submodules as modified and can be set separately for each submodule. The command line option "--ignore-submodules=" has been extended to accept the new parameter "none" for both status and diff. Users that chose submodules to get rid of long work tree scanning times might want to set the "dirty" option for those submodules. This brings back the pre 1.7.0 behavior, where submodule work trees were never scanned for modifications. By using "--ignore-submodules=none" on the command line the status and diff commands can be told to do a full scan. This option can be set to the following values (which have the same name and meaning as for the "--ignore-submodules" option of status and diff): "all": All changes to the submodule will be ignored. "dirty": Only differences of the commit recorded in the superproject and the submodules HEAD will be considered modifications, all changes to the work tree of the submodule will be ignored. When using this value, the submodule will not be scanned for work tree changes at all, leading to a performance benefit on large submodules. "untracked": Only untracked files in the submodules work tree are ignored, a changed HEAD and/or modified files in the submodule will mark it as modified. "none" (which is the default): Either untracked or modified files in a submodules work tree or a difference between the subdmodules HEAD and the commit recorded in the superproject will make it show up as changed. This value is added as a new parameter for the "--ignore-submodules" option of the diff family and "git status" so the user can override the settings in the configuration. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
12 years ago
void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
const char *path)
{
const struct submodule *submodule = submodule_from_path(the_repository,
null_oid(),
path);
if (submodule) {
const char *ignore;
char *key;
Submodules: Add the new "ignore" config option for diff and status The new "ignore" config option controls the default behavior for "git status" and the diff family. It specifies under what circumstances they consider submodules as modified and can be set separately for each submodule. The command line option "--ignore-submodules=" has been extended to accept the new parameter "none" for both status and diff. Users that chose submodules to get rid of long work tree scanning times might want to set the "dirty" option for those submodules. This brings back the pre 1.7.0 behavior, where submodule work trees were never scanned for modifications. By using "--ignore-submodules=none" on the command line the status and diff commands can be told to do a full scan. This option can be set to the following values (which have the same name and meaning as for the "--ignore-submodules" option of status and diff): "all": All changes to the submodule will be ignored. "dirty": Only differences of the commit recorded in the superproject and the submodules HEAD will be considered modifications, all changes to the work tree of the submodule will be ignored. When using this value, the submodule will not be scanned for work tree changes at all, leading to a performance benefit on large submodules. "untracked": Only untracked files in the submodules work tree are ignored, a changed HEAD and/or modified files in the submodule will mark it as modified. "none" (which is the default): Either untracked or modified files in a submodules work tree or a difference between the subdmodules HEAD and the commit recorded in the superproject will make it show up as changed. This value is added as a new parameter for the "--ignore-submodules" option of the diff family and "git status" so the user can override the settings in the configuration. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
12 years ago
key = xstrfmt("submodule.%s.ignore", submodule->name);
config: fix leaks from git_config_get_string_const() There are two functions to get a single config string: - git_config_get_string() - git_config_get_string_const() One might naively think that the first one allocates a new string and the second one just points us to the internal configset storage. But in fact they both allocate a new copy; the second one exists only to avoid having to cast when using it with a const global which we never intend to free. The documentation for the function explains that clearly, but it seems I'm not alone in being surprised by this. Of 17 calls to the function, 13 of them leak the resulting value. We could obviously fix these by adding the appropriate free(). But it would be simpler still if we actually had a non-allocating way to get the string. There's git_config_get_value() but that doesn't quite do what we want. If the config key is present but is a boolean with no value (e.g., "[foo]bar" in the file), then we'll get NULL (whereas the string versions will print an error and die). So let's introduce a new variant, git_config_get_string_tmp(), that behaves as these callers expect. We need a new name because we have new semantics but the same function signature (so even if we converted the four remaining callers, topics in flight might be surprised). The "tmp" is because this value should only be held onto for a short time. In practice it's rare for us to clear and refresh the configset, invalidating the pointer, but hopefully the "tmp" makes callers think about the lifetime. In each of the converted cases here the value only needs to last within the local function or its immediate caller. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 years ago
if (repo_config_get_string_tmp(the_repository, key, &ignore))
ignore = submodule->ignore;
free(key);
if (ignore)
handle_ignore_submodules_arg(diffopt, ignore);
else if (is_gitmodules_unmerged(the_repository->index))
diff: make struct diff_flags members lowercase Now that the flags stored in struct diff_flags are being accessed directly and not through macros, change all struct members from being uppercase to lowercase. This conversion is done using the following semantic patch: @@ expression E; @@ - E.RECURSIVE + E.recursive @@ expression E; @@ - E.TREE_IN_RECURSIVE + E.tree_in_recursive @@ expression E; @@ - E.BINARY + E.binary @@ expression E; @@ - E.TEXT + E.text @@ expression E; @@ - E.FULL_INDEX + E.full_index @@ expression E; @@ - E.SILENT_ON_REMOVE + E.silent_on_remove @@ expression E; @@ - E.FIND_COPIES_HARDER + E.find_copies_harder @@ expression E; @@ - E.FOLLOW_RENAMES + E.follow_renames @@ expression E; @@ - E.RENAME_EMPTY + E.rename_empty @@ expression E; @@ - E.HAS_CHANGES + E.has_changes @@ expression E; @@ - E.QUICK + E.quick @@ expression E; @@ - E.NO_INDEX + E.no_index @@ expression E; @@ - E.ALLOW_EXTERNAL + E.allow_external @@ expression E; @@ - E.EXIT_WITH_STATUS + E.exit_with_status @@ expression E; @@ - E.REVERSE_DIFF + E.reverse_diff @@ expression E; @@ - E.CHECK_FAILED + E.check_failed @@ expression E; @@ - E.RELATIVE_NAME + E.relative_name @@ expression E; @@ - E.IGNORE_SUBMODULES + E.ignore_submodules @@ expression E; @@ - E.DIRSTAT_CUMULATIVE + E.dirstat_cumulative @@ expression E; @@ - E.DIRSTAT_BY_FILE + E.dirstat_by_file @@ expression E; @@ - E.ALLOW_TEXTCONV + E.allow_textconv @@ expression E; @@ - E.TEXTCONV_SET_VIA_CMDLINE + E.textconv_set_via_cmdline @@ expression E; @@ - E.DIFF_FROM_CONTENTS + E.diff_from_contents @@ expression E; @@ - E.DIRTY_SUBMODULES + E.dirty_submodules @@ expression E; @@ - E.IGNORE_UNTRACKED_IN_SUBMODULES + E.ignore_untracked_in_submodules @@ expression E; @@ - E.IGNORE_DIRTY_SUBMODULES + E.ignore_dirty_submodules @@ expression E; @@ - E.OVERRIDE_SUBMODULE_CONFIG + E.override_submodule_config @@ expression E; @@ - E.DIRSTAT_BY_LINE + E.dirstat_by_line @@ expression E; @@ - E.FUNCCONTEXT + E.funccontext @@ expression E; @@ - E.PICKAXE_IGNORE_CASE + E.pickaxe_ignore_case @@ expression E; @@ - E.DEFAULT_FOLLOW_RENAMES + E.default_follow_renames Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
5 years ago
diffopt->flags.ignore_submodules = 1;
}
}
/* Cheap function that only determines if we're interested in submodules at all */
int git_default_submodule_config(const char *var, const char *value, void *cb)
{
if (!strcmp(var, "submodule.recurse")) {
int v = git_config_bool(var, value) ?
RECURSE_SUBMODULES_ON : RECURSE_SUBMODULES_OFF;
config_update_recurse_submodules = v;
}
return 0;
submodule loading: separate code path for .gitmodules and config overlay The .gitmodules file is not supposed to have all the options available, that are available in the configuration so separate it out. A configuration option such as the hypothetical submodule.color.diff that determines in which color a submodule change is printed, is a very user specific thing, that the .gitmodules file should not tamper with. The .gitmodules file should only be used for settings that required to setup the project in which the .gitmodules file is tracked. As the minimum this would only include the name<->path mapping of the submodule and its URL and branch. Any further setting (such as 'fetch.recursesubmodules' or 'submodule.<name>.{update, ignore, shallow}') is not specific to the project setup requirements, but rather is a distribution of suggested developer configurations. In other areas of Git a suggested developer configuration is not transported in-tree but via other means. In an organisation this could be done by deploying an opinionated system wide config (/etc/gitconfig) or by putting the settings in the users home directory when they start at the organisation. In open source projects this is often accomplished via extensive READMEs (cf. our SubmittingPatches/CodingGuidlines). As a later patch in this series wants to introduce a generic submodule recursion option, we want to make sure that switch is not exposed via the gitmodules file. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
}
int option_parse_recurse_submodules_worktree_updater(const struct option *opt,
const char *arg, int unset)
{
if (unset) {
config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
return 0;
}
if (arg)
config_update_recurse_submodules =
parse_update_recurse_submodules_arg(opt->long_name,
arg);
else
config_update_recurse_submodules = RECURSE_SUBMODULES_ON;
return 0;
}
/*
* Determine if a submodule has been initialized at a given 'path'
*/
/*
* NEEDSWORK: Emit a warning if submodule.active exists, but is valueless,
* ie, the config looks like: "[submodule] active\n".
* Since that is an invalid pathspec, we should inform the user.
*/
branch: add --recurse-submodules option for branch creation To improve the submodules UX, we would like to teach Git to handle branches in submodules. Start this process by teaching "git branch" the --recurse-submodules option so that "git branch --recurse-submodules topic" will create the `topic` branch in the superproject and its submodules. Although this commit does not introduce breaking changes, it does not work well with existing --recurse-submodules commands because "git branch --recurse-submodules" writes to the submodule ref store, but most commands only consider the superproject gitlink and ignore the submodule ref store. For example, "git checkout --recurse-submodules" will check out the commits in the superproject gitlinks (and put the submodules in detached HEAD) instead of checking out the submodule branches. Because of this, this commit introduces a new configuration value, `submodule.propagateBranches`. The plan is for Git commands to prioritize submodule ref store information over superproject gitlinks if this value is true. Because "git branch --recurse-submodules" writes to submodule ref stores, for the sake of clarity, it will not function unless this configuration value is set. This commit also includes changes that support working with submodules from a superproject commit because "branch --recurse-submodules" (and future commands) need to read .gitmodules and gitlinks from the superproject commit, but submodules are typically read from the filesystem's .gitmodules and the index's gitlinks. These changes are: * add a submodules_of_tree() helper that gives the relevant information of an in-tree submodule (e.g. path and oid) and initializes the repository * add is_tree_submodule_active() by adding a treeish_name parameter to is_submodule_active() * add the "submoduleNotUpdated" advice to advise users to update the submodules in their trees Incidentally, fix an incorrect usage string that combined the 'list' usage of git branch (-l) with the 'create' usage; this string has been incorrect since its inception, a8dfd5eac4 (Make builtin-branch.c use parse_options., 2007-10-07). Helped-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Glen Choo <chooglen@google.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 months ago
int is_tree_submodule_active(struct repository *repo,
const struct object_id *treeish_name,
const char *path)
{
int ret = 0;
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
char *key = NULL;
char *value = NULL;
const struct string_list *sl;
const struct submodule *module;
branch: add --recurse-submodules option for branch creation To improve the submodules UX, we would like to teach Git to handle branches in submodules. Start this process by teaching "git branch" the --recurse-submodules option so that "git branch --recurse-submodules topic" will create the `topic` branch in the superproject and its submodules. Although this commit does not introduce breaking changes, it does not work well with existing --recurse-submodules commands because "git branch --recurse-submodules" writes to the submodule ref store, but most commands only consider the superproject gitlink and ignore the submodule ref store. For example, "git checkout --recurse-submodules" will check out the commits in the superproject gitlinks (and put the submodules in detached HEAD) instead of checking out the submodule branches. Because of this, this commit introduces a new configuration value, `submodule.propagateBranches`. The plan is for Git commands to prioritize submodule ref store information over superproject gitlinks if this value is true. Because "git branch --recurse-submodules" writes to submodule ref stores, for the sake of clarity, it will not function unless this configuration value is set. This commit also includes changes that support working with submodules from a superproject commit because "branch --recurse-submodules" (and future commands) need to read .gitmodules and gitlinks from the superproject commit, but submodules are typically read from the filesystem's .gitmodules and the index's gitlinks. These changes are: * add a submodules_of_tree() helper that gives the relevant information of an in-tree submodule (e.g. path and oid) and initializes the repository * add is_tree_submodule_active() by adding a treeish_name parameter to is_submodule_active() * add the "submoduleNotUpdated" advice to advise users to update the submodules in their trees Incidentally, fix an incorrect usage string that combined the 'list' usage of git branch (-l) with the 'create' usage; this string has been incorrect since its inception, a8dfd5eac4 (Make builtin-branch.c use parse_options., 2007-10-07). Helped-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Glen Choo <chooglen@google.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 months ago
module = submodule_from_path(repo, treeish_name, path);
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
/* early return if there isn't a path->module mapping */
if (!module)
return 0;
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
/* submodule.<name>.active is set */
key = xstrfmt("submodule.%s.active", module->name);
if (!repo_config_get_bool(repo, key, &ret)) {
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
free(key);
return ret;
}
free(key);
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
/* submodule.active is set */
sl = repo_config_get_value_multi(repo, "submodule.active");
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
if (sl) {
struct pathspec ps;
struct strvec args = STRVEC_INIT;
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
const struct string_list_item *item;
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
for_each_string_list_item(item, sl) {
strvec_push(&args, item->string);
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
}
parse_pathspec(&ps, 0, 0, NULL, args.v);
ret = match_pathspec(repo->index, &ps, path, strlen(path), 0, NULL, 1);
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
strvec_clear(&args);
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
clear_pathspec(&ps);
return ret;
}
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
/* fallback to checking if the URL is set */
key = xstrfmt("submodule.%s.url", module->name);
ret = !repo_config_get_string(repo, key, &value);
submodule: decouple url and submodule interest Currently the submodule.<name>.url config option is used to determine if a given submodule is of interest to the user. This ends up being cumbersome in a world where we want to have different submodules checked out in different worktrees or a more generalized mechanism to select which submodules are of interest. In a future with worktree support for submodules, there will be multiple working trees, each of which may only need a subset of the submodules checked out. The URL (which is where the submodule repository can be obtained) should not differ between different working trees. It may also be convenient for users to more easily specify groups of submodules they are interested in as opposed to running "git submodule init <path>" on each submodule they want checked out in their working tree. To this end two config options are introduced, submodule.active and submodule.<name>.active. The submodule.active config holds a pathspec that specifies which submodules should exist in the working tree. The submodule.<name>.active config is a boolean flag used to indicate if that particular submodule should exist in the working tree. Its important to note that submodule.active functions differently than the other configuration options since it takes a pathspec. This allows users to adopt at least two new workflows: 1. Submodules can be grouped with a leading directory, such that a pathspec e.g. 'lib/' would cover all library-ish modules to allow those who are interested in library-ish modules to set "submodule.active = lib/" just once to say any and all modules in 'lib/' are interesting. 2. Once the pathspec-attribute feature is invented, users can label submodules with attributes to group them, so that a broad pathspec with attribute requirements, e.g. ':(attr:lib)', can be used to say any and all modules with the 'lib' attribute are interesting. Since the .gitattributes file, just like the .gitmodules file, is tracked by the superproject, when a submodule moves in the superproject tree, the project can adjust which path gets the attribute in .gitattributes, just like it can adjust which path has the submodule in .gitmodules. Neither of these two additional configuration options solve the problem of wanting different submodules checked out in different worktrees because multiple worktrees share .git/config. Only once per-worktree configurations become a reality can this be solved, but this is a necessary preparatory step for that future. Given these multiple ways to check if a submodule is of interest, the more fine-grained submodule.<name>.active option has the highest order of precedence followed by the pathspec check against submodule.active. To ensure backwards compatibility, if neither of these options are set, git falls back to checking the submodule.<name>.url option to determine if a submodule is interesting. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
6 years ago
free(value);
free(key);
return ret;
}
branch: add --recurse-submodules option for branch creation To improve the submodules UX, we would like to teach Git to handle branches in submodules. Start this process by teaching "git branch" the --recurse-submodules option so that "git branch --recurse-submodules topic" will create the `topic` branch in the superproject and its submodules. Although this commit does not introduce breaking changes, it does not work well with existing --recurse-submodules commands because "git branch --recurse-submodules" writes to the submodule ref store, but most commands only consider the superproject gitlink and ignore the submodule ref store. For example, "git checkout --recurse-submodules" will check out the commits in the superproject gitlinks (and put the submodules in detached HEAD) instead of checking out the submodule branches. Because of this, this commit introduces a new configuration value, `submodule.propagateBranches`. The plan is for Git commands to prioritize submodule ref store information over superproject gitlinks if this value is true. Because "git branch --recurse-submodules" writes to submodule ref stores, for the sake of clarity, it will not function unless this configuration value is set. This commit also includes changes that support working with submodules from a superproject commit because "branch --recurse-submodules" (and future commands) need to read .gitmodules and gitlinks from the superproject commit, but submodules are typically read from the filesystem's .gitmodules and the index's gitlinks. These changes are: * add a submodules_of_tree() helper that gives the relevant information of an in-tree submodule (e.g. path and oid) and initializes the repository * add is_tree_submodule_active() by adding a treeish_name parameter to is_submodule_active() * add the "submoduleNotUpdated" advice to advise users to update the submodules in their trees Incidentally, fix an incorrect usage string that combined the 'list' usage of git branch (-l) with the 'create' usage; this string has been incorrect since its inception, a8dfd5eac4 (Make builtin-branch.c use parse_options., 2007-10-07). Helped-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Glen Choo <chooglen@google.com> Reviewed-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
10 months ago
int is_submodule_active(struct repository *repo, const char *path)
{
return is_tree_submodule_active(repo, null_oid(), path);
}
int is_submodule_populated_gently(const char *path, int *return_error_code)
{
int ret = 0;
char *gitdir = xstrfmt("%s/.git", path);
if (resolve_gitdir_gently(gitdir, return_error_code))
ret = 1;
free(gitdir);
return ret;
}
/*
* Dies if the provided 'prefix' corresponds to an unpopulated submodule
*/
void die_in_unpopulated_submodule(struct index_state *istate,
const char *prefix)
{
int i, prefixlen;
if (!prefix)
return;
prefixlen = strlen(prefix);
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
int ce_len = ce_namelen(ce);
if (!S_ISGITLINK(ce->ce_mode))
continue;
if (prefixlen <= ce_len)
continue;
if (strncmp(ce->name, prefix, ce_len))
continue;
if (prefix[ce_len] != '/')
continue;
die(_("in unpopulated submodule '%s'"), ce->name);
}
}
/*
* Dies if any paths in the provided pathspec descends into a submodule
*/
void die_path_inside_submodule(struct index_state *istate,
const struct pathspec *ps)
{
int i, j;
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
int ce_len = ce_namelen(ce);
if (!S_ISGITLINK(ce->ce_mode))
continue;
for (j = 0; j < ps->nr ; j++) {
const struct pathspec_item *item = &ps->items[j];
if (item->len <= ce_len)
continue;
if (item->match[ce_len] != '/')
continue;
if (strncmp(ce->name, item->match, ce_len))
continue;
if (item->len == ce_len + 1)
continue;
die(_("Pathspec '%s' is in submodule '%.*s'"),
item->original, ce_len, ce->name);
}
}
}
enum submodule_update_type parse_submodule_update_type(const char *value)
{
if (!strcmp(value, "none"))
return SM_UPDATE_NONE;
else if (!strcmp(value, "checkout"))
return SM_UPDATE_CHECKOUT;
else if (!strcmp(value, "rebase"))
return SM_UPDATE_REBASE;
else if (!strcmp(value, "merge"))
return SM_UPDATE_MERGE;
else if (*value == '!')
return SM_UPDATE_COMMAND;
else
return SM_UPDATE_UNSPECIFIED;
}
int parse_submodule_update_strategy(const char *value,
struct submodule_update_strategy *dst)
{
enum submodule_update_type type;
free((void*)dst->command);
dst->command = NULL;
type = parse_submodule_update_type(value);
if (type == SM_UPDATE_UNSPECIFIED)
return -1;
dst->type = type;
if (type == SM_UPDATE_COMMAND)
dst->command = xstrdup(value + 1);
return 0;
}
submodule: port init from shell to C By having the `submodule init` functionality in C, we can reference it easier from other parts in the code in later patches. The code is split up to have one function to initialize one submodule and a calling function that takes care of the rest, such as argument handling and translating the arguments to the paths of the submodules. This is the first submodule subcommand that is fully converted to C except for the usage string, so this is actually removing a call to the `submodule--helper list` function, which is supposed to be used in this transition. Instead we'll make a direct call to `module_list_compute`. An explanation why we need to edit the prefixes in cmd_update in git-submodule.sh in this patch: By having no processing in the shell part, we need to convey the notion of wt_prefix and prefix to the C parts, which former patches punted on and did the processing of displaying path in the shell. `wt_prefix` used to hold the path from the repository root to the current directory, e.g. wt_prefix would be t/ if the user invoked the `git submodule` command in ~/repo/t and ~repo is the GIT_DIR. `prefix` used to hold the relative path from the repository root to the operation, e.g. if you have recursive submodules, the shell script would modify the `prefix` in each recursive step by adding the submodule path. We will pass `wt_prefix` into the C helper via `git -C <dir>` as that will setup git in the directory the user actually called git-submodule.sh from. The `prefix` will be passed in via the `--prefix` option. Having `prefix` and `wt_prefix` relative to the GIT_DIR of the calling superproject is unfortunate with this patch as the C code doesn't know about a possible recursion from a superproject via `submodule update --init --recursive`. To fix this, we change the meaning of `wt_prefix` to point to the current project instead of the superproject and `prefix` to include any relative paths issues in the superproject. That way `prefix` will become the leading part for displaying paths and `wt_prefix` will be empty in recursive calls for now. The new notion of `wt_prefix` and `prefix` still allows us to reconstruct the calling directory in the superproject by just traveling reverse of `prefix`. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
7 years ago
const char *submodule_strategy_to_string(const struct submodule_update_strategy *s)
{
struct strbuf sb = STRBUF_INIT;
switch (s->type) {
case SM_UPDATE_CHECKOUT:
return "checkout";
case SM_UPDATE_MERGE:
return "merge";
case SM_UPDATE_REBASE:
return "rebase";
case SM_UPDATE_NONE:
return "none";
case SM_UPDATE_UNSPECIFIED:
return NULL;
case SM_UPDATE_COMMAND:
strbuf_addf(&sb, "!%s", s->command);
return strbuf_detach(&sb, NULL);
}
return NULL;
}
Add the option "--ignore-submodules" to "git status" In some use cases it is not desirable that "git status" considers submodules that only contain untracked content as dirty. This may happen e.g. when the submodule is not under the developers control and not all build generated files have been added to .gitignore by the upstream developers. Using the "untracked" parameter for the "--ignore-submodules" option disables checking for untracked content and lets git diff report them as changed only when they have new commits or modified content. Sometimes it is not wanted to have submodules show up as changed when they just contain changes to their work tree (this was the behavior before 1.7.0). An example for that are scripts which just want to check for submodule commits while ignoring any changes to the work tree. Also users having large submodules known not to change might want to use this option, as the - sometimes substantial - time it takes to scan the submodule work tree(s) is saved when using the "dirty" parameter. And if you want to ignore any changes to submodules, you can now do that by using this option without parameters or with "all" (when the config option status.submodulesummary is set, using "all" will also suppress the output of the submodule summary). A new function handle_ignore_submodules_arg() is introduced to parse this option new to "git status" in a single location, as "git diff" already knew it. Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>