Skip to content

Commit

Permalink
remote: announce removal of "branches/" and "remotes/"
Browse files Browse the repository at this point in the history
Back when Git was in its infancy, remotes were configured via separate
files in "branches/" (back in 2005). This mechanism was replaced later
that year with the "remotes/" directory. These mechanism have eventually
been replaced by config-based remotes, and it is very unlikely that
anybody still uses these directories to configure their remotes.

Both of these directories have been marked as deprecated, one in 2005
and the other one in 2011. Follow through with the deprecation and
finally announce the removal of these features in Git 3.0.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
pks-t authored and gitster committed Jan 6, 2025
1 parent 1ab8568 commit 1ba23cf
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 43 deletions.
25 changes: 25 additions & 0 deletions Documentation/BreakingChanges.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,31 @@ Cf. <xmqq1rjuz6n3.fsf_-_@gitster.c.googlers.com>,
<CAKvOHKAFXQwt4D8yUCCkf_TQL79mYaJ=KAKhtpDNTvHJFuX1NA@mail.gmail.com>,
<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 reason why anybody would want to use these mechanisms.
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

Some features have gained newer replacements that aim to improve the design in
Expand Down
7 changes: 5 additions & 2 deletions Documentation/gitrepository-layout.txt
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ config.worktree::
linkgit:git-worktree[1]).

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'.
A file can be stored as `branches/<name>` and then
'name' can be given to these commands in place of
Expand All @@ -162,7 +162,8 @@ branches::
and not likely to be found in modern repositories. This
directory is ignored if $GIT_COMMON_DIR is set and
"$GIT_COMMON_DIR/branches" will be used instead.

+
Git will stop reading remotes from this directory in Git 3.0.

hooks::
Hooks are customization scripts used by various Git
Expand Down Expand Up @@ -238,6 +239,8 @@ remotes::
and not likely to be found in modern repositories. This
directory is ignored if $GIT_COMMON_DIR is set and
"$GIT_COMMON_DIR/remotes" will be used instead.
+
Git will stop reading remotes from this directory in Git 3.0.

logs::
Records of changes made to refs are stored in this directory.
Expand Down
2 changes: 2 additions & 0 deletions builtin/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,10 +640,12 @@ static int migrate_file(struct remote *remote)
strbuf_addf(&buf, "remote.%s.fetch", remote->name);
for (i = 0; i < remote->fetch.nr; i++)
git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0);
#ifndef WITH_BREAKING_CHANGES
if (remote->origin == REMOTE_REMOTES)
unlink_or_warn(git_path("remotes/%s", remote->name));
else if (remote->origin == REMOTE_BRANCHES)
unlink_or_warn(git_path("branches/%s", remote->name));
#endif /* WITH_BREAKING_CHANGES */
strbuf_release(&buf);

return 0;
Expand Down
6 changes: 6 additions & 0 deletions remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ static void add_instead_of(struct rewrite *rewrite, const char *instead_of)
rewrite->instead_of_nr++;
}

#ifndef WITH_BREAKING_CHANGES
static const char *skip_spaces(const char *s)
{
while (isspace(*s))
Expand Down Expand Up @@ -374,6 +375,7 @@ static void read_branches_file(struct remote_state *remote_state,
strbuf_release(&buf);
free(to_free);
}
#endif /* WITH_BREAKING_CHANGES */

static int handle_config(const char *key, const char *value,
const struct config_context *ctx, void *cb)
Expand Down Expand Up @@ -572,6 +574,7 @@ static void read_config(struct repository *repo, int early)
alias_all_urls(repo->remote_state);
}

#ifndef WITH_BREAKING_CHANGES
static int valid_remote_nick(const char *name)
{
if (!name[0] || is_dot_or_dotdot(name))
Expand All @@ -583,6 +586,7 @@ static int valid_remote_nick(const char *name)
return 0;
return 1;
}
#endif /* WITH_BREAKING_CHANGES */

