3

The custom Git tooling that our team uses creates a branch for each new feature/bug that is worked on.

Often times when the change is nearing completion, the remote branch will be altered via another tool, leaving the local copy of the branch out-of-sync.

A question that often comes up is how to clean up all of the stale branches that are left in developers local repositories. A shortcut is desired since typing out many git branch -D branchname can be tiresome when there are dozens of these stale branches.

Some advice that I had been giving out is to delete files from their .git/refs/heads folder.

Here is the full text that I send out:

One manual trick to quickly delete branches in batch is to delete files from your .git/refs/heads folder. You will see filenames that correspond to branches. A branch is just a pointer to a sha that makes up the file's content, so deleting the file will delete the branch. Note that this will only delete the pointer, not the actual commit that the pointer happened to be pointing to.

This advice seems safe, but I am paranoid that there is a situation where this approach could fail or cause work to be lost.

Other than the user making an obvious mistake such as deleting the master file, is this safe advice?

EDIT: This question is different from this question because due to the nature of our in-house tooling, often --merged will not be sufficient to determine if a local branch is stale or not. Also, we don't want to delete branches in one-fell-swoop...a manual check for each branch needs to take place to avoid deleting still-active branches.

Jonathan.Brink
  • 19,445
  • 13
  • 59
  • 98
  • 1
    Based on my understanding, I don't thing that you would lose work by doing this. As you say, you're only deleting the heads, but the files and commits are still in tact. Worst case scenario, even if you deleted an important branch head, your reflog should still be in tact within `.git/logs/`. There is likely a preferable, tidier/neater approach that doesn't involve manually deleting files. – Chris Aug 07 '17 at 14:41
  • Possible duplicate of [How can I delete all git branches which have been merged?](https://stackoverflow.com/questions/6127328/how-can-i-delete-all-git-branches-which-have-been-merged) – smarber Aug 07 '17 at 14:42

1 Answers1

2

One pitfall is that if references have been "packed" in the past, various branch names and corresponding hash IDs will be in .git/packed-refs rather than or in addition to being in .git/refs/heads/.

If a name appears in both places, deleting the branch name B from .git/refs/heads/B simply reveals the old packed reference. If it is only in .git/packed-refs there would be no separate file to delete.

This also leaves stale reflogs behind. This might temporarily be a feature (as in the comment by Chris), though note that the reflog never contains the @{0} value, only the @{1} and higher values.

I strongly suspect that some future version of Git will abandon the one-file-per-branch-name trick entirely, since it misfires quite badly on Windows and MacOS file systems that do case-folding. It's clearly better/safer/more-future-proof to use git branch -D or git update-ref -d (note that update-ref requires spelling out the full reference name).

torek
  • 330,127
  • 43
  • 437
  • 552