Can I recover a branch after its deletion in Git?

后端 未结 20 2114
广开言路
广开言路 2020-11-22 05:53

If I run git branch -d XYZ, is there a way to recover the branch? Is there a way to go back as if I didn\'t run the delete branch command?

相关标签:
20条回答
  • 2020-11-22 06:24

    Most of the time unreachable commits are in the reflog. So, the first thing to try is to look at the reflog using the command git reflog (which display the reflog for HEAD).

    Perhaps something easier if the commit was part of a specific branch still existing is to use the command git reflog name-of-my-branch. It works also with a remote, for example if you forced push (additional advice: always prefer git push --force-with-lease instead that better prevent mistakes and is more recoverable).


    If your commits are not in your reflog (perhaps because deleted by a 3rd party tool that don't write in the reflog), I successfully recovered a branch by reseting my branch to the sha of the commit found using a command like that (it creates a file with all the dangling commits):

    git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt
    

    If you should use it more than one time (or want to save it somewhere), you could also create an alias with that command...

    git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\  -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'
    

    and use it with git rescue

    To investigate found commits, you could display each commit using some commands to look into them.

    To display the commit metadata (author, creation date and commit message):

    git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
    

    To see also the diffs:

    git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
    

    Once you found your commit, then create a branch on this commit with:

    git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560
    

    For the ones that are under Windows and likes GUIs, you could easily recover commits (and also uncommited staged files) with GitExtensions by using the feature Repository => Git maintenance => Recover lost objects...


    A similar command to easily recover staged files deleted: https://stackoverflow.com/a/58853981/717372

    0 讨论(0)
  • 2020-11-22 06:27

    BIG YES

    if you are using GIT follow these simple steps https://confluence.atlassian.com/bbkb/how-to-restore-a-deleted-branch-765757540.html

    if you are using smartgit and already push that branch go to origin, find that branch and right click then checkout

    0 讨论(0)
  • 2020-11-22 06:28

    I rebased a branch from remote to try to clear a few commits I didn't want and was going to cherrypick the right ones that I wanted. Of course I wrote the SHAs wrong...

    Here is how I found them (mostly an easier interface/interaction from things on answers here):

    First, generate a list of loose commits in your log. Do this as soon as possible and stop working, as those may be dumped by the garbage collector.

    git fsck --full --no-reflogs --unreachable --lost-found > lost
    

    This creates a lost file with all the commits you will have to look at. To simplify our life, let's cut only the SHA from it:

    cat lost | cut -d\  -f3 > commits
    

    Now you have a commits file with all the commits you have to look.

    Assuming you are using Bash, the final step:

    for c in `cat commits`; do  git show $c; read; done
    

    This will show you the diff and commit information for each of them. And wait for you to press Enter. Now write down all the ones you want, and then cherry-pick them in. After you are done, just Ctrl-C it.

    0 讨论(0)
  • 2020-11-22 06:29

    The top voted solution does actually more than requested:

    git checkout <sha>
    git checkout -b <branch>
    

    or

    git checkout -b <branch> <sha>
    

    move you to the new branch together with all recent changes you might have forgot to commit. This may not be your intention, especially when in the "panic mode" after losing the branch.

    A cleaner (and simpler) solution seems to be the one-liner (after you found the <sha> with git reflog):

    git branch <branch> <sha>
    

    Now neither your current branch nor uncommited changes are affected. Instead only a new branch will be created all the way up to the <sha>.

    If it is not the tip, it'll still work and you get a shorter branch, then you can retry with new <sha> and new branch name until you get it right.

    Finally you can rename the successfully restored branch into what it was named or anything else:

    git branch -m <restored branch> <final branch>
    

    Needless to say, the key to success was to find the right commit <sha>, so name your commits wisely :)

    0 讨论(0)
  • 2020-11-22 06:29

    I did this on the computer which i delete the branch:

    git reflog

    response:

    74b2383 (develope) HEAD@{1}: checkout: moving from master to develope
    40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: checkout: moving from develope to master
    74b2383 (develope) HEAD@{3}: checkout: moving from master to develope
    40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{4}: reset: moving to HEAD
    40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git
    

    and i retrieve the branch with this command:

    git checkout -b newBranchName 74b2383

    0 讨论(0)
  • 2020-11-22 06:30

    For GitHub users without Git installed:

    If you want to restore it from GitHub website, you can use their API to get a list of repo-related events:

    First

    • find those SHAs (commit hashes):

      curl -i https://api.github.com/repos/PublicUser/PublicRepo/events

      ... or for private repos:

      curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events

      (will be prompted for GitHub password)

      • (If the repo rquires two-factor auth, see the comments on this answer below.)

    Next

    • go to GitHub and create a new temporary branch which will be deleted for ever (Chrome is preferable).

       •  Go to branches and delete that one.

       •  On the same page, without reloading, open DevTools, Network panel. Now prepare...

       •  Click restore. You will notice a new "line". Right-click on it and select "Copy as cURL" and save this text in some editor.

       •  Append to the end of the copied line of code, this one: -H "Cookie=".

    You should now get something like:

        curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed
    

    Final step

    • replace "BranchSHA" with your SHA-hash and BranchName with desired name (BTW, it is great hack to rename branch from web). If you were not too slow, you need to make this request anyhow. For example, just copy-paste to a terminal.

    P.S.

    I realize this may not be the "simplest solution" or the "right" solution, but it is offered in case someone finds it useful.

    0 讨论(0)
提交回复
热议问题