Skip to content

Commit

Permalink
Merge branch 'gb/maint-submodule-env' into maint
Browse files Browse the repository at this point in the history
* gb/maint-submodule-env:
  is_submodule_modified(): clear environment properly
  submodules: ensure clean environment when operating in a submodule
  shell setup: clear_local_git_env() function
  rev-parse: --local-env-vars option
  Refactor list of of repo-local env vars
  • Loading branch information
gitster committed Mar 8, 2010
2 parents 030bc0a + 5ce9086 commit bd08ecc
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 33 deletions.
6 changes: 6 additions & 0 deletions Documentation/git-rev-parse.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,12 @@ shown. If the pattern does not contain a globbing character (`?`,
--is-bare-repository::
When the repository is bare print "true", otherwise "false".

--local-env-vars::
List the GIT_* environment variables that are local to the
repository (e.g. GIT_DIR or GIT_WORK_TREE, but not GIT_EDITOR).
Only the names of the variables are listed, not their value,
even if they are set.

--short::
--short=number::
Instead of outputting the full SHA1 values of object names try to
Expand Down
7 changes: 7 additions & 0 deletions builtin-rev-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,13 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
if (argc > 1 && !strcmp("--sq-quote", argv[1]))
return cmd_sq_quote(argc - 2, argv + 2);

if (argc == 2 && !strcmp("--local-env-vars", argv[1])) {
int i;
for (i = 0; local_repo_env[i]; i++)
printf("%s\n", local_repo_env[i]);
return 0;
}

if (argc > 1 && !strcmp("-h", argv[1]))
usage(builtin_rev_parse_usage);

Expand Down
9 changes: 9 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,15 @@ static inline enum object_type object_type(unsigned int mode)
#define GIT_NOTES_REF_ENVIRONMENT "GIT_NOTES_REF"
#define GIT_NOTES_DEFAULT_REF "refs/notes/commits"

/*
* Repository-local GIT_* environment variables
* The array is NULL-terminated to simplify its usage in contexts such
* environment creation or simple walk of the list.
* The number of non-NULL entries is available as a macro.
*/
#define LOCAL_REPO_ENV_SIZE 8
extern const char *const local_repo_env[LOCAL_REPO_ENV_SIZE + 1];

extern int is_bare_repository_cfg;
extern int is_bare_repository(void);
extern int is_inside_git_dir(void);
Expand Down
14 changes: 2 additions & 12 deletions connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,18 +607,8 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
*arg++ = host;
}
else {
/* remove these from the environment */
const char *env[] = {
ALTERNATE_DB_ENVIRONMENT,
DB_ENVIRONMENT,
GIT_DIR_ENVIRONMENT,
GIT_WORK_TREE_ENVIRONMENT,
GRAFT_ENVIRONMENT,
INDEX_ENVIRONMENT,
NO_REPLACE_OBJECTS_ENVIRONMENT,
NULL
};
conn->env = env;
/* remove repo-local variables from the environment */
conn->env = local_repo_env;
conn->use_shell = 1;
}
*arg++ = cmd.buf;
Expand Down
17 changes: 17 additions & 0 deletions environment.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ static char *work_tree;
static const char *git_dir;
static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;

/*
* Repository-local GIT_* environment variables
* Remember to update local_repo_env_size in cache.h when
* the size of the list changes
*/
const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
ALTERNATE_DB_ENVIRONMENT,
CONFIG_ENVIRONMENT,
DB_ENVIRONMENT,
GIT_DIR_ENVIRONMENT,
GIT_WORK_TREE_ENVIRONMENT,
GRAFT_ENVIRONMENT,
INDEX_ENVIRONMENT,
NO_REPLACE_OBJECTS_ENVIRONMENT,
NULL
};

