Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: Deny deleting remote branch via push (like receive.denyDeletes), but only if branch is not fully merged

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.

like image 451
sleske Avatar asked Sep 07 '12 15:09

sleske


People also ask

Why does git say branch is not fully merged?

There are times when you get an “not fully merged” error for a git branch, usually when trying to delete a local branch from your machine. It's a safe bet that something in your local branch has not actually made it to the remote repository and we should do some investigating.

How do I force delete a branch?

Delete a branch with git branch -d <branch> . The -d option will delete the branch only if it has already been pushed and merged with the remote branch. Use -D instead if you want to force the branch to be deleted, even if it hasn't been pushed or merged yet. The branch is now deleted locally.

Does git push push all branches?

No, git push only pushes commits from current local branch to remote branch that you specified in command.


1 Answers

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.

like image 186
Christopher Avatar answered Sep 23 '22 14:09

Christopher