Browse Source

Merge branch 'js/init-defaultbranch-advice'

Our users are going to be trained to prepare for future change of
init.defaultBranch configuration variable.

* js/init-defaultbranch-advice:
  init: provide useful advice about init.defaultBranch
  get_default_branch_name(): prepare for showing some advice
  branch -m: allow renaming a yet-unborn branch
  init: document `init.defaultBranch` better
maint
Junio C Hamano 4 years ago
parent
commit
772bdcd429
  1. 11
      Documentation/git-init.txt
  2. 4
      builtin/branch.c
  3. 2
      builtin/clone.c
  4. 8
      builtin/init-db.c
  5. 24
      refs.c
  6. 4
      refs.h
  7. 5
      remote.c
  8. 17
      t/t0001-init.sh
  9. 2
      t/t1510-repo-setup.sh
  10. 4
      t/test-lib-functions.sh

11
Documentation/git-init.txt

@ -20,8 +20,9 @@ DESCRIPTION @@ -20,8 +20,9 @@ DESCRIPTION

This command creates an empty Git repository - basically a `.git`
directory with subdirectories for `objects`, `refs/heads`,
`refs/tags`, and template files. An initial `HEAD` file that
references the HEAD of the master branch is also created.
`refs/tags`, and template files. An initial branch without any
commits will be created (see the `--initial-branch` option below
for its name).

If the `$GIT_DIR` environment variable is set then it specifies a path
to use instead of `./.git` for the base of the repository.
@ -73,8 +74,10 @@ If this is reinitialization, the repository will be moved to the specified path. @@ -73,8 +74,10 @@ If this is reinitialization, the repository will be moved to the specified path.
-b <branch-name>::
--initial-branch=<branch-name>::

Use the specified name for the initial branch in the newly created repository.
If not specified, fall back to the default name: `master`.
Use the specified name for the initial branch in the newly created
repository. If not specified, fall back to the default name (currently
`master`, but this is subject to change in the future; the name can be
customized via the `init.defaultBranch` configuration variable).

--shared[=(false|true|umask|group|all|world|everybody|0xxx)]::


4
builtin/branch.c

@ -538,7 +538,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int @@ -538,7 +538,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
strbuf_addf(&logmsg, "Branch: renamed %s to %s",
oldref.buf, newref.buf);

if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
if (!copy &&
(!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) &&
rename_ref(oldref.buf, newref.buf, logmsg.buf))
die(_("Branch rename failed"));
if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
die(_("Branch copy failed"));

2
builtin/clone.c

