Merge branch 'ps/3.0-remote-deprecation'

Following the procedure we established to introduce breaking
changes for Git 3.0, allow an early opt-in for removing support of
$GIT_DIR/branches/ and $GIT_DIR/remotes/ directories to configure
remotes.

* ps/3.0-remote-deprecation:
  remote: announce removal of "branches/" and "remotes/"
  builtin/pack-redundant: remove subcommand with breaking changes
  ci: repurpose "linux-gcc" job for deprecations
  ci: merge linux-gcc-default into linux-gcc
  Makefile: wire up build option for deprecated features
This commit is contained in:
Junio C Hamano
2025-02-03 10:23:33 -08:00
21 changed files with 129 additions and 56 deletions

View File

@@ -265,9 +265,8 @@ jobs:
- jobname: linux-reftable - jobname: linux-reftable
cc: clang cc: clang
pool: ubuntu-latest pool: ubuntu-latest
- jobname: linux-gcc - jobname: linux-breaking-changes
cc: gcc cc: gcc
cc_package: gcc-8
pool: ubuntu-20.04 pool: ubuntu-20.04
- jobname: linux-TEST-vars - jobname: linux-TEST-vars
cc: gcc cc: gcc
@@ -285,9 +284,6 @@ jobs:
- jobname: osx-meson - jobname: osx-meson
cc: clang cc: clang
pool: macos-13 pool: macos-13
- jobname: linux-gcc-default
cc: gcc
pool: ubuntu-latest
- jobname: linux-leaks - jobname: linux-leaks
cc: gcc cc: gcc
pool: ubuntu-latest pool: ubuntu-latest

View File

@@ -45,17 +45,13 @@ test:linux:
- jobname: linux-reftable - jobname: linux-reftable
image: ubuntu:latest image: ubuntu:latest
CC: clang CC: clang
- jobname: linux-gcc - jobname: linux-breaking-changes
image: ubuntu:20.04 image: ubuntu:20.04
CC: gcc CC: gcc
CC_PACKAGE: gcc-8
- jobname: linux-TEST-vars - jobname: linux-TEST-vars
image: ubuntu:20.04 image: ubuntu:20.04
CC: gcc CC: gcc
CC_PACKAGE: gcc-8 CC_PACKAGE: gcc-8
- jobname: linux-gcc-default
image: ubuntu:latest
CC: gcc
- jobname: linux-leaks - jobname: linux-leaks
image: ubuntu:latest image: ubuntu:latest
CC: gcc CC: gcc

View File

@@ -154,6 +154,31 @@ Cf. <xmqq1rjuz6n3.fsf_-_@gitster.c.googlers.com>,
<CAKvOHKAFXQwt4D8yUCCkf_TQL79mYaJ=KAKhtpDNTvHJFuX1NA@mail.gmail.com>, <CAKvOHKAFXQwt4D8yUCCkf_TQL79mYaJ=KAKhtpDNTvHJFuX1NA@mail.gmail.com>,
<20230323204047.GA9290@coredump.intra.peff.net>, <20230323204047.GA9290@coredump.intra.peff.net>,
* Support for storing shorthands for remote URLs in "$GIT_COMMON_DIR/branches/"
and "$GIT_COMMON_DIR/remotes/" has been long superseded by storing remotes in
the repository configuration.
+
The mechanism has originally been introduced in f170e4b39d ([PATCH] fetch/pull:
short-hand notation for remote repositories., 2005-07-16) and was superseded by
6687f8fea2 ([PATCH] Use .git/remote/origin, not .git/branches/origin.,
2005-08-20), where we switched from ".git/branches/" to ".git/remotes/". That
commit already mentions an upcoming deprecation of the ".git/branches/"
directory, and starting with a1d4aa7424 (Add repository-layout document.,
2005-09-01) we have also marked this layout as deprecated. Eventually we also
started to migrate away from ".git/remotes/" in favor of config-based remotes,
and we have marked the directory as legacy in 3d3d282146 (Documentation:
Grammar correction, wording fixes and cleanup, 2011-08-23)
+
As our documentation mentions, these directories are not to be found in modern
repositories at all and most users aren't even aware of these mechanisms. They
have been deprecated for almost 20 years and 14 years respectively, and we are
not aware of any active users that have complained about this deprecation.
Furthermore, the ".git/branches/" directory is nowadays misleadingly named and
may cause confusion as "branches" are almost exclusively used in the context of
references.
+
These features will be removed.
== Superseded features that will not be deprecated == Superseded features that will not be deprecated
Some features have gained newer replacements that aim to improve the design in Some features have gained newer replacements that aim to improve the design in

