I would flip the question. Why would you keep branches which has already been merged in?
While it can make sense to keep old branches for a while, after some time the main branch has deviated so much, that the knowledge held in the older branches (which have already been merged in!) is not that useful.
I, personally, would recommend to not keep older PR branches around, since I have rarely found it useful.
You can configure GitHub repos to auto-delete the remote branch when a PR is merged, and I think you can configure git to delete tracking branches locally when that happens (How Core Git Developers Configure Git)
Well, I usually sqash the branch of a pull request before merging it. But sometimes a bug squeezed in, and then it is useful to undo just the one commit that caused the bug.
If really needed you can restore a branch after it has been deleted using GitHub UI.
One big reason for deleting all branches of merged and closed PRs is that when cloning a repository all branches are fetched, fetching branches that aren’t going to be used for literally anything is a big waste of everybody’s bandwidth.
They don’t officially promise not to garbage-collect, but it’s pretty well-established that GitHub never ever deletes anything. It would mess majorly with their entire infrastructure if they changed that. So it’s a pretty safe assumption.
Well, I can’t speak for future GitHub’s plans, but that’s what it is now.
They don’t do that. In the backend GitHub doesn’t have a standard git repo, but a rather sophisticated “database” which can interact with standard git clients.
You should still be able to fetch the ref of a PR.
There seem to be some misconceptions on what a branch is. As far as I understand, a branch has no internal meaning to git. Instead it is just a convenient way to (temporary) name a particular stream of commits (see here for details). I.e., as also explained in this stackoverflow post deleting a branch just deletes the corresponding file in .git/refs/heads/<mybranch> which only content was a git hash referring to the commit currently named <mybranch>.
Thus, you can always delete and restore branches (from any commit) at will. Internally, git only cares about commits and deleting those is more complicated and requires rewriting the git history.
Sorry but I have to nitpick your post, there are dangerous statements there.
It’s true that a branch is only a pointer to a commit.
It’s true that deleted branches can be recreated from the last commit in that branch - provided that the commit still exists.
When you delete a branch, any commits that were unique to that branch become “unreachable”, and are only accessible by commit hash/id (which can be found in the reflog for 30 days, by default).
Unreachable commits (i.e. not tagged or in a branch) more than 30 days old are permanently deleted when git performs garbage collection.
So branches cannot “always” be restored at will - only for 30 days, or if the commits exist in ancestor trees of other branches and tags.
Deleting commits isn’t complicated. Delete all branches they occur in and they’ll be gone in the next garbage collection after 30 days.
A git rebase is often called “rewriting history”, but it doesn’t actually rewrite anything. It creates new commits and makes the old ones unreachable, but you can still find them in the reflog (for 30 days).
Thanks for clarifying that branches still matter as references to commits, i.e., in order to render them reachable. Yet, in the end it’s the structure of commits that matters and a commit from a merged branch (as in the OP) stays reachable even after deleting its branch, i.e., name. Also “delete all branches they occur in” might not be easy to do (or imply deleting main and most of the repo) when the commit is part of a long merged history. In this case, it must probably be made unreachable explicitly by creating essentially a new chain of commits around it, e.g., via git rebase.
and a commit from a merged branch (as in the OP) stays reachable even after deleting its branch,
The OP specifically said they are squash merging. Are the commits of squashed pr considered ancestors of the merge commit? I always assumed squash merge means to „copy“ the pr, sqash history and merge a single squashed commit. Or is squash merging something more clever?
Sorry had missed that part. Guess you are right, squashing simply creates a new commit and leaves the old ones dangling.
Should stop commenting on that thread. At least for me the discussion has cleared some things up, though.