@ -1326,7 +1326,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix) @@ -1326,7 +1326,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
remote_head = NULL;
option_no_checkout = 1;
if (!option_bare) {
const char *branch = git_default_branch_name();
const char *branch = git_default_branch_name(0);
char *ref = xstrfmt("refs/heads/%s", branch);

install_branch_config(0, branch, remote_name, ref);

8
builtin/init-db.c

@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit) @@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit)
static int create_default_files(const char *template_path,
const char *original_git_dir,
const char *initial_branch,
const struct repository_format *fmt)
const struct repository_format *fmt,
int quiet)
{
struct stat st1;
struct strbuf buf = STRBUF_INIT;
@ -267,7 +268,7 @@ static int create_default_files(const char *template_path, @@ -267,7 +268,7 @@ static int create_default_files(const char *template_path,
char *ref;

if (!initial_branch)
initial_branch = git_default_branch_name();
initial_branch = git_default_branch_name(quiet);

ref = xstrfmt("refs/heads/%s", initial_branch);
if (check_refname_format(ref, 0) < 0)
@ -438,7 +439,8 @@ int init_db(const char *git_dir, const char *real_git_dir, @@ -438,7 +439,8 @@ int init_db(const char *git_dir, const char *real_git_dir,
validate_hash_algorithm(&repo_fmt, hash);

reinit = create_default_files(template_dir, original_git_dir,
initial_branch, &repo_fmt);
initial_branch, &repo_fmt,
flags & INIT_DB_QUIET);
if (reinit && initial_branch)
warning(_("re-init: ignored --initial-branch=%s"),
initial_branch);

24
refs.c

@ -562,7 +562,20 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix) @@ -562,7 +562,20 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
strvec_pushf(prefixes, *p, len, prefix);
}

char *repo_default_branch_name(struct repository *r)
static const char default_branch_name_advice[] = N_(
"Using '%s' as the name for the initial branch. This default branch name\n"
"is subject to change. To configure the initial branch name to use in all\n"
"of your new repositories, which will suppress this warning, call:\n"
"\n"
"\tgit config --global init.defaultBranch <name>\n"
"\n"
"Names commonly chosen instead of 'master' are 'main', 'trunk' and\n"
"'development'. The just-created branch can be renamed via this command:\n"
"\n"
"\tgit branch -m <name>\n"
);

char *repo_default_branch_name(struct repository *r, int quiet)
{
const char *config_key = "init.defaultbranch";
const char *config_display_key = "init.defaultBranch";
@ -574,8 +587,11 @@ char *repo_default_branch_name(struct repository *r) @@ -574,8 +587,11 @@ char *repo_default_branch_name(struct repository *r)
else if (repo_config_get_string(r, config_key, &ret) < 0)
die(_("could not retrieve `%s`"), config_display_key);

if (!ret)
if (!ret) {
ret = xstrdup("master");
if (!quiet)
advise(_(default_branch_name_advice), ret);
}

full_ref = xstrfmt("refs/heads/%s", ret);
if (check_refname_format(full_ref, 0))
@ -585,12 +601,12 @@ char *repo_default_branch_name(struct repository *r) @@ -585,12 +601,12 @@ char *repo_default_branch_name(struct repository *r)
return ret;
}

const char *git_default_branch_name(void)
const char *git_default_branch_name(int quiet)
{
static char *ret;

if (!ret)
ret = repo_default_branch_name(the_repository);
ret = repo_default_branch_name(the_repository, quiet);

return ret;
}

4
refs.h

@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref); @@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
* The return value of `repo_default_branch_name()` is an allocated string. The
* return value of `git_default_branch_name()` is a singleton.
*/
const char *git_default_branch_name(void);
char *repo_default_branch_name(struct repository *r);
const char *git_default_branch_name(int quiet);
char *repo_default_branch_name(struct repository *r, int quiet);

/*
* A ref_transaction represents a collection of reference updates that

5
remote.c

@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote) @@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
if (frag)
*(frag++) = '\0';
else
frag = (char *)git_default_branch_name();
frag = (char *)git_default_branch_name(0);

add_url_alias(remote, strbuf_detach(&buf, NULL));
refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head, @@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head,

/* If a remote branch exists with the default branch name, let's use it. */
if (!all) {
char *ref = xstrfmt("refs/heads/%s", git_default_branch_name());
char *ref = xstrfmt("refs/heads/%s",
git_default_branch_name(0));

r = find_ref_by_name(refs, ref);
free(ref);

17
t/t0001-init.sh

@ -163,7 +163,7 @@ test_expect_success 'reinit' ' @@ -163,7 +163,7 @@ test_expect_success 'reinit' '
(
mkdir again &&
cd again &&
git init >out1 2>err1 &&
git -c init.defaultBranch=initial init >out1 2>err1 &&
git init >out2 2>err2
) &&
test_i18ngrep "Initialized empty" again/out1 &&
@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' ' @@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
grep nmb actual
'

test_expect_success 'advice on unconfigured init.defaultBranch' '
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
init unconfigured-default-branch-name 2>err &&
test_decode_color <err >decoded &&
test_i18ngrep "<YELLOW>hint: " decoded
'

test_expect_success 'overridden default main branch name (env)' '
test_config_global init.defaultBranch nmb &&
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
@ -571,4 +578,12 @@ test_expect_success 'invalid default branch name' ' @@ -571,4 +578,12 @@ test_expect_success 'invalid default branch name' '
test_i18ngrep "invalid branch name" err
'

test_expect_success 'branch -m with the initial branch' '
git init rename-initial &&
git -C rename-initial branch -m renamed &&
test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
git -C rename-initial branch -m renamed again &&
test again = $(git -C rename-initial symbolic-ref --short HEAD)
'

test_done

2
t/t1510-repo-setup.sh

@ -79,7 +79,7 @@ setup_repo () { @@ -79,7 +79,7 @@ setup_repo () {
name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
sane_unset GIT_DIR GIT_WORK_TREE &&

git init "$name" &&
git -c init.defaultBranch=initial init "$name" &&
maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
maybe_config "$name/.git/config" core.bare "$barecfg" &&
mkdir -p "$name/sub/sub" &&

4
t/test-lib-functions.sh

@ -1202,7 +1202,9 @@ test_create_repo () { @@ -1202,7 +1202,9 @@ test_create_repo () {
mkdir -p "$repo"
(
cd "$repo" || error "Cannot setup test environment"
"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \
init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \
init \
"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled

Loading…
Cancel
Save