Coming from svn, just starting to become familiar with git.
When a branch is deleted in git, is it removed from the history?
In svn, you can easily recover
Branches are just pointers to commits in git. In git each commit has a complete source tree, it is a very different structure from svn where all branches and tags (by convention) live in separate 'folders' of the repository alongside the special 'trunk'.
If the branch was merged into another branch before it was deleted then all of the commits will still be reachable from the other branch when the first branch is deleted. They remain exactly as they were.
If the branch is deleted without being merged into another branch then the commits in that branch (up until the point where the forked from a commit that is still reachable) will cease to be visible.
The commits will still be retained in the repository and it is possible to recover them immediately after the delete, but eventually they will be garbage collected.
If you are worried about accidentally deleted branches and do not have a local copy of your repo any longer, there are extensions to enterprise Git servers like Gerrit that will detect history rewrites and branch deletions, will back them up under a special ref so that they can be restored if needed and will not be pruned by garbage collection. Gerrit administrators can still remove selected commits if needed for legal reasons.
In Git, branches are just pointers (references) to commits in a directed acyclic graph (DAG) of commits. This means that deleting a branch removes only references to commits, which might make some commits in the DAG unreachable, thus invisible. But all commits that were on a deleted branch would still be in the repository, at least until unreachable commits get pruned (e.g. using git gc
).
Note that git branch -d
would refuse to delete a branch if it cannot be sure that deleting it wouldn't leave unreachable commits. You need to use the stronger git branch -D
to force deletion of a branch if it might leave unreachable commits.
Note also that unreachable commits, if they are present, are only those commits between the last tip of a deleted branch and either a commit that got merged to another existing branch, any tagged commit, or the branching point; whichever is later. For example in the following situation:
----O----*----*----/M----* <-- master <-- HEAD \ / \--.----.--/--x---y <-- deleted branch
only commits 'x' and 'y' would become unreachable after deleting the branch.
If you operated on a deleted branch within the gc.reflogExpire
period, default 90 days, you would have the last tip of a deleted branch recorded in HEAD reflog (see git reflog show HEAD
, or git log --oneline --walk-reflogs HEAD
). You should be able to use HEAD reflog to recover the deleted pointer. Note also that in this case, unreachable commits in just a deleted branch would be protected from pruning (removing) within the gc.reflogExpireUnreachable
period, which by default is 30 days.
If you can't find the tip of a just deleted branch in reflog for HEAD, you can try to use git fsck
to find "unreachable commit <sha1>", and examine those (via git show <sha1>
or git log <sha1>
) to find the tip of the deleted branch.
Independent on how you find the tip of a deleted branch, you can undo deletion, or rather re-create a just deleted branch using
git branch <deleted-branch> <found-sha1-id>
Note however that reflog for a branch would be lost.
There is also git-resurrect.sh script in contrib/
which helps find traces of a branch tip with given name and resurrect (undelete) it.