From: Junio C Hamano Date: Sun, 7 Mar 2010 20:47:17 +0000 (-0800) Subject: Merge branch 'gb/maint-submodule-env' X-Git-Tag: v1.7.1-rc0~83 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/9317dc4f051452a0e0f7a62a5531b16adf36b553?hp=-c Merge branch 'gb/maint-submodule-env' * 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 --- 9317dc4f051452a0e0f7a62a5531b16adf36b553 diff --combined Documentation/git-rev-parse.txt index 1a613aa108,33092a3373..8db600f6ba --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@@ -101,14 -101,15 +101,14 @@@ OPTION abbreviation mode. --all:: - Show all refs found in `$GIT_DIR/refs`. + Show all refs found in `refs/`. --branches[=pattern]:: --tags[=pattern]:: --remotes[=pattern]:: Show all branches, tags, or remote-tracking branches, - respectively (i.e., refs found in `$GIT_DIR/refs/heads`, - `$GIT_DIR/refs/tags`, or `$GIT_DIR/refs/remotes`, - respectively). + respectively (i.e., refs found in `refs/heads`, + `refs/tags`, or `refs/remotes`, respectively). + If a `pattern` is given, only refs matching the given shell glob are shown. If the pattern does not contain a globbing character (`?`, @@@ -148,6 -149,12 +148,12 @@@ --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 @@@ -188,7 -195,7 +194,7 @@@ blobs contained in a commit `g`, and an abbreviated object name. * A symbolic ref name. E.g. 'master' typically means the commit - object referenced by $GIT_DIR/refs/heads/master. If you + object referenced by refs/heads/master. If you happen to have both heads/master and tags/master, you can explicitly say 'heads/master' to tell git which one you mean. When ambiguous, a `` is disambiguated by taking the @@@ -197,15 -204,15 +203,15 @@@ . if `$GIT_DIR/` exists, that is what you mean (this is usually useful only for `HEAD`, `FETCH_HEAD`, `ORIG_HEAD` and `MERGE_HEAD`); - . otherwise, `$GIT_DIR/refs/` if exists; + . otherwise, `refs/` if exists; - . otherwise, `$GIT_DIR/refs/tags/` if exists; + . otherwise, `refs/tags/` if exists; - . otherwise, `$GIT_DIR/refs/heads/` if exists; + . otherwise, `refs/heads/` if exists; - . otherwise, `$GIT_DIR/refs/remotes/` if exists; + . otherwise, `refs/remotes/` if exists; - . otherwise, `$GIT_DIR/refs/remotes//HEAD` if exists. + . otherwise, `refs/remotes//HEAD` if exists. + HEAD names the commit your changes in the working tree is based on. FETCH_HEAD records the branch you fetched from a remote repository @@@ -216,9 -223,6 +222,9 @@@ you can change the tip of the branch ba them easily. MERGE_HEAD records the commit(s) you are merging into your branch when you run 'git merge'. ++ +Note that any of the `refs/*` cases above may come either from +the `$GIT_DIR/refs` directory or from the `$GIT_DIR/packed-refs` file. * A ref followed by the suffix '@' with a date specification enclosed in a brace diff --combined builtin-rev-parse.c index 88bad9af3c,b76f205e62..8fbf9d0db6 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@@ -455,6 -455,13 +455,13 @@@ int cmd_rev_parse(int argc, const char 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); @@@ -637,7 -644,6 +644,7 @@@ if (!strcmp(arg, "--git-dir")) { const char *gitdir = getenv(GIT_DIR_ENVIRONMENT); static char cwd[PATH_MAX]; + int len; if (gitdir) { puts(gitdir); continue; @@@ -648,8 -654,7 +655,8 @@@ } if (!getcwd(cwd, PATH_MAX)) die_errno("unable to get current working directory"); - printf("%s/.git\n", cwd); + len = strlen(cwd); + printf("%s%s.git\n", cwd, len && cwd[len-1] != '/' ? "/" : ""); continue; } if (!strcmp(arg, "--is-inside-git-dir")) { diff --combined cache.h index c286310ded,58209adbd6..89f6a40d1a --- a/cache.h +++ b/cache.h @@@ -388,6 -388,15 +388,15 @@@ static inline enum object_type object_t #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); @@@ -641,10 -650,6 +650,10 @@@ int git_mkstemp(char *path, size_t n, c int git_mkstemps(char *path, size_t n, const char *template, int suffix_len); +/* set default permissions by passing mode arguments to open(2) */ +int git_mkstemps_mode(char *pattern, int suffix_len, int mode); +int git_mkstemp_mode(char *pattern, int mode); + /* * NOTE NOTE NOTE!! * @@@ -679,7 -684,6 +688,7 @@@ int normalize_path_copy(char *dst, cons int longest_ancestor_length(const char *path, const char *prefix_list); char *strip_path_suffix(const char *path, const char *suffix); int daemon_avoid_alias(const char *path); +int offset_1st_component(const char *path); /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ extern int sha1_object_info(const unsigned char *, unsigned long *); @@@ -780,7 -784,7 +789,7 @@@ extern const char *git_committer_info(i extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int); extern const char *fmt_name(const char *name, const char *email); extern const char *git_editor(void); -extern const char *git_pager(void); +extern const char *git_pager(int stdout_is_tty); struct checkout { const char *base_dir; diff --combined connect.c index 9f39038f6f,24ce2fc70e..323a771b69 --- a/connect.c +++ b/connect.c @@@ -152,28 -152,6 +152,28 @@@ static enum protocol get_protocol(cons #define STR_(s) # s #define STR(s) STR_(s) +static void get_host_and_port(char **host, const char **port) +{ + char *colon, *end; + + if (*host[0] == '[') { + end = strchr(*host + 1, ']'); + if (end) { + *end = 0; + end++; + (*host)++; + } else + end = *host; + } else + end = *host; + colon = strchr(end, ':'); + + if (colon) { + *colon = 0; + *port = colon + 1; + } +} + #ifndef NO_IPV6 static const char *ai_name(const struct addrinfo *ai) @@@ -192,14 -170,30 +192,14 @@@ static int git_tcp_connect_sock(char *host, int flags) { int sockfd = -1, saved_errno = 0; - char *colon, *end; const char *port = STR(DEFAULT_GIT_PORT); struct addrinfo hints, *ai0, *ai; int gai; int cnt = 0; - if (host[0] == '[') { - end = strchr(host + 1, ']'); - if (end) { - *end = 0; - end++; - host++; - } else - end = host; - } else - end = host; - colon = strchr(end, ':'); - - if (colon) { - *colon = 0; - port = colon + 1; - if (!*port) - port = ""; - } + get_host_and_port(&host, &port); + if (!*port) + port = ""; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; @@@ -257,15 -251,30 +257,15 @@@ static int git_tcp_connect_sock(char *host, int flags) { int sockfd = -1, saved_errno = 0; - char *colon, *end; - char *port = STR(DEFAULT_GIT_PORT), *ep; + const char *port = STR(DEFAULT_GIT_PORT); + char *ep; struct hostent *he; struct sockaddr_in sa; char **ap; unsigned int nport; int cnt; - if (host[0] == '[') { - end = strchr(host + 1, ']'); - if (end) { - *end = 0; - end++; - host++; - } else - end = host; - } else - end = host; - colon = strchr(end, ':'); - - if (colon) { - *colon = 0; - port = colon + 1; - } + get_host_and_port(&host, &port); if (flags & CONNECT_VERBOSE) fprintf(stderr, "Looking up %s ... ", host); @@@ -397,10 -406,26 +397,10 @@@ static int git_use_proxy(const char *ho static void git_proxy_connect(int fd[2], char *host) { const char *port = STR(DEFAULT_GIT_PORT); - char *colon, *end; const char *argv[4]; struct child_process proxy; - if (host[0] == '[') { - end = strchr(host + 1, ']'); - if (end) { - *end = 0; - end++; - host++; - } else - end = host; - } else - end = host; - colon = strchr(end, ':'); - - if (colon) { - *colon = 0; - port = colon + 1; - } + get_host_and_port(&host, &port); argv[0] = git_proxy_command; argv[1] = host; @@@ -479,7 -504,7 +479,7 @@@ struct child_process *git_connect(int f /* * Don't do destructive transforms with git:// as that - * protocol code does '[]' dewrapping of its own. + * protocol code does '[]' unwrapping of its own. */ if (host[0] == '[') { end = strchr(host + 1, ']'); @@@ -582,18 -607,8 +582,8 @@@ *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; diff --combined git-sh-setup.sh index 7a095665d7,cf864a6273..6131670860 mode 100644,100755..100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@@ -107,19 -107,6 +107,19 @@@ git_editor() eval "$GIT_EDITOR" '"$@"' } +git_pager() { + if test -t 1 + then + GIT_PAGER=$(git var GIT_PAGER) + else + GIT_PAGER=cat + fi + : ${LESS=-FRSX} + export LESS + + eval "$GIT_PAGER" '"$@"' +} + sane_grep () { GREP_OPTIONS= LC_ALL=C grep "$@" } @@@ -141,7 -128,7 +141,7 @@@ cd_to_toplevel () } require_work_tree () { - test $(git rev-parse --is-inside-work-tree) = true || + test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || die "fatal: $0 cannot be used without a working tree." } @@@ -172,6 -159,13 +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" diff --combined git-submodule.sh index 383dc45119,e2082fd149..f21d0bfce7 --- a/git-submodule.sh +++ b/git-submodule.sh @@@ -222,7 -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 @@@ -278,7 -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" @@@ -434,7 -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 @@@ -454,7 -454,7 +454,7 @@@ 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 @@@ -477,14 -477,14 +477,14 @@@ ;; 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 @@@ -492,7 -492,7 +492,7 @@@ 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 || @@@ -553,15 -553,12 +553,15 @@@ cmd_summary() test $summary_limit = 0 && return - if rev=$(git rev-parse -q --verify "$1^0") + if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"}) then head=$rev - shift + test $# = 0 || shift + elif test -z "$1" -o "$1" = "HEAD" + then + return else - head=HEAD + head="HEAD" fi if [ -n "$files" ] @@@ -760,7 -757,7 +760,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" @@@ -770,7 -767,7 +770,7 @@@ then ( prefix="$displaypath/" - unset GIT_DIR + clear_local_git_env cd "$path" && cmd_status $orig_args ) || @@@ -821,7 -818,7 +821,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'"