From: Ingo Rohloff Date: Wed, 06 Nov 2019 16:56:28 GMT Subject: [PATCH] branch: Forbid to create local branches with confusing names Message-ID: <20191106165628.28563-1-ingo.rohloff@lauterbach.com> Without this patch, git allows to do something like this: git branch remotes/origin/master git branch refs/remotes/origin/master git branch heads/master git branch tags/v3.4 All of these local branch names lead to severe confusion, not only for a user but also for git itself. This patch forbids to create local branches, with names which start with any of refs/ heads/ remotes/ tags/ With this patch, you might still create these kind of local branches, but now you have to additionally specify the '-f' option. Signed-off-by: Ingo Rohloff --- branch.c | 10 ++++++++++ 1 file changed, 10 insertions(+) This patch refers way back to the discussion from 2014: From: Josef Wolf To: git@vger.kernel.org Subject: error: src refspec refs/heads/master matches more than one. Date: Fri, 14 Feb 2014 12:31:36 +0100 See for example here: https://public-inbox.org/git/20140214113136.GA17817@raven.inka.de/ The origin of the problem is, that git has (almost) no constraints what kind of names are allowed for local branches. There nowadays is a constraint that you are NOT allowed to create a branch which is called HEAD. See commit 16169285f1e6 ("Merge branch 'jc/branch-name-sanity'", 2017-11-28). In the old mail thread a lot of potential constraints for local branch names were discussed; in particular a lot of strategies were discussed what kind of local branch names might be a problem (the gist is: avoid ambiguities, by finding out which names lead to ambiguities NOW). I personally think it makes more sense to forbid a much bigger class of confusing branch names. In particular I think all local branch names starting with refs/ heads/ remotes/ tags/ should be forbidden (per default, can still be forced). This also avoids trouble for an unforseeable future. Example: git branch remotes/blub/master This might not be a problem now, because you have no remote called "blub" right now. But if you later use git remote add blub git fetch blub you very likely run into trouble. The above approach still allows you to create local branches with a name of the form / but I cannot see how this might be avoided; remotes might be added later so what would you do in the case that a local branch already existed named like the remote or a remote tracking branch. With the proposed constraints you are at least are able to use heads// remotes// to differentiate between the two. This really is an issue; people seem to stumble over it and I guess this is particularly true if you control git via scripts. See for example (two years later): From: Duy Nguyen To: Junio C Hamano Cc: Git Mailing List , Subject: Re: error: src refspec refs/heads/master matches more than one. Date: Wed, 23 Mar 2016 18:17:05 +0700 So with this patch I want to pick up this old discussion yet again. This code can probably be done a lot better I guess, but I wanted to send in something, to start the discussion. diff --git a/branch.c b/branch.c index 579494738a..e74872dac5 100644 --- a/branch.c +++ b/branch.c @@ -256,6 +256,16 @@ void create_branch(struct repository *r, int dont_change_ref = 0; int explicit_tracking = 0; + if (!force && ( + starts_with(name, "refs/") || + starts_with(name, "heads/") || + starts_with(name, "remotes/") || + starts_with(name, "tags/") + )) { + die(_("A local branch name should not start with " + "\"refs/\", \"heads/\", \"remotes/\" or \"tags/\"")); + } + if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE) explicit_tracking = 1; -- 2.24.0.1.g6c2c19214d.dirty