static const char *remotes_remote_for_branch(struct remote_state *remote_state,
struct branch *branch,
Expand Down Expand Up @@ -725,12 +729,14 @@ remotes_remote_get_1(struct remote_state *remote_state, const char *name,
&name_given);

ret = make_remote(remote_state, name, 0);
#ifndef WITH_BREAKING_CHANGES
if (valid_remote_nick(name) && have_git_dir()) {
if (!valid_remote(ret))
read_remotes_file(remote_state, ret);
if (!valid_remote(ret))
read_branches_file(remote_state, ret);
}
#endif /* WITH_BREAKING_CHANGES */
if (name_given && !valid_remote(ret))
add_url_alias(remote_state, ret, name);
if (!valid_remote(ret))
Expand Down
2 changes: 2 additions & 0 deletions remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ struct transport_ls_refs_options;
enum {
REMOTE_UNCONFIGURED = 0,
REMOTE_CONFIG,
#ifndef WITH_BREAKING_CHANGES
REMOTE_REMOTES,
REMOTE_BRANCHES
#endif /* WITH_BREAKING_CHANGES */
};

struct rewrite {
Expand Down
6 changes: 3 additions & 3 deletions t/t5505-remote.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1007,7 +1007,7 @@ Pull: refs/heads/main:refs/heads/origin
Pull: refs/heads/next:refs/heads/origin2
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 &&
origin_url=$(pwd)/one &&
(
Expand All @@ -1033,7 +1033,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 &&
origin_url=$(pwd)/one &&
(
Expand All @@ -1049,7 +1049,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 &&
(
cd seven &&
Expand Down
13 changes: 5 additions & 8 deletions t/t5510-fetch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,11 @@ test_expect_success "clone and setup child repos" '
git clone . three &&
(
cd three &&
git config branch.main.remote two &&
git config branch.main.merge refs/heads/one &&
mkdir -p .git/remotes &&
cat >.git/remotes/two <<-\EOF
URL: ../two/.git/
Pull: refs/heads/main:refs/heads/two
Pull: refs/heads/one:refs/heads/one
EOF
git config set remote.two.url ../two/.git/ &&
git config set remote.two.fetch refs/heads/main:refs/heads/two &&
git config set --append remote.two.fetch refs/heads/one:refs/heads/one &&
git config set branch.main.remote two &&
git config set branch.main.merge refs/heads/one
) &&
git clone . bundle &&
git clone . seven
Expand Down
47 changes: 25 additions & 22 deletions t/t5515-fetch-merge-logic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -104,28 +104,31 @@ test_expect_success setup '
git config remote.config-glob.fetch refs/heads/*:refs/remotes/rem/* &&
remotes="$remotes config-glob" &&
mkdir -p .git/remotes &&
cat >.git/remotes/remote-explicit <<-\EOF &&
URL: ../.git/
Pull: refs/heads/main:remotes/rem/main
Pull: refs/heads/one:remotes/rem/one
Pull: two:remotes/rem/two
Pull: refs/heads/three:remotes/rem/three
EOF
remotes="$remotes remote-explicit" &&
cat >.git/remotes/remote-glob <<-\EOF &&
URL: ../.git/
Pull: refs/heads/*:refs/remotes/rem/*
EOF
remotes="$remotes remote-glob" &&
mkdir -p .git/branches &&
echo "../.git" > .git/branches/branches-default &&
remotes="$remotes branches-default" &&
echo "../.git#one" > .git/branches/branches-one &&
remotes="$remotes branches-one" &&
if test_have_prereq WITHOUT_BREAKING_CHANGES
then
mkdir -p .git/remotes &&
cat >.git/remotes/remote-explicit <<-\EOF &&
URL: ../.git/
Pull: refs/heads/main:remotes/rem/main
Pull: refs/heads/one:remotes/rem/one
Pull: two:remotes/rem/two
Pull: refs/heads/three:remotes/rem/three
EOF
remotes="$remotes remote-explicit" &&
cat >.git/remotes/remote-glob <<-\EOF &&
URL: ../.git/
Pull: refs/heads/*:refs/remotes/rem/*
EOF
remotes="$remotes remote-glob" &&
mkdir -p .git/branches &&
echo "../.git" > .git/branches/branches-default &&
remotes="$remotes branches-default" &&
echo "../.git#one" > .git/branches/branches-one &&
remotes="$remotes branches-one"
fi &&
for remote in $remotes ; do
git config branch.br-$remote.remote $remote &&
Expand Down
14 changes: 6 additions & 8 deletions t/t5516-fetch-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,7 @@ test_expect_success 'allow push to HEAD of non-bare repository (config)' '
! 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 &&
git branch second $the_first_commit &&
git checkout second &&
Expand All @@ -991,7 +991,7 @@ test_expect_success 'fetch with branches' '
git checkout main
'

test_expect_success 'fetch with branches containing #' '
test_expect_success WITHOUT_BREAKING_CHANGES 'fetch with branches containing #' '
mk_empty testrepo &&
mkdir testrepo/.git/branches &&
echo "..#second" > testrepo/.git/branches/branch2 &&
Expand All @@ -1005,7 +1005,7 @@ test_expect_success 'fetch with branches containing #' '
git checkout main
'

test_expect_success 'push with branches' '
test_expect_success WITHOUT_BREAKING_CHANGES 'push with branches' '
mk_empty testrepo &&
git checkout second &&
Expand All @@ -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 &&
test_when_finished "rm -rf .git/branches" &&
Expand Down Expand Up @@ -1211,18 +1211,16 @@ test_expect_success 'push --porcelain --dry-run rejected' '
'

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 : &&
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
'

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/*" &&
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
'

Expand Down

0 comments on commit 1ba23cf

Please sign in to comment.