diff --git a/Documentation/BreakingChanges.txt b/Documentation/BreakingChanges.txt index 27acff86db4883..a91eb3bc5518d0 100644 --- a/Documentation/BreakingChanges.txt +++ b/Documentation/BreakingChanges.txt @@ -154,6 +154,31 @@ Cf. , , <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 diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index fa8b51daf08775..85911ca8ea0b22 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -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/` and then '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 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 @@ -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. diff --git a/builtin/remote.c b/builtin/remote.c index 1ad3e70a6b438a..e565b2b3fec8bf 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -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; diff --git a/remote.c b/remote.c index 10104d11e3cba1..55e91fab471973 100644 --- a/remote.c +++ b/remote.c @@ -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)) @@ -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) @@ -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)) @@ -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, @@ -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)) diff --git a/remote.h b/remote.h index a7e5c4e07c53ce..45b0c9babb1374 100644 --- a/remote.h +++ b/remote.h @@ -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 { diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 08424e878e104c..e96ac8c7676cee 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -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 && ( @@ -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 && ( @@ -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 && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 3b3991ab8678a5..04d8a96367910d 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -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 diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh index 320d26796d24d8..4e6026c6114fb8 100755 --- a/t/t5515-fetch-merge-logic.sh +++ b/t/t5515-fetch-merge-logic.sh @@ -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 && diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 9d693eb57f7790..e705aedbf4a8d5 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -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 && @@ -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 && @@ -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 && @@ -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" && @@ -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 '