static void setup_git_env(void)
{
git_dir = getenv(GIT_DIR_ENVIRONMENT);
Expand Down
7 changes: 7 additions & 0 deletions git-sh-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ get_author_ident_from_commit () {
LANG=C LC_ALL=C sed -ne "$pick_author_script"
}
# Clear repo-local GIT_* environment variables. Useful when switching to
# another repository (e.g. when entering a submodule). See also the env
# list in git_connect()
clear_local_git_env() {
unset $(git rev-parse --local-env-vars)
}
# Make sure we are in a valid repository of a vintage we understand,
# if we require to be in a git repository.
if test -z "$NONGIT_OK"
Expand Down
20 changes: 10 additions & 10 deletions git-submodule.sh
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ cmd_add()

module_clone "$path" "$realrepo" "$reference" || exit
(
unset GIT_DIR
clear_local_git_env
cd "$path" &&
# ash fails to wordsplit ${branch:+-b "$branch"...}
case "$branch" in
Expand Down Expand Up @@ -278,7 +278,7 @@ cmd_foreach()
name=$(module_name "$path")
(
prefix="$prefix$path/"
unset GIT_DIR
clear_local_git_env
cd "$path" &&
eval "$@" &&
if test -n "$recursive"
Expand Down Expand Up @@ -434,7 +434,7 @@ cmd_update()
module_clone "$path" "$url" "$reference"|| exit
subsha1=
else
subsha1=$(unset GIT_DIR; cd "$path" &&
subsha1=$(clear_local_git_env; cd "$path" &&
git rev-parse --verify HEAD) ||
die "Unable to find current revision in submodule path '$path'"
fi
Expand All @@ -454,7 +454,7 @@ cmd_update()

if test -z "$nofetch"
then
(unset GIT_DIR; cd "$path" &&
(clear_local_git_env; cd "$path" &&
git-fetch) ||
die "Unable to fetch in submodule path '$path'"
fi
Expand All @@ -477,22 +477,22 @@ cmd_update()
;;
esac

(unset GIT_DIR; cd "$path" && $command "$sha1") ||
(clear_local_git_env; cd "$path" && $command "$sha1") ||
die "Unable to $action '$sha1' in submodule path '$path'"
say "Submodule path '$path': $msg '$sha1'"
fi

if test -n "$recursive"
then
(unset GIT_DIR; cd "$path" && cmd_update $orig_args) ||
(clear_local_git_env; cd "$path" && cmd_update $orig_args) ||
die "Failed to recurse into submodule path '$path'"
fi
done
}

set_name_rev () {
revname=$( (
unset GIT_DIR
clear_local_git_env
cd "$1" && {
git describe "$2" 2>/dev/null ||
git describe --tags "$2" 2>/dev/null ||
Expand Down Expand Up @@ -757,7 +757,7 @@ cmd_status()
else
if test -z "$cached"
then
sha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD)
sha1=$(clear_local_git_env; cd "$path" && git rev-parse --verify HEAD)
set_name_rev "$path" "$sha1"
fi
say "+$sha1 $displaypath$revname"
Expand All @@ -767,7 +767,7 @@ cmd_status()
then
(
prefix="$displaypath/"
unset GIT_DIR
clear_local_git_env
cd "$path" &&
cmd_status $orig_args
) ||
Expand Down Expand Up @@ -818,7 +818,7 @@ cmd_sync()
if test -e "$path"/.git
then
(
unset GIT_DIR
clear_local_git_env
cd "$path"
remote=$(get_default_remote)
say "Synchronizing submodule url for '$name'"
Expand Down
22 changes: 11 additions & 11 deletions submodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,19 @@ void show_submodule_summary(FILE *f, const char *path,

int is_submodule_modified(const char *path)
{
int len;
int len, i;
struct child_process cp;
const char *argv[] = {
"status",
"--porcelain",
NULL,
};
char *env[4];
const char *env[LOCAL_REPO_ENV_SIZE + 3];
struct strbuf buf = STRBUF_INIT;

for (i = 0; i < LOCAL_REPO_ENV_SIZE; i++)
env[i] = local_repo_env[i];

strbuf_addf(&buf, "%s/.git/", path);
if (!is_directory(buf.buf)) {
strbuf_release(&buf);
Expand All @@ -143,16 +146,14 @@ int is_submodule_modified(const char *path)
strbuf_reset(&buf);

strbuf_addf(&buf, "GIT_WORK_TREE=%s", path);
env[0] = strbuf_detach(&buf, NULL);
env[i++] = strbuf_detach(&buf, NULL);
strbuf_addf(&buf, "GIT_DIR=%s/.git", path);
env[1] = strbuf_detach(&buf, NULL);
strbuf_addf(&buf, "GIT_INDEX_FILE");
env[2] = strbuf_detach(&buf, NULL);
env[3] = NULL;
env[i++] = strbuf_detach(&buf, NULL);
env[i] = NULL;

memset(&cp, 0, sizeof(cp));
cp.argv = argv;
cp.env = (const char *const *)env;
cp.env = env;
cp.git_cmd = 1;
cp.no_stdin = 1;
cp.out = -1;
Expand All @@ -165,9 +166,8 @@ int is_submodule_modified(const char *path)
if (finish_command(&cp))
die("git status --porcelain failed");

free(env[0]);
free(env[1]);
free(env[2]);
for (i = LOCAL_REPO_ENV_SIZE; env[i]; i++)
free((char *)env[i]);
strbuf_release(&buf);
return len != 0;
}

0 comments on commit bd08ecc

Please sign in to comment.