View File

@@ -153,7 +153,7 @@ config.worktree::
linkgit:git-worktree[1]). linkgit:git-worktree[1]).
branches:: branches::
A slightly deprecated way to store shorthands to be used A deprecated way to store shorthands to be used
to specify a URL to 'git fetch', 'git pull' and 'git push'. to specify a URL to 'git fetch', 'git pull' and 'git push'.
A file can be stored as `branches/<name>` and then A file can be stored as `branches/<name>` and then
'name' can be given to these commands in place of 'name' can be given to these commands in place of
@@ -162,7 +162,8 @@ branches::
and not likely to be found in modern repositories. This and not likely to be found in modern repositories. This
directory is ignored if $GIT_COMMON_DIR is set and directory is ignored if $GIT_COMMON_DIR is set and
"$GIT_COMMON_DIR/branches" will be used instead. "$GIT_COMMON_DIR/branches" will be used instead.
+
Git will stop reading remotes from this directory in Git 3.0.
hooks:: hooks::
Hooks are customization scripts used by various Git Hooks are customization scripts used by various Git
@@ -238,6 +239,8 @@ remotes::
and not likely to be found in modern repositories. This and not likely to be found in modern repositories. This
directory is ignored if $GIT_COMMON_DIR is set and directory is ignored if $GIT_COMMON_DIR is set and
"$GIT_COMMON_DIR/remotes" will be used instead. "$GIT_COMMON_DIR/remotes" will be used instead.
+
Git will stop reading remotes from this directory in Git 3.0.
logs:: logs::
Records of changes made to refs are stored in this directory. Records of changes made to refs are stored in this directory.

View File

@@ -45,4 +45,5 @@ TEST_OUTPUT_DIRECTORY=@TEST_OUTPUT_DIRECTORY@
TEST_SHELL_PATH=@TEST_SHELL_PATH@ TEST_SHELL_PATH=@TEST_SHELL_PATH@
USE_GETTEXT_SCHEME=@USE_GETTEXT_SCHEME@ USE_GETTEXT_SCHEME=@USE_GETTEXT_SCHEME@
USE_LIBPCRE2=@USE_LIBPCRE2@ USE_LIBPCRE2=@USE_LIBPCRE2@
WITH_BREAKING_CHANGES=@WITH_BREAKING_CHANGES@
X=@X@ X=@X@

View File

