Merge branch 'jc/clone'

* jc/clone:
  Move "no merge candidate" warning into git-pull
  Use preprocessor constants for environment variable names.
  Do not create $GIT_DIR/remotes/ directory anymore.
  Introduce GIT_TEMPLATE_DIR
  Revert "fix testsuite: make sure they use templates freshly built from the source"
  fix testsuite: make sure they use templates freshly built from the source
  git-clone: lose the traditional 'no-separate-remote' layout
  git-clone: lose the artificial "first" fetch refspec
  git-pull: refuse default merge without branch.*.merge
  git-clone: use wildcard specification for tracking branches
This commit is contained in:
Junio C Hamano 2006-12-20 13:56:14 -08:00
commit aa1cef54a2
13 changed files with 52 additions and 85 deletions

View file

@ -11,8 +11,7 @@ SYNOPSIS
[verse] [verse]
'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare] 'git-clone' [--template=<template_directory>] [-l [-s]] [-q] [-n] [--bare]
[-o <name>] [-u <upload-pack>] [--reference <repository>] [-o <name>] [-u <upload-pack>] [--reference <repository>]
[--use-separate-remote | --no-separate-remote] <repository> <repository> [<directory>]
[<directory>]
DESCRIPTION DESCRIPTION
----------- -----------
@ -99,18 +98,6 @@ OPTIONS
if unset the templates are taken from the installation if unset the templates are taken from the installation
defined default, typically `/usr/share/git-core/templates`. defined default, typically `/usr/share/git-core/templates`.
--use-separate-remote::
Save remotes heads under `$GIT_DIR/refs/remotes/origin/` instead
of `$GIT_DIR/refs/heads/`. Only the local master branch is
saved in the latter. This is the default.
--no-separate-remote::
Save remotes heads in the same namespace as the local
heads, `$GIT_DIR/refs/heads/'. In regular repositories,
this is a legacy setup git-clone created by default in
older Git versions, and will be removed before the next
major release.
<repository>:: <repository>::
The (possibly remote) repository to clone from. It can The (possibly remote) repository to clone from. It can
be any URL git-fetch supports. be any URL git-fetch supports.

View file

@ -124,8 +124,11 @@ static void copy_templates(const char *git_dir, int len, const char *template_di
int template_len; int template_len;
DIR *dir; DIR *dir;
if (!template_dir) if (!template_dir) {
template_dir = DEFAULT_GIT_TEMPLATE_DIR; template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);
if (!template_dir)
template_dir = DEFAULT_GIT_TEMPLATE_DIR;
}
strcpy(template_path, template_dir); strcpy(template_path, template_dir);
template_len = strlen(template_path); template_len = strlen(template_path);
if (template_path[template_len-1] != '/') { if (template_path[template_len-1] != '/') {

View file

@ -66,10 +66,10 @@ static int get_value(const char* key_, const char* regex_)
char *global = NULL, *repo_config = NULL; char *global = NULL, *repo_config = NULL;
const char *local; const char *local;
local = getenv("GIT_CONFIG"); local = getenv(CONFIG_ENVIRONMENT);
if (!local) { if (!local) {
const char *home = getenv("HOME"); const char *home = getenv("HOME");
local = getenv("GIT_CONFIG_LOCAL"); local = getenv(CONFIG_LOCAL_ENVIRONMENT);
if (!local) if (!local)
local = repo_config = xstrdup(git_path("config")); local = repo_config = xstrdup(git_path("config"));
if (home) if (home)

View file

@ -122,6 +122,10 @@ extern int cache_errno;
#define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY" #define DB_ENVIRONMENT "GIT_OBJECT_DIRECTORY"
#define INDEX_ENVIRONMENT "GIT_INDEX_FILE" #define INDEX_ENVIRONMENT "GIT_INDEX_FILE"
#define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE" #define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE"
#define TEMPLATE_DIR_ENVIRONMENT "GIT_TEMPLATE_DIR"
#define CONFIG_ENVIRONMENT "GIT_CONFIG"
#define CONFIG_LOCAL_ENVIRONMENT "GIT_CONFIG_LOCAL"
#define EXEC_PATH_ENVIRONMENT "GIT_EXEC_PATH"
extern int is_bare_git_dir(const char *dir); extern int is_bare_git_dir(const char *dir);
extern const char *get_git_dir(void); extern const char *get_git_dir(void);

View file

@ -349,10 +349,10 @@ int git_config(config_fn_t fn)
* $GIT_CONFIG_LOCAL will make it process it in addition to the * $GIT_CONFIG_LOCAL will make it process it in addition to the
* global config file, the same way it would the per-repository * global config file, the same way it would the per-repository
* config file otherwise. */ * config file otherwise. */
filename = getenv("GIT_CONFIG"); filename = getenv(CONFIG_ENVIRONMENT);
if (!filename) { if (!filename) {
home = getenv("HOME"); home = getenv("HOME");
filename = getenv("GIT_CONFIG_LOCAL"); filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
if (!filename) if (!filename)
filename = repo_config = xstrdup(git_path("config")); filename = repo_config = xstrdup(git_path("config"));
} }
@ -543,9 +543,9 @@ int git_config_set_multivar(const char* key, const char* value,
char* lock_file; char* lock_file;
const char* last_dot = strrchr(key, '.'); const char* last_dot = strrchr(key, '.');
config_filename = getenv("GIT_CONFIG"); config_filename = getenv(CONFIG_ENVIRONMENT);
if (!config_filename) { if (!config_filename) {
config_filename = getenv("GIT_CONFIG_LOCAL"); config_filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
if (!config_filename) if (!config_filename)
config_filename = git_path("config"); config_filename = git_path("config");
} }
@ -753,9 +753,9 @@ int git_config_rename_section(const char *old_name, const char *new_name)
int out_fd; int out_fd;
char buf[1024]; char buf[1024];
config_filename = getenv("GIT_CONFIG"); config_filename = getenv(CONFIG_ENVIRONMENT);
if (!config_filename) { if (!config_filename) {
config_filename = getenv("GIT_CONFIG_LOCAL"); config_filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
if (!config_filename) if (!config_filename)
config_filename = git_path("config"); config_filename = git_path("config");
} }

View file

@ -21,7 +21,7 @@ const char *git_exec_path(void)
if (current_exec_path) if (current_exec_path)
return current_exec_path; return current_exec_path;
env = getenv("GIT_EXEC_PATH"); env = getenv(EXEC_PATH_ENVIRONMENT);
if (env && *env) { if (env && *env) {
return env; return env;
} }
@ -35,7 +35,7 @@ int execv_git_cmd(const char **argv)
char git_command[PATH_MAX + 1]; char git_command[PATH_MAX + 1];
int i; int i;
const char *paths[] = { current_exec_path, const char *paths[] = { current_exec_path,
getenv("GIT_EXEC_PATH"), getenv(EXEC_PATH_ENVIRONMENT),
builtin_exec_path }; builtin_exec_path };
for (i = 0; i < ARRAY_SIZE(paths); ++i) { for (i = 0; i < ARRAY_SIZE(paths); ++i) {

View file

@ -14,7 +14,7 @@ die() {
} }
usage() { usage() {
die "Usage: $0 [--template=<template_directory>] [--no-separate-remote] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [-n] <repo> [<dir>]" die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [-n] <repo> [<dir>]"
} }
get_repo_base() { get_repo_base() {
@ -137,11 +137,9 @@ while
*,--template=*) *,--template=*)
template="$1" ;; template="$1" ;;
*,-q|*,--quiet) quiet=-q ;; *,-q|*,--quiet) quiet=-q ;;
*,--use-separate-remote) *,--use-separate-remote) ;;
# default
use_separate_remote=t ;;
*,--no-separate-remote) *,--no-separate-remote)
use_separate_remote= ;; die "clones are always made with separate-remote layout" ;;
1,--reference) usage ;; 1,--reference) usage ;;
*,--reference) *,--reference)
shift; reference="$1" ;; shift; reference="$1" ;;
@ -327,12 +325,8 @@ cd "$D" || exit
if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD" if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD"
then then
# Figure out which remote branch HEAD points at. # a non-bare repository is always in separate-remote layout
case "$use_separate_remote" in remote_top="refs/remotes/$origin"
'') remote_top=refs/heads ;;
*) remote_top="refs/remotes/$origin" ;;
esac
head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"` head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
case "$head_sha1" in case "$head_sha1" in
'ref: refs/'*) 'ref: refs/'*)
@ -366,41 +360,26 @@ then
) )
) )
# Write out remotes/$origin file, and update our "$head_points_at". # Write out remote.$origin config, and update our "$head_points_at".
case "$head_points_at" in case "$head_points_at" in
?*) ?*)
mkdir -p "$GIT_DIR/remotes" && # Local default branch
git-symbolic-ref HEAD "refs/heads/$head_points_at" && git-symbolic-ref HEAD "refs/heads/$head_points_at" &&
case "$use_separate_remote" in
t) origin_track="$remote_top/$head_points_at" # Tracking branch for the primary branch at the remote.
git-update-ref HEAD "$head_sha1" ;; origin_track="$remote_top/$head_points_at" &&
*) origin_track="$remote_top/$origin" git-update-ref HEAD "$head_sha1" &&
git-update-ref "refs/heads/$origin" "$head_sha1" ;;
esac && # Upstream URL
git-repo-config remote."$origin".url "$repo" && git-repo-config remote."$origin".url "$repo" &&
# Set up the mappings to track the remote branches.
git-repo-config remote."$origin".fetch \ git-repo-config remote."$origin".fetch \
"refs/heads/$head_points_at:$origin_track" && "refs/heads/*:$remote_top/*" '^$' &&
(cd "$GIT_DIR/$remote_top" && find . -type f -print) | rm -f "refs/remotes/$origin/HEAD"
while read dotslref git-symbolic-ref "refs/remotes/$origin/HEAD" \
do "refs/remotes/$origin/$head_points_at" &&
name=`expr "$dotslref" : './\(.*\)'`
if test "z$head_points_at" = "z$name"
then
continue
fi
if test "$use_separate_remote" = '' &&
test "z$origin" = "z$name"
then
continue
fi
git-repo-config remote."$origin".fetch "refs/heads/${name}:$remote_top/${name}" '^$'
done &&
case "$use_separate_remote" in
t)
rm -f "refs/remotes/$origin/HEAD"
git-symbolic-ref "refs/remotes/$origin/HEAD" \
"refs/remotes/$origin/$head_points_at"
esac &&
git-repo-config branch."$head_points_at".remote "$origin" && git-repo-config branch."$head_points_at".remote "$origin" &&
git-repo-config branch."$head_points_at".merge "refs/heads/$head_points_at" git-repo-config branch."$head_points_at".merge "refs/heads/$head_points_at"
esac esac

