36

I'm trying to use Git for our software development. I found that if I delete a branch in Git, I could lose my code forever. That surprised me. I thought as a version control system, it should be able to let me do anything (even stupid one) without worry about harming my work.

The steps below are what I did:

  1. Initialize a Git repository.
  2. commit several changes to repository.
  3. switch/checkout current working directory to first commit.
  4. delete master branch.
  5. then I lost all of my work and I can't believe what I saw. Is it real? If I am drunk while coding. I could lose the code in Git.

The question is how can I roll back the action of deleting a branch?

Or, how can I get all history in Git, even something which has disappeared in log?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Edison Chuang
  • 2,911
  • 4
  • 26
  • 28
  • 1
    If you commited it will still be there, check git reflog – James Kyburz Apr 04 '11 at 19:26
  • 2
    I hope that, even when you're drunk, you won't delete your master branch again! – Cascabel Apr 04 '11 at 22:48
  • 3
    Another tip: only use `git branch -d`, not `git branch -D`. You'll be warned if you're about to delete something that might make you lose work, then you can take a second to think before using `-D`. (Or, you can go delete from `gitk` so you really see what you're deleting.) – Cascabel Apr 04 '11 at 22:59
  • Possible duplicate of [Can I recover branch after its deletion in git?](http://stackoverflow.com/questions/3640764/can-i-recover-branch-after-its-deletion-in-git) – Steve Chambers Oct 01 '15 at 15:56
  • It is just another example of a revision control system is not a backup system or a [journaling filesystem](https://en.wikipedia.org/wiki/Journaling_file_system) (and vice versa). – Peter Mortensen Apr 10 '21 at 20:19

1 Answers1

73

To avoid the issue in the first place, Jefromi advices in the comments:

Another tip: only use git branch -d, not git branch -D.
You'll be warned if you're about to delete something that might make you lose work, then you can take a second to think before using -D.
(Or, you can go delete from gitk so you really see what you're deleting.)

-d

Delete a branch.
The branch must be fully merged in its upstream branch, or in HEAD if no upstream was set with --track or --set-upstream.


But if you did "lose" your work, see one of the many blogs about reflog (as James Kyburz suggests in the comments):

Git reflog to the rescue:

back to list Git reflog to the rescue September 09, 2010 — written by Chris Sloan | 0 comments »

The other day, I was working on a feature for Real Travel using our current branching strategy in that each release we do is a separate branch.
Not sure if it was a cause of lack of sleep from late hours pulled, but I accidentally deleted my local and remote copy of the branch before I merged it back into the master branch for release.
After a quick state of shock and thoughts running through my head of losing hours of work, I calmed down and relied on my Git knowledge.
Reading your full commit history:

There are two ways to read the commit history in git. The first way shows a list of details commits while the other shows the log in reference to the current HEAD.

// log of detailed commits by users
$> git log

// reference log compared to the current HEAD
$> git reflog

Using the reflog command, I was able to find out exactly where the last reference to my deleted branch was.
An example output of the reflog might look like this:

c7f3d98 HEAD@{0}: commit: Merged in some code
f5716c8 HEAD@{1}: pull : Fast-forward
d93c27b HEAD@{2}: commit: Added some items to project
...

Now the reflog will not show exactly where the branch was deleted, but if you remember your last commit to that branch and have a detailed enough message, it should be easy to find and restore.

Restoring your branch is straight forward by checking out the HEAD you want to a new branch.

$> git checkout -b my_new_branch HEAD@{5}

You can also use the hash too to checkout the new branch.

$> git checkout -b my_new_branch d93c27b

Simple enough and now I can move on with actually merging the branch in before deletion.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    This is great if you happen to remember what the last commit on your branch was, but I just accidentally deleted multiple local branches, and I ***don't*** remember what the last commit was on all of them, so I'm stuck sifting through literally 391 dangling commits to try and figure out which branch was on which commit :/ If you want to know how I deleted multiple branches, turns out `git fetch --prune upstream +refs/heads/*:refs/heads/*` is kind of dangerous :/ –  Sep 24 '13 at 17:41
  • 1
    I actually solved my multiple branch deletion problem fairly easily by doing a text search of `git reflog` for the names of the deleted branches, which I still have...so "KEEP CALM AND GIT REFLOG!" ;) –  Sep 24 '13 at 18:08
  • Actually, I have a deleted branch that was never checked-out into my working copy (it was created with `git branch`), so it doesn't show up in the default `git reflog`, and doing `git reflog ` results in "fatal: ambiguous argument", I guess because the branch reference was never moved after it was created. Is there some easy way to recover this branch via some method I'm not aware of, or am I going to have to search through dangling/unreachable commits? –  Sep 24 '13 at 18:16
  • @Cupcake Not sure actually, but I don't think a `@{-1}` revision reference would work here (http://stackoverflow.com/a/18954079/6309), so... that might be a good question on its own. – VonC Sep 24 '13 at 19:14
  • saved my week thanks! I though I lost it when syncing on develop with a visual studio addon – Rivenfall Nov 14 '14 at 14:04