@@ -1273,7 +1273,9 @@ BUILTIN_OBJS += builtin/mv.o
BUILTIN_OBJS += builtin/name-rev.o BUILTIN_OBJS += builtin/name-rev.o
BUILTIN_OBJS += builtin/notes.o BUILTIN_OBJS += builtin/notes.o
BUILTIN_OBJS += builtin/pack-objects.o BUILTIN_OBJS += builtin/pack-objects.o
ifndef WITH_BREAKING_CHANGES
BUILTIN_OBJS += builtin/pack-redundant.o BUILTIN_OBJS += builtin/pack-redundant.o
endif
BUILTIN_OBJS += builtin/pack-refs.o BUILTIN_OBJS += builtin/pack-refs.o
BUILTIN_OBJS += builtin/patch-id.o BUILTIN_OBJS += builtin/patch-id.o
BUILTIN_OBJS += builtin/prune-packed.o BUILTIN_OBJS += builtin/prune-packed.o
@@ -2236,6 +2238,10 @@ ifdef FSMONITOR_OS_SETTINGS
COMPAT_OBJS += compat/fsmonitor/fsm-path-utils-$(FSMONITOR_OS_SETTINGS).o COMPAT_OBJS += compat/fsmonitor/fsm-path-utils-$(FSMONITOR_OS_SETTINGS).o
endif endif
ifdef WITH_BREAKING_CHANGES
BASIC_CFLAGS += -DWITH_BREAKING_CHANGES
endif
ifeq ($(TCLTK_PATH),) ifeq ($(TCLTK_PATH),)
NO_TCLTK = NoThanks NO_TCLTK = NoThanks
endif endif
@@ -3194,6 +3200,7 @@ GIT-BUILD-OPTIONS: FORCE
-e "s|@TEST_SHELL_PATH@|\'$(TEST_SHELL_PATH_SQ)\'|" \ -e "s|@TEST_SHELL_PATH@|\'$(TEST_SHELL_PATH_SQ)\'|" \
-e "s|@USE_GETTEXT_SCHEME@|\'$(USE_GETTEXT_SCHEME)\'|" \ -e "s|@USE_GETTEXT_SCHEME@|\'$(USE_GETTEXT_SCHEME)\'|" \
-e "s|@USE_LIBPCRE2@|\'$(USE_LIBPCRE2)\'|" \ -e "s|@USE_LIBPCRE2@|\'$(USE_LIBPCRE2)\'|" \
-e "s|@WITH_BREAKING_CHANGES@|\'$(WITH_BREAKING_CHANGES)\'|" \
-e "s|@X@|\'$(X)\'|" \ -e "s|@X@|\'$(X)\'|" \
GIT-BUILD-OPTIONS.in >$@+ GIT-BUILD-OPTIONS.in >$@+
@if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi @if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi

View File

@@ -642,10 +642,12 @@ static int migrate_file(struct remote *remote)
strbuf_addf(&buf, "remote.%s.fetch", remote->name); strbuf_addf(&buf, "remote.%s.fetch", remote->name);
for (i = 0; i < remote->fetch.nr; i++) for (i = 0; i < remote->fetch.nr; i++)
git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0); git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0);
#ifndef WITH_BREAKING_CHANGES
if (remote->origin == REMOTE_REMOTES) if (remote->origin == REMOTE_REMOTES)
unlink_or_warn(git_path("remotes/%s", remote->name)); unlink_or_warn(git_path("remotes/%s", remote->name));
else if (remote->origin == REMOTE_BRANCHES) else if (remote->origin == REMOTE_BRANCHES)
unlink_or_warn(git_path("branches/%s", remote->name)); unlink_or_warn(git_path("branches/%s", remote->name));
#endif /* WITH_BREAKING_CHANGES */
strbuf_release(&buf); strbuf_release(&buf);
return 0; return 0;

View File

@@ -329,11 +329,6 @@ export SKIP_DASHED_BUILT_INS=YesPlease
case "$distro" in case "$distro" in
ubuntu-*) ubuntu-*)
if test "$jobname" = "linux-gcc-default"
then
break
fi
# Python 2 is end of life, and Ubuntu 23.04 and newer don't actually # Python 2 is end of life, and Ubuntu 23.04 and newer don't actually
# have it anymore. We thus only test with Python 2 on older LTS # have it anymore. We thus only test with Python 2 on older LTS
# releases. # releases.

View File

@@ -13,8 +13,9 @@ esac
run_tests=t run_tests=t
case "$jobname" in case "$jobname" in
linux-gcc) linux-breaking-changes)
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export WITH_BREAKING_CHANGES=YesPlease
;; ;;
linux-TEST-vars) linux-TEST-vars)
export OPENSSL_SHA1_UNSAFE=YesPlease export OPENSSL_SHA1_UNSAFE=YesPlease

View File