View file

@ -132,7 +132,6 @@ canon_refs_list_for_fetch () {
# or the first one otherwise; add prefix . to the rest # or the first one otherwise; add prefix . to the rest
# to prevent the secondary branches to be merged by default. # to prevent the secondary branches to be merged by default.
merge_branches= merge_branches=
found_mergeref=
curr_branch= curr_branch=
if test "$1" = "-d" if test "$1" = "-d"
then then
@ -142,7 +141,8 @@ canon_refs_list_for_fetch () {
curr_branch=$(git-symbolic-ref HEAD | \ curr_branch=$(git-symbolic-ref HEAD | \
sed -e 's|^refs/heads/||') sed -e 's|^refs/heads/||')
merge_branches=$(git-repo-config \ merge_branches=$(git-repo-config \
--get-all "branch.${curr_branch}.merge") --get-all "branch.${curr_branch}.merge") ||
merge_branches=.this.would.never.match.any.ref.
fi fi
set x $(expand_refs_wildcard "$@") set x $(expand_refs_wildcard "$@")
shift shift
@ -171,10 +171,6 @@ canon_refs_list_for_fetch () {
dot_prefix= && break dot_prefix= && break
done done
fi fi
if test -z $dot_prefix
then
found_mergeref=true
fi
case "$remote" in case "$remote" in
'') remote=HEAD ;; '') remote=HEAD ;;
refs/heads/* | refs/tags/* | refs/remotes/*) ;; refs/heads/* | refs/tags/* | refs/remotes/*) ;;
@ -195,11 +191,6 @@ canon_refs_list_for_fetch () {
fi fi
echo "${dot_prefix}${force}${remote}:${local}" echo "${dot_prefix}${force}${remote}:${local}"
done done
if test -z "$found_mergeref" -a "$curr_branch"
then
echo >&2 "Warning: No merge candidate found because value of config option
\"branch.${curr_branch}.merge\" does not match any remote branch fetched."
fi
} }
# Returns list of src: (no store), or src:dst (store) # Returns list of src: (no store), or src:dst (store)

View file

@ -76,6 +76,10 @@ merge_head=$(sed -e '/ not-for-merge /d' \
case "$merge_head" in case "$merge_head" in
'') '')
curr_branch=$(git-symbolic-ref HEAD | \
sed -e 's|^refs/heads/||')
echo >&2 "Warning: No merge candidate found because value of config option
\"branch.${curr_branch}.merge\" does not match any remote branch fetched."
echo >&2 "No changes." echo >&2 "No changes."
exit 0 exit 0
;; ;;

View file

@ -1272,7 +1272,7 @@ int main(int argc, char *argv[])
struct commit *result, *h1, *h2; struct commit *result, *h1, *h2;
git_config(git_default_config); /* core.filemode */ git_config(git_default_config); /* core.filemode */
original_index_file = getenv("GIT_INDEX_FILE"); original_index_file = getenv(INDEX_ENVIRONMENT);
if (!original_index_file) if (!original_index_file)
original_index_file = xstrdup(git_path("index")); original_index_file = xstrdup(git_path("index"));

View file

@ -23,15 +23,14 @@ test_expect_success "clone and setup child repos" '
git clone . two && git clone . two &&
cd two && cd two &&
git repo-config branch.master.remote one && git repo-config branch.master.remote one &&
{ git repo-config remote.one.url ../one/.git/ &&
echo "URL: ../one/.git/" git repo-config remote.one.fetch refs/heads/master:refs/heads/one &&
echo "Pull: refs/heads/master:refs/heads/one"
} >.git/remotes/one
cd .. && cd .. &&
git clone . three && git clone . three &&
cd three && cd three &&
git repo-config branch.master.remote two && git repo-config branch.master.remote two &&
git repo-config branch.master.merge refs/heads/one && git repo-config branch.master.merge refs/heads/one &&
mkdir -p .git/remotes &&
{ {
echo "URL: ../two/.git/" echo "URL: ../two/.git/"
echo "Pull: refs/heads/master:refs/heads/two" echo "Pull: refs/heads/master:refs/heads/two"

View file

@ -208,8 +208,9 @@ test_done () {
# t/ subdirectory and are run in trash subdirectory. # t/ subdirectory and are run in trash subdirectory.
PATH=$(pwd)/..:$PATH PATH=$(pwd)/..:$PATH
GIT_EXEC_PATH=$(pwd)/.. GIT_EXEC_PATH=$(pwd)/..
GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
HOME=$(pwd)/trash HOME=$(pwd)/trash
export PATH GIT_EXEC_PATH HOME export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR HOME
GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git
export GITPERLLIB export GITPERLLIB

View file

@ -1 +0,0 @@
: this is just to ensure the directory exists.