Development Tip

Git에서 삭제 한 분기를 복구 할 수 있습니까?

yourdevel 2020. 9. 27. 14:09
반응형

Git에서 삭제 한 분기를 복구 할 수 있습니까?


을 실행 git branch -d XYZ하면 분기를 복구 할 수있는 방법이 있습니까? delete branch 명령을 실행하지 않은 것처럼 돌아가는 방법이 있습니까?


예, git reflog삭제 된 브랜치의 끝에서 커밋에 대한 SHA1을 찾아서 찾을 수 있어야합니다 git checkout [sha]. 그리고 일단 해당 커밋에 도달하면 git checkout -b [branchname]거기에서 분기를 다시 만들 수 있습니다 .


이 압축 / 원 라이너 버전에 대해 @Cascabel에 감사드립니다.

한 단계로 수행 할 수 있습니다.

git checkout -b <branch> <sha>

대부분의 경우 도달 할 수없는 커밋은 리플 로그에 있습니다. 따라서 가장 먼저 시도 할 것은 명령 git reflog(에 대한 reflog를 표시하는)을 사용하여 reflog를 살펴 보는 것HEAD 입니다.

커밋이 여전히 존재하는 특정 분기의 일부인 경우 더 쉬운 방법은 명령을 사용하는 것 git reflog name-of-my-branch입니다. 예를 들어 강제로 푸시하는 경우 (추가 조언 : 항상git push --force-with-lease 실수를 방지하고 복구 가능성이 더 높은 것을 선호하는 경우) 리모컨에서도 작동합니다 .


커밋이 reflog에없는 경우 (아마도 reflog 에 쓰지 않는 타사 도구에 의해 삭제 되었기 때문일 수 있음), 다음과 같은 명령을 사용하여 찾은 커밋의 sha로 분기를 재설정하여 분기를 성공적으로 복구했습니다. 모든 매달린 커밋으로 파일을 생성합니다) :

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

두 번 이상 사용해야하는 경우 (또는 어딘가에 저장하려는 경우) 해당 명령으로 별칭을 만들 수도 있습니다.

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'

그리고 그것을 함께 사용하십시오 git rescue

발견 된 커밋을 조사하기 위해 몇 가지 명령을 사용하여 각 커밋을 표시하여 조사 할 수 있습니다.

커밋 메타 데이터 (작성자, 생성 날짜 및 커밋 메시지)를 표시하려면 :

git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

diff도 보려면 :

git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

커밋을 찾았 으면 다음을 사용하여이 커밋에 분기를 만듭니다.

git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560

Windows에 있고 GUI를 좋아하는 사람들의 경우 기능 => => 기능을 사용하여 GitExtensions커밋 (및 커밋되지 않은 스테이징 된 파일)을 쉽게 복구 할 수 있습니다.RepositoryGit maintenanceRecover lost objects...


GUI를 사용하고 싶다면 gitk로 전체 작업을 수행 할 수 있습니다.

gitk --reflog

이렇게하면 브랜치가 삭제되지 않은 것처럼 브랜치의 커밋 내역을 볼 수 있습니다. 이제 가장 최근의 브랜치 커밋을 마우스 오른쪽 버튼으로 클릭하고 메뉴 옵션을 선택하십시오 Create new branch.


가장 많이 투표 한 솔루션은 실제로 요청한 것보다 더 많은 일을합니다.

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

또는

git checkout -b <branch> <sha>

커밋하는 것을 잊었을 수있는 모든 최근 변경 사항과 함께 새 분기로 이동합니다. 특히 분기를 잃은 후 "패닉 모드"에있을 때 이는 귀하의 의도가 아닐 수 있습니다.

깔끔하고 단순한 솔루션 은 한 줄로 보입니다 ( <sha>with 를 찾은 후 git reflog).

git branch <branch> <sha>

이제 현재 분기 나 커밋되지 않은 변경 사항이 영향을받지 않습니다. 대신 새 분기 만 <sha>.

팁이 아니라면 여전히 작동하고 더 짧은 분기 <sha>를 얻은 다음 올바르게 얻을 때까지 새 분기 이름으로 다시 시도 할 수 있습니다 .

마지막으로 성공적으로 복원 된 분기의 이름을 이름 또는 다른 이름으로 바꿀 수 있습니다.

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

말할 필요도없이 성공의 열쇠는 올바른 커밋을 찾는 것이 었 <sha>으므로 커밋의 이름을 현명하게 지정하십시오. :)


tfe 답변에 추가 : Git 소스 영역 (git.git 저장소)에 git-resurrect.sh 스크립트 contrib/있습니다.

git-resurrect <name>라는 분기 팁의 흔적을 찾고 <name>이를 부활 시키려고합니다. 현재 reflog에서 체크 아웃 메시지와 -r병합 메시지를 검색 합니다. -m하고 -t, 모든 심판의 역사를 검사 Merge <name> into other/ Merge <other> into <name>(각각) 오히려 느린하지만 당신은 다른 사람의 주제 가지를 부활 할 수있는 과목을 커밋합니다.


