--force
옵션을 사용하여 프로젝트에 잘못된 소스를 커밋했습니다 .
되돌릴 수 있습니까? -f
옵션을 사용하여 이전 분기를 모두 덮어 썼다는 것을 알고 있으므로 이전 개정판을 망 쳤을 수 있습니다.
--force
옵션을 사용하여 프로젝트에 잘못된 소스를 커밋했습니다 .
되돌릴 수 있습니까? -f
옵션을 사용하여 이전 분기를 모두 덮어 썼다는 것을 알고 있으므로 이전 개정판을 망 쳤을 수 있습니다.
답변:
Git은 일반적으로 아무것도 버리지 않지만 여기서 복구하는 것은 여전히 까다로울 수 있습니다.
소스가 올바른 경우 --force
옵션 을 사용하여 원격으로 푸시 할 수 있습니다. Git은 당신이 지시하지 않는 한 어떤 브랜치를 삭제하지 않을 것입니다. 실제로 커밋을 잃어버린 경우 커밋 복구 에 대한 유용한 가이드를 참조하십시오 . 원하는 커밋의 SHA-1을 알고 있다면 괜찮을 것입니다.
최선의 방법 : 모든 것을 백업하고 로컬 저장소에 아직 무엇이 있는지 확인하십시오. 가능하면 리모컨에서도 똑같이하십시오. git fsck
복구 할 수 있는지 확인하기 위해 사용 하고 무엇보다도 실행하지 마십시오git gc
.
무엇보다도 --force
, 정말로 진심이 아니라면 옵션을 사용하지 마십시오 .
git reflog show remotes/origin/master
. 당신은 거기에서 당신의 푸시를 볼 수있을 것입니다; 이전 줄의 커밋은 당신이 그것을 엉망으로 만들기 전에 있었던 곳입니다. 그런 다음 해당 개정판 (사용 --force
)을 원래 위치로 푸시하고 원래 위치로 돌아갈 수 있습니다!
git fetch
오랜 시간 동안 편집 하지 않았 음)이라도 GitHub 측의 reflog를 표시하고 복구 할 수 있습니다!
커밋 해시를 알고 있다면 간단합니다. 브랜치를 다시 만드십시오.
5794458...b459f069 master -> master (forced update)
원격 분기를 삭제합니다.
git push origin :master
그런 다음 다음 명령으로 분기를 다시 만듭니다.
git checkout 5794458
git branch master
git push origin master
# work on local master
git checkout master
# reset to the previous state of origin/master, as recorded by reflog
git reset --hard origin/master@{1}
# at this point verify that this is indeed the desired commit.
# (if necessary, use git reflog to find the right one, and
# git reset --hard to that one)
# finally, push the master branch (and only the master branch) to the server
git push -f origin master
git reflog show remotes/origin/master
git reflog가 필요한 경우 (위의 @Cascabel에서 언급했듯이)
강제 푸시가 발생한 로컬 리포지토리에 있지 않은 경우 원본 / 마스터 수준에서 복구 할 방법이 없습니다. 당신이하지만 운이 사용하기에 충분한 GitHub의 또는 기업에 대한 GitHub의를 , 당신은에보고 할 수 있습니다 REST의 API를 패치, 예를 들어 커밋 손실 검색 :
https://api.github.com/repos/apache/logging-log4j2/commits/889232e28f3863d2a17392c06c1dd8cac68485de
git apply patch.patch && git commit -m "restored commit"&& git push origin master
이전 푸시가 로컬 리포지토리에서 제공되지 않은 경우 손실 된 커밋을 복구하거나 손실 된 커밋을 파악하는 또 다른 방법은 CI 머신을 살펴 보는 것입니다.
모든 커밋 (또는 일련의 연속 커밋) 후에 마스터 브랜치를 테스트하는 작업이 있다면, 마지막으로 테스트 한 것을 볼 수 있습니다. 이것이 복원해야 할 커밋입니다.
CI 머신은이 복구를 수행 할 수있는 저장소의 로컬 복제본을 유지할 수도 있습니다.
출처 : 지속적인 제공 : 빌드, 테스트 및 배포 자동화를 통한 신뢰할 수있는 소프트웨어 릴리스 (Addison-Wesley Signature Series (Fowler))
예, 이후 커밋을 복구 할 수 있습니다. git push -f your_branch
문서의 텍스트 :
지정된 시간보다 오래된 항목을 정리합니다. 이 옵션을 지정하지 않으면 구성 설정 gc.reflogExpire에서 만료 시간을 가져 오며 기본값은 90 일입니다. --expire = 연령에 관계없이 모든 항목을 정리합니다. --expire = 접근 가능한 항목의 정리를 끄지 않습니다 (그러나 --expire-unreachable 참조).
따라서 다음을 수행 할 수 있습니다.
1- git reflog
2- 당신은 Head_Number를 선택하여 복구를 원하십니까 git reset –hard HEAD@{HEAD-NUMBER}
3-이 머리에 대한 모든 커밋을 볼 수 있습니다. git cherry -v branch_name
4- 결국 강제로 밀어야합니다. git push -f branch_name
또는
1- GIT 클라이언트 (인터페이스)에서 SHA 수 가져 오기
git reset --hard commit_SHA
2- 강제 밀기
git push -f your_branch
도움이 되었기를 바랍니다
하나의 파일에 대한 마지막 푸시를 실행 취소하면서 동일한 작업을 수행했습니다. 결국 저장소의 원래 상태로 돌아갑니다. Linux에서 로컬 사본이 있으므로 Linus의 git 명령을 사용했습니다. 다행히도 그 사본은 여전히 손상되지 않았습니다.
내가 한 것은 (로컬 리포지토리의 복사본을 광적으로 몇 개 더 만든 후) :
git add .
git status
(오리진 / 마스터가 68 개의 커밋보다 앞서 있다고 말했습니다. 좋아요 ... 내가 삭제 한 모든 커밋이었습니다)
git remote set-url origin <GIT_SSH_URL>
git push
그리고 모든 것이 내가 강하게 밀기 전의 방식으로 복원되었습니다. 기억해야 할 가장 중요한 것은 git checkout을하지 않는 것입니다. 강하게 밀고 나서. 그러나 가장 좋은 방법은 푸시 옵션을 비활성화하는 것입니다. 다시는 사용하지 않습니다. 나의 교훈을 배웠다 !!
여기에서 결정을 읽을 수 있습니다 https://evilmartians.com/chronicles/git-push---force-and-how-to-deal-with-it
두 번째는 나를 도왔다. 나는이 명령을 잘못했다
1) (some-branch) git pull -> correct command was git pull origin some-branch
2) (some-branch) git push -f origin some-branch
이 명령 후에 나는 세 개의 커밋을 잃었습니다. 그들을 복구하기 위해 나는 잘못 'git pull'한 터미널을 보았고 거기에서 다음과 같은 출력을 보았습니다.
60223bf ... 0b258eb 일부 분기-> 원산지 / 일부 분기
두 번째 해시 0b258eb는 정확히 필요한 것입니다. 그래서이 해시를 가져 와서
git push --force origin 0b258eb:some-branch
저와 같이 정말 나쁜 상황에 처한 사람들의 경우 (예 : bad object
실행할 때 오류 가 발생하는 경우 git reset --hard
) :
마지막 수단으로 GitHub API에서 모든 파일을 가져 오는 treesaver라는 스크립트를 작성 했습니다 . 사용 방법은 다음과 같습니다.
treesaver
스크립트를 복제하십시오 cd
.SHA
에 액세스하여 복원 할 트리 문자열을
찾습니다 https://api.github.com/repos/<your_username_or_org>/<repo>/events
.payload
푸시 이벤트에 해당 하는 속성 commit
에서 되돌리려 는 을 찾아 해당 url
.commit.tree
에서 tree
의 url
.python3 main.py <tree_url> <path_to_save_to>
합니다.예를 들어, 제 경우에는 다음을 실행합니다.
python3 main.py https://api.github.com/repos/anthonykrivonos/my-repo/git/trees/1234567 .
물론 PR도 환영합니다.