@@ -1205,6 +1205,7 @@ string(REPLACE "@TEST_OUTPUT_DIRECTORY@" "" git_build_options "${git_build_optio
string(REPLACE "@TEST_SHELL_PATH@" "'${TEST_SHELL_PATH}'" git_build_options "${git_build_options}") string(REPLACE "@TEST_SHELL_PATH@" "'${TEST_SHELL_PATH}'" git_build_options "${git_build_options}")
string(REPLACE "@USE_GETTEXT_SCHEME@" "" git_build_options "${git_build_options}") string(REPLACE "@USE_GETTEXT_SCHEME@" "" git_build_options "${git_build_options}")
string(REPLACE "@USE_LIBPCRE2@" "" git_build_options "${git_build_options}") string(REPLACE "@USE_LIBPCRE2@" "" git_build_options "${git_build_options}")
string(REPLACE "@WITH_BREAKING_CHANGES@" "" git_build_options "${git_build_options}")
string(REPLACE "@X@" "${EXE_EXTENSION}" git_build_options "${git_build_options}") string(REPLACE "@X@" "${EXE_EXTENSION}" git_build_options "${git_build_options}")
if(USE_VCPKG) if(USE_VCPKG)
string(APPEND git_build_options "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n") string(APPEND git_build_options "PATH=\"$PATH:$TEST_DIRECTORY/../compat/vcbuild/vcpkg/installed/x64-windows/bin\"\n")

2
git.c
View File

@@ -587,7 +587,9 @@ static struct cmd_struct commands[] = {
{ "name-rev", cmd_name_rev, RUN_SETUP }, { "name-rev", cmd_name_rev, RUN_SETUP },
{ "notes", cmd_notes, RUN_SETUP }, { "notes", cmd_notes, RUN_SETUP },
{ "pack-objects", cmd_pack_objects, RUN_SETUP }, { "pack-objects", cmd_pack_objects, RUN_SETUP },
#ifndef WITH_BREAKING_CHANGES
{ "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT }, { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT },
#endif
{ "pack-refs", cmd_pack_refs, RUN_SETUP }, { "pack-refs", cmd_pack_refs, RUN_SETUP },
{ "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT }, { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT },
{ "pickaxe", cmd_blame, RUN_SETUP }, { "pickaxe", cmd_blame, RUN_SETUP },

View File

@@ -655,6 +655,12 @@ build_options_config.set('GIT_TEST_UTF8_LOCALE', '')
build_options_config.set_quoted('LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir'))) build_options_config.set_quoted('LOCALEDIR', fs.as_posix(get_option('prefix') / get_option('localedir')))
build_options_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb')) build_options_config.set('GITWEBDIR', fs.as_posix(get_option('prefix') / get_option('datadir') / 'gitweb'))
if get_option('breaking_changes')
build_options_config.set('WITH_BREAKING_CHANGES', 'YesPlease')
else
build_options_config.set('WITH_BREAKING_CHANGES', '')
endif
if get_option('sane_tool_path') != '' if get_option('sane_tool_path') != ''
build_options_config.set_quoted('BROKEN_PATH_FIX', 's|^\# @BROKEN_PATH_FIX@$|git_broken_path_fix "' + get_option('sane_tool_path') + '"|') build_options_config.set_quoted('BROKEN_PATH_FIX', 's|^\# @BROKEN_PATH_FIX@$|git_broken_path_fix "' + get_option('sane_tool_path') + '"|')
else else

View File

@@ -59,6 +59,8 @@ option('sha256_backend', type: 'combo', choices: ['openssl', 'nettle', 'gcrypt',
description: 'The backend used for hashing objects with the SHA256 object format.') description: 'The backend used for hashing objects with the SHA256 object format.')
# Build tweaks. # Build tweaks.
option('breaking_changes', type: 'boolean', value: false,
description: 'Enable upcoming breaking changes.')
option('macos_use_homebrew_gettext', type: 'boolean', value: true, option('macos_use_homebrew_gettext', type: 'boolean', value: true,
description: 'Use gettext from Homebrew instead of the slightly-broken system-provided one.') description: 'Use gettext from Homebrew instead of the slightly-broken system-provided one.')

View File

@@ -294,6 +294,7 @@ static void add_instead_of(struct rewrite *rewrite, const char *instead_of)
rewrite->instead_of_nr++; rewrite->instead_of_nr++;
} }
#ifndef WITH_BREAKING_CHANGES
static const char *skip_spaces(const char *s) static const char *skip_spaces(const char *s)
{ {
while (isspace(*s)) while (isspace(*s))
@@ -301,6 +302,21 @@ static const char *skip_spaces(const char *s)
return s; return s;
} }
static void warn_about_deprecated_remote_type(const char *type,
const struct remote *remote)
{
warning(_("reading remote from \"%s/%s\", which is nominated for removal.\n"
"\n"
"If you still use the \"remotes/\" directory it is recommended to\n"
"migrate to config-based remotes:\n"
"\n"
"\tgit remote rename %s %s\n"
"\n"
"If you cannot, please let us know why you still need to use it by\n"
"sending an e-mail to <git@vger.kernel.org>."),
type, remote->name, remote->name, remote->name);
}
static void read_remotes_file(struct remote_state *remote_state, static void read_remotes_file(struct remote_state *remote_state,
struct remote *remote) struct remote *remote)
{ {
@@ -309,6 +325,9 @@ static void read_remotes_file(struct remote_state *remote_state,
if (!f) if (!f)
return; return;
warn_about_deprecated_remote_type("remotes", remote);
remote->configured_in_repo = 1; remote->configured_in_repo = 1;
remote->origin = REMOTE_REMOTES; remote->origin = REMOTE_REMOTES;
while (strbuf_getline(&buf, f) != EOF) { while (strbuf_getline(&buf, f) != EOF) {
@@ -338,6 +357,8 @@ static void read_branches_file(struct remote_state *remote_state,
if (!f) if (!f)
return; return;
warn_about_deprecated_remote_type("branches", remote);
strbuf_getline_lf(&buf, f); strbuf_getline_lf(&buf, f);
fclose(f); fclose(f);
strbuf_trim(&buf); strbuf_trim(&buf);
@@ -375,6 +396,7 @@ static void read_branches_file(struct remote_state *remote_state,
strbuf_release(&buf); strbuf_release(&buf);
free(to_free); free(to_free);
} }
#endif /* WITH_BREAKING_CHANGES */
static int handle_config(const char *key, const char *value, static int handle_config(const char *key, const char *value,
const struct config_context *ctx, void *cb) const struct config_context *ctx, void *cb)
@@ -591,6 +613,7 @@ static void read_config(struct repository *repo, int early)
alias_all_urls(repo->remote_state); alias_all_urls(repo->remote_state);
} }
#ifndef WITH_BREAKING_CHANGES
static int valid_remote_nick(const char *name) static int valid_remote_nick(const char *name)
{ {
if (!name[0] || is_dot_or_dotdot(name)) if (!name[0] || is_dot_or_dotdot(name))
@@ -602,6 +625,7 @@ static int valid_remote_nick(const char *name)
return 0; return 0;
return 1; return 1;
} }
#endif /* WITH_BREAKING_CHANGES */
static const char *remotes_remote_for_branch(struct remote_state *remote_state, static const char *remotes_remote_for_branch(struct remote_state *remote_state,
struct branch *branch, struct branch *branch,
@@ -744,12 +768,14 @@ remotes_remote_get_1(struct remote_state *remote_state, const char *name,
&name_given); &name_given);
ret = make_remote(remote_state, name, 0); ret = make_remote(remote_state, name, 0);
#ifndef WITH_BREAKING_CHANGES
if (valid_remote_nick(name) && have_git_dir()) { if (valid_remote_nick(name) && have_git_dir()) {
if (!valid_remote(ret)) if (!valid_remote(ret))
read_remotes_file(remote_state, ret); read_remotes_file(remote_state, ret);
if (!valid_remote(ret)) if (!valid_remote(ret))
read_branches_file(remote_state, ret); read_branches_file(remote_state, ret);
} }
#endif /* WITH_BREAKING_CHANGES */
if (name_given && !valid_remote(ret)) if (name_given && !valid_remote(ret))
add_url_alias(remote_state, ret, name); add_url_alias(remote_state, ret, name);
if (!valid_remote(ret)) if (!valid_remote(ret))

View File

@@ -21,8 +21,10 @@ struct transport_ls_refs_options;
enum { enum {
REMOTE_UNCONFIGURED = 0, REMOTE_UNCONFIGURED = 0,
REMOTE_CONFIG, REMOTE_CONFIG,
#ifndef WITH_BREAKING_CHANGES
REMOTE_REMOTES, REMOTE_REMOTES,
REMOTE_BRANCHES REMOTE_BRANCHES
#endif /* WITH_BREAKING_CHANGES */
}; };
struct rewrite { struct rewrite {

View File

@@ -36,6 +36,12 @@ relationship between packs and objects is as follows:
. ./test-lib.sh . ./test-lib.sh
if ! test_have_prereq WITHOUT_BREAKING_CHANGES
then
skip_all='skipping git-pack-redundant tests; built with breaking changes'
test_done
fi
main_repo=main.git main_repo=main.git
shared_repo=shared.git shared_repo=shared.git

View File

@@ -1113,7 +1113,7 @@ Pull: refs/heads/main:refs/heads/origin
Pull: refs/heads/next:refs/heads/origin2 Pull: refs/heads/next:refs/heads/origin2
EOF EOF
test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' ' test_expect_success WITHOUT_BREAKING_CHANGES 'migrate a remote from named file in $GIT_DIR/remotes' '
git clone one five && git clone one five &&
origin_url=$(pwd)/one && origin_url=$(pwd)/one &&
( (
@@ -1139,7 +1139,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
) )
' '
test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' ' test_expect_success WITHOUT_BREAKING_CHANGES 'migrate a remote from named file in $GIT_DIR/branches' '
git clone --template= one six && git clone --template= one six &&
origin_url=$(pwd)/one && origin_url=$(pwd)/one &&
( (
@@ -1155,7 +1155,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
) )
' '
test_expect_success 'migrate a remote from named file in $GIT_DIR/branches (2)' ' test_expect_success WITHOUT_BREAKING_CHANGES 'migrate a remote from named file in $GIT_DIR/branches (2)' '
git clone --template= one seven && git clone --template= one seven &&
( (
cd seven && cd seven &&

View File

@@ -34,14 +34,11 @@ test_expect_success "clone and setup child repos" '
git clone . three && git clone . three &&
( (
cd three && cd three &&
git config branch.main.remote two && git config set remote.two.url ../two/.git/ &&
git config branch.main.merge refs/heads/one && git config set remote.two.fetch refs/heads/main:refs/heads/two &&
mkdir -p .git/remotes && git config set --append remote.two.fetch refs/heads/one:refs/heads/one &&
cat >.git/remotes/two <<-\EOF git config set branch.main.remote two &&
URL: ../two/.git/ git config set branch.main.merge refs/heads/one
Pull: refs/heads/main:refs/heads/two
Pull: refs/heads/one:refs/heads/one
EOF
) && ) &&
git clone . bundle && git clone . bundle &&
git clone . seven git clone . seven

View File

@@ -104,28 +104,31 @@ test_expect_success setup '
git config remote.config-glob.fetch refs/heads/*:refs/remotes/rem/* && git config remote.config-glob.fetch refs/heads/*:refs/remotes/rem/* &&
remotes="$remotes config-glob" && remotes="$remotes config-glob" &&
mkdir -p .git/remotes && if test_have_prereq WITHOUT_BREAKING_CHANGES
cat >.git/remotes/remote-explicit <<-\EOF && then
URL: ../.git/ mkdir -p .git/remotes &&
Pull: refs/heads/main:remotes/rem/main cat >.git/remotes/remote-explicit <<-\EOF &&
Pull: refs/heads/one:remotes/rem/one URL: ../.git/
Pull: two:remotes/rem/two Pull: refs/heads/main:remotes/rem/main
Pull: refs/heads/three:remotes/rem/three Pull: refs/heads/one:remotes/rem/one
EOF Pull: two:remotes/rem/two
remotes="$remotes remote-explicit" && Pull: refs/heads/three:remotes/rem/three
EOF
remotes="$remotes remote-explicit" &&
cat >.git/remotes/remote-glob <<-\EOF && cat >.git/remotes/remote-glob <<-\EOF &&
URL: ../.git/ URL: ../.git/
Pull: refs/heads/*:refs/remotes/rem/* Pull: refs/heads/*:refs/remotes/rem/*
EOF EOF
remotes="$remotes remote-glob" && remotes="$remotes remote-glob" &&
mkdir -p .git/branches && mkdir -p .git/branches &&
echo "../.git" > .git/branches/branches-default && echo "../.git" > .git/branches/branches-default &&
remotes="$remotes branches-default" && remotes="$remotes branches-default" &&
echo "../.git#one" > .git/branches/branches-one && echo "../.git#one" > .git/branches/branches-one &&
remotes="$remotes branches-one" && remotes="$remotes branches-one"
fi &&
for remote in $remotes ; do for remote in $remotes ; do
git config branch.br-$remote.remote $remote && git config branch.br-$remote.remote $remote &&

View File

@@ -975,7 +975,7 @@ test_expect_success 'allow push to HEAD of non-bare repository (config)' '
! grep "warning: updating the current branch" stderr ! grep "warning: updating the current branch" stderr
' '
test_expect_success 'fetch with branches' ' test_expect_success WITHOUT_BREAKING_CHANGES 'fetch with branches' '
mk_empty testrepo && mk_empty testrepo &&
git branch second $the_first_commit && git branch second $the_first_commit &&
git checkout second && git checkout second &&
@@ -991,7 +991,7 @@ test_expect_success 'fetch with branches' '
git checkout main git checkout main
' '
test_expect_success 'fetch with branches containing #' ' test_expect_success WITHOUT_BREAKING_CHANGES 'fetch with branches containing #' '
mk_empty testrepo && mk_empty testrepo &&
mkdir testrepo/.git/branches && mkdir testrepo/.git/branches &&
echo "..#second" > testrepo/.git/branches/branch2 && echo "..#second" > testrepo/.git/branches/branch2 &&
@@ -1005,7 +1005,7 @@ test_expect_success 'fetch with branches containing #' '
git checkout main git checkout main
' '
test_expect_success 'push with branches' ' test_expect_success WITHOUT_BREAKING_CHANGES 'push with branches' '
mk_empty testrepo && mk_empty testrepo &&
git checkout second && git checkout second &&
@@ -1022,7 +1022,7 @@ test_expect_success 'push with branches' '
) )
' '
test_expect_success 'push with branches containing #' ' test_expect_success WITHOUT_BREAKING_CHANGES 'push with branches containing #' '
mk_empty testrepo && mk_empty testrepo &&
test_when_finished "rm -rf .git/branches" && test_when_finished "rm -rf .git/branches" &&
@@ -1211,18 +1211,16 @@ test_expect_success 'push --porcelain --dry-run rejected' '
' '
test_expect_success 'push --prune' ' test_expect_success 'push --prune' '
mk_test testrepo heads/main heads/second heads/foo heads/bar && mk_test testrepo heads/main heads/foo heads/bar &&
git push --prune testrepo : && git push --prune testrepo : &&
check_push_result testrepo $the_commit heads/main && check_push_result testrepo $the_commit heads/main &&
check_push_result testrepo $the_first_commit heads/second &&
! check_push_result testrepo $the_first_commit heads/foo heads/bar ! check_push_result testrepo $the_first_commit heads/foo heads/bar
' '
test_expect_success 'push --prune refspec' ' test_expect_success 'push --prune refspec' '
mk_test testrepo tmp/main tmp/second tmp/foo tmp/bar && mk_test testrepo tmp/main tmp/foo tmp/bar &&
git push --prune testrepo "refs/heads/*:refs/tmp/*" && git push --prune testrepo "refs/heads/*:refs/tmp/*" &&
check_push_result testrepo $the_commit tmp/main && check_push_result testrepo $the_commit tmp/main &&
check_push_result testrepo $the_first_commit tmp/second &&
! check_push_result testrepo $the_first_commit tmp/foo tmp/bar ! check_push_result testrepo $the_first_commit tmp/foo tmp/bar
' '

View File

@@ -1862,6 +1862,10 @@ test_lazy_prereq CURL '
curl --version curl --version
' '
test_lazy_prereq WITHOUT_BREAKING_CHANGES '
test -z "$WITH_BREAKING_CHANGES"
'
# SHA1 is a test if the hash algorithm in use is SHA-1. This is both for tests # SHA1 is a test if the hash algorithm in use is SHA-1. This is both for tests
# which will not work with other hash algorithms and tests that work but don't # which will not work with other hash algorithms and tests that work but don't
# test anything meaningful (e.g. special values which cause short collisions). # test anything meaningful (e.g. special values which cause short collisions).