예를 들어 리플 로그가없는 경우. reflog가 활성화되지 않은 베어 저장소에서 작업하고 있고 복구하려는 커밋이 최근에 생성 되었기 때문에 또 다른 옵션은 최근에 생성 된 커밋 객체를 찾아서 살펴 보는 것입니다.

.git/objects디렉토리 내부에서 다음을 실행하십시오.

find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit

이는 지난 12 시간 동안 생성 된 모든 객체 (커밋, 파일, 태그 등)를 찾아서 커밋 만 표시하도록 필터링합니다. 이를 확인하는 것은 빠른 프로세스입니다.

Jakub의 답변 에서 언급 한 git-ressurect.sh 스크립트를 먼저 시도해 보겠습니다 .


들어 GitHub의 힘내없는 사용자가 설치 :

GitHub 웹 사이트 에서 복원 하려면 API사용하여 저장소 관련 이벤트 목록을 가져올 수 있습니다.

먼저

  • 해당 SHA (커밋 해시)를 찾습니다.

    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.


I used the following commands to find and retrieve my deleted branch. The first steps are from gcb's description.

$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\  -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline

Now look for the git commit id (GIT-SHA) based on the commit comments and use it in the command below. Checkout a new branch called NEW-BRANCH with the previously found GIT-SHA:

$ git checkout -b NEW-BRANCH GIT-SHA

From my understanding if the branch to be deleted can be reached by another branch, you can delete it safely using

git branch -d [branch]

and your work is not lost. Remember that a branch is not a snapshot, but a pointer to one. So when you delete a branch you delete a pointer.

You won't even lose work if you delete a branch which cannot be reached by another one. Of course it won't be as easy as checking out the commit hash, but you can still do it. That's why Git is unable to delete a branch which cannot be reached by using -d. Instead you have to use

git branch -D [branch]

This is part of a must watch video from Scott Chacon about Git. Check minute 58:00 when he talks about branches and how delete them.

Introduction to Git with Scott Chacon of GitHub


For recovering a deleted branch, First go through the reflog history,

git reflog -n 60

Where n refers to the last n commits. Then find the proper head and create a branch with that head.

git branch testbranch HEAD@{30}

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.


Make sure to perform all of this locally, and confirm your repo is in the state you desire before pushing to Bitbucket Cloud. It may also be a good idea to clone your current repo, and test these solutions out first.

  1. If you just deleted the branch, you'll see something like this in your terminal:
    Deleted branch <your-branch> (was <sha>)

2.To restore the branch, use:

    git checkout -b <branch> <sha>

If you don't know the 'sha' off the top of your head, you can:

  1. Find the 'sha' for the commit at the tip of your deleted branch using:
    git reflog
  1. To restore the branch, use:
    git checkout -b <branch> <sha>

If your commits are not in your reflog:

  1. You can try recovering a branch by reseting your branch to the sha of the commit found using a command like:
    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

2.You can then display each commit using one of these:

    git log -p <commit>
    git cat-file -p <commit>

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


First go to git batch the move to your project like :

cd android studio project
cd Myproject
then type :
git reflog

You all have a list of the changes and the reference number take the ref number then checkout
from android studio or from the git betcha. another solution take the ref number and go to android studio click on git branches down then click on checkout tag or revision past the reference number then lol you have the branches.


Adding to tfe's answer, you can recover with this process mentioned, unless it's commits are not garbage collected. Git branch is simply a pointer to a particular commit in the commit tree. But if you delete the pointer, and the commits on that branch are not merged into other existing branch, then git treats it as dangling commits and removes them during garbage collection, which it may run automatically periodically.

If your branch wasn't merged to an existing branch, and if it was garbage collected, then you will loose all commits up until the point from where branch was forked from an existing branch.


A related issue: I came to this page after searching for "how to know what are deleted branches".

While deleting many old branches, felt I mistakenly deleted one of the newer branches, but didn't know the name to recover it.

To know what branches are deleted recently, do the below:

If you go to your Git URL, which will look something like this:

https://your-website-name/orgs/your-org-name/dashboard

Then you can see the feed, of what is deleted, by whom, in the recent past.


Just using git reflog did not return the sha for me. Only the commit id (which is 8 chars long and a sha is way longer)

So I used git reflog --no-abbrev

And then do the same as mentioned above: git checkout -b <branch> <sha>


지점을 삭제 한 컴퓨터에서이 작업을 수행했습니다.

git reflog

응답:

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

이 명령으로 분기를 검색합니다.

git checkout -b newBranchName 74b2383

참고 URL : https://stackoverflow.com/questions/3640764/can-i-recover-a-branch-after-its-deletion-in-git

반응형