6

Git will by default deny deleting a local branch (via git branch -d mybranch), if that branch is not fully merged.

However, if I delete a remote branch via git push origin --delete mybranch, there is no warning whatsoever if the branch is not fully merged.

This seems rather dangerous: Someone else might have pushed updates to the branch since I last fetched it, so accidentally deleting an unmerged branch seems more likely for a remote branch than in the case of a local branch.

So why does git not warn if I delete a remote unmerged branch? And is there a way to make it warn or deny the deletion?

Note: I realize that ideally I should git pull the branch before deleting it, and make sure it is fully merged. However, everyone makes mistakes, and I'd like to have a safety net.

ks1322
  • 33,961
  • 14
  • 109
  • 164
sleske
  • 81,358
  • 34
  • 189
  • 227

2 Answers2

5

However, if I delete a remote branch via git push origin --delete mybranch, there is no warning whatsoever if the branch is not fully merged.

My response would be "merged with what?" The remote's HEAD? The master branch? Something else? Git ref matching is more or less infinitely configurable. You can configure multiple remotes. Upstream tracking branches aren't required to have the same name as their local counterparts. You can even configure multiple upstream tracking branches if you know how (it's called an "octopus" pull, and there's no porcelain command that'll let you do it).

git branch -d checks that the branch hasn't been merged with its upstream branch (something that won't exist in a remote repository) and then, if no upstream exists, HEAD. The counterpart check for a remote repository isn't nearly as obvious.

Per kan's comment, below, one might also check if deleting a remote branch generated dangling commits (so a more powerful git branch -d). I don't believe there is any protection of this type, either, and it might not be an easy thing to verify in a remote with dozens or hundreds of branches.

The best you might be able to do is prevent deletes entirely with receive.denyDeletes.

Christopher
  • 42,720
  • 11
  • 81
  • 99
  • As I understand it has a sense. The requirement could be: if a branch deletion makes a dangling commit in the repo, then don't allow to delete the branch. – kan Sep 07 '12 at 19:09
  • @kan Yeah that's right. I don't think there's any support for that type of protection. Edited the answer accordingly. For what it's worth that's not quite what `git branch -d` does. That only checks if it's fully merged with its upstream branch, or `HEAD` if no upstream is configured. – Christopher Sep 07 '12 at 19:14
0

Christopher's answer (upvoted) illustrates the difference between a local (downstream) repo and a remote (upstream) repo.
See "Definition of “downstream” and “upstream”"

An upstream repo doesn't know anything about any downstream repo, like your local repo.
It (the upstream repo) can represent anything (a remote repos used by many, or a temp repo used just for compilations and tests).
Asking the remote repo to delete a branch shouldn't be constrained by any local repo characteristic (if it were, all you need to do is to have another local repo respecting whatever constraint you want to enforce: it could delete the remote branch, even though your first local repo would still be in an incorrect state).

However, removing a local branch in your local repo can be tied to local policy you want to follow.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • _"Asking the remote repo to delete a branch shouldn't be constrained by any local repo characteristic"_: Sorry, I can't quite follow. I do not want the remote repo to "follow any local characteristic". I'd be quite content with a warning that pushing this branch deletion will cause dangling commits. That would be similar in spirit to the warning from "git branch -d", but follow a slightly different rule. – sleske Sep 11 '12 at 08:03
  • @sleske in that case, I confirm there is no such warning currently in place: either you prevent any deletion entirely, or the branch will be silently deleted on the remote repo. – VonC Sep 11 '12 at 08:08