다음 명령으로 인한 변경 사항을 취소할 수 있습니까? 그렇다면 어떻게?
git reset --hard HEAD~1
질문자 :Paul Wicks
다음 명령으로 인한 변경 사항을 취소할 수 있습니까? 그렇다면 어떻게?
git reset --hard HEAD~1
팻 노츠가 맞습니다. 며칠 이내라면 커밋을 되돌릴 수 있습니다. git은 새 얼룩을 제거하도록 명시적으로 지시하지 않는 한 약 한 달 정도 후에 가비지 수집만 합니다.
$ git init Initialized empty Git repository in .git/ $ echo "testing reset" > file1 $ git add file1 $ git commit -m 'added file1' Created initial commit 1a75c1d: added file1 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file1 $ echo "added new file" > file2 $ git add file2 $ git commit -m 'added file2' Created commit f6e5064: added file2 1 files changed, 1 insertions(+), 0 deletions(-) create mode 100644 file2 $ git reset --hard HEAD^ HEAD is now at 1a75c1d... added file1 $ cat file2 cat: file2: No such file or directory $ git reflog 1a75c1d... HEAD@{0}: reset --hard HEAD^: updating HEAD f6e5064... HEAD@{1}: commit: added file2 $ git reset --hard f6e5064 HEAD is now at f6e5064... added file2 $ cat file2 added new file
예에서 file2가 하드 리셋의 결과로 제거되었지만 reflog를 통해 리셋할 때 다시 제자리에 놓이는 것을 볼 수 있습니다.
당신이하고 싶은 것은 복원하려는 커밋의 sha1을 지정하는 것입니다. git reflog
)를 검사한 다음 다음을 수행하여 sha1을 얻을 수 있습니다.
git reset --hard <sha1 of desired commit>
그러나 너무 오래 기다리지 마십시오... 몇 주 후에 git은 결국 해당 커밋을 참조되지 않은 것으로 보고 모든 blob을 삭제합니다.
답변은 위의 자세한 답변에 숨겨져 있습니다. 간단히 다음을 수행할 수 있습니다.
$> git reset --hard HEAD@{1}
(git reflog show 출력 참조)
Git이 아직 가비지 수집되지 않은 경우 복구할 수 있습니다.
fsck
하여 매달린 커밋에 대한 개요를 확인합니다.
$ git fsck --lost-found dangling commit b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
rebase를 사용하여 댕글링 커밋을 복구합니다.
$ git rebase b72e67a9bb3f1fc1b64528bcce031af4f0d6fcbf
내가 아는 한 --hard
는 커밋되지 않은 변경 사항을 버립니다. git에서 추적하지 않기 때문입니다. discarded commit
취소할 수 있습니다.
$ git reflog
윌은 다음을 나열합니다:
b0d059c HEAD@{0}: reset: moving to HEAD~1 4bac331 HEAD@{1}: commit: added level introduction.... ....
여기서 4bac331
은 discarded commit
입니다.
이제 머리를 해당 커밋으로 이동하십시오.
$ git reset --hard 4bac331
나처럼 정말 운이 좋다면 텍스트 편집기로 돌아가서 '실행 취소'를 누를 수 있습니다.
나는 그것이 실제로 적절한 대답이 아니라는 것을 알고 있지만 반나절의 작업을 절약 했으므로 다른 사람에게도 똑같이 할 수 있기를 바랍니다!
명령을 실행할 때 저장소의 상태에 따라 git reset --hard
의 효과는 사소한 것에서 실행 취소, 기본적으로 불가능에 이르기까지 다양할 수 있습니다.
아래에는 다양한 가능한 시나리오와 이러한 시나리오에서 복구할 수 있는 방법이 나와 있습니다.
이 상황은 일반적으로 git reset --hard HEAD~
에서와 같이 인수와 함께 git reset
을 실행할 때 발생합니다. 걱정하지 마세요. 이것은 쉽게 복구할 수 있습니다!
방금 git reset
실행하고 그 이후로 다른 작업을 수행하지 않은 경우 이 한 줄짜리로 원래 위치로 돌아갈 수 있습니다.
git reset --hard @{1}
이것은 마지막으로 수정되기 전의 상태에 관계없이 현재 분기를 재설정합니다(귀하의 경우 분기에 대한 가장 최근 수정은 실행 취소하려는 하드 재설정이 될 것입니다).
그러나, 당신은 리셋 이후 지점에 다른 수정을 한 경우, 한 줄 위에서 작동하지 않습니다. 대신 git reflog
<branchname>
을 실행하여 분기에 적용된 모든 최근 변경 사항(재설정 포함) 목록을 확인해야 합니다. 그 목록은 다음과 같이 보일 것입니다:
7c169bd master@{0}: reset: moving to HEAD~ 3ae5027 master@{1}: commit: Changed file2 7c169bd master@{2}: commit: Some change 5eb37ca master@{3}: commit (initial): Initial commit
이 목록에서 "실행 취소"하려는 작업을 찾습니다. 위의 예에서 첫 번째 줄은 "재설정: HEAD로 이동~"으로 표시됩니다. 그런 다음 해당 작업 이전 (아래) 커밋 표현을 복사합니다. 우리의 경우 master@{1}
(또는 3ae5027
, 둘 다 동일한 커밋을 나타냄)이고 git reset --hard <commit>
을 실행하여 현재 분기를 해당 커밋으로 다시 재설정합니다.
git add
하여 변경 사항을 준비했지만 커밋하지 않았습니다. 이제 내 변경 사항이 사라졌습니다! 이것은 복구하기가 조금 더 까다롭습니다. git 에는 추가한 파일의 복사본이 있지만 이러한 복사본은 특정 커밋에 연결되지 않았기 때문에 변경 사항을 한 번에 모두 복원할 수 없습니다. 대신 git 데이터베이스에서 개별 파일을 찾아 수동으로 복원해야 합니다. git fsck
사용하여 이 작업을 수행할 수 있습니다.
이에 대한 자세한 내용 은 스테이징 영역에 커밋되지 않은 파일이 있는 Undo git reset --hard를 참조하십시오.
git add
스테이징하지 않고 커밋하지 않은 작업 디렉토리의 파일이 변경되었습니다. 이제 내 변경 사항이 사라졌습니다! 어 오. 이런 말 하기 싫지만 아마 운이 나빴을 겁니다. git은 추가하거나 커밋하지 않은 변경 사항을 저장하지 않으며 git reset
에 대한 설명서에 따라 다음을 수행합니다.
--딱딱한
인덱스 및 작업 트리를 재설정합니다.
<commit>
이후 작업 트리에서 추적된 파일에 대한 모든 변경 사항은 무시됩니다.
일종의 디스크 복구 유틸리티나 전문 데이터 복구 서비스를 사용하여 변경 사항을 복구할 수도 있지만 이 시점에서는 가치 있는 것보다 더 많은 문제가 있을 수 있습니다.
$ git fsck --lost-found
Checking object directories: 100% (256/256), done. Checking objects: 100% (3/3), done. dangling blob 025cab9725ccc00fbd7202da543f556c146cb119 dangling blob 84e9af799c2f5f08fb50874e5be7fb5cb7aa7c1b dangling blob 85f4d1a289e094012819d9732f017c7805ee85b4 dangling blob 8f654d1cd425da7389d12c17dd2d88d318496d98 dangling blob 9183b84bbd292dcc238ca546dab896e073432933 dangling blob 1448ee51d0ea16f259371b32a557b60f908d15ee dangling blob 95372cef6148d980ab1d7539ee6fbb44f5e87e22 dangling blob 9b3bf9fb1ee82c6d6d5ec9149e38fe53d4151fbd dangling blob 2b21002ca449a9e30dbb87e535fbd4e65bac18f7 dangling blob 2fff2f8e4ea6408ac84a8560477aa00583002e66 dangling blob 333e76340b59a944456b4befd0e007c2e23ab37b dangling blob b87163c8def315d40721e592f15c2192a33816bb dangling blob c22aafb90358f6bf22577d1ae077ad89d9eea0a7 dangling blob c6ef78dd64c886e9c9895e2fc4556e69e4fbb133 dangling blob 4a71f9ff8262701171d42559a283c751fea6a201 dangling blob 6b762d368f44ddd441e5b8eae6a7b611335b49a2 dangling blob 724d23914b48443b19eada79c3eb1813c3c67fed dangling blob 749ffc9a412e7584245af5106e78167b9480a27b dangling commit f6ce1a403399772d4146d306d5763f3f5715cb5a <- it's this one
$ git show f6ce1a403399772d4146d306d5763f3f5715cb5a
commit f6ce1a403399772d4146d306d5763f3f5715cb5a Author: Stian Gudmundsen Høiland <stian@Stians-Mac-mini.local> Date: Wed Aug 15 08:41:30 2012 +0200 *MY COMMIT MESSAGE IS DISPLAYED HERE* diff --git a/Some.file b/Some.file new file mode 100644 index 0000000..15baeba --- /dev/null +++ b/Some.file *THE WHOLE COMMIT IS DISPLAYED HERE*
$ git rebase f6ce1a403399772d4146d306d5763f3f5715cb5a
First, rewinding head to replay your work on top of it... Fast-forwarded master to f6ce1a403399772d4146d306d5763f3f5715cb5a.
git reflog
git cherry-pick <the sha>
아직 저장소를 가비지 수집하지 않은 경우(예: git repack -d
또는 git gc
하지만 가비지 수집도 자동으로 발생할 수 있음) 커밋은 여전히 존재합니다. 더 이상 HEAD를 통해 연결할 수 없습니다.
git fsck --lost-found
의 출력을 살펴봄으로써 커밋을 찾을 수 있습니다.
최신 버전의 Git에는 "reflog"라는 항목이 있는데, 이는 refs에 대한 모든 변경 사항의 로그입니다(리포지토리 내용에 대한 변경 사항과 반대). 예를 들어 HEAD를 전환할 때마다(즉, 분기를 전환하기 git checkout
그리고 물론 git reset
도 HEAD를 조작했으므로 기록되었습니다. git reset HEAD@{1}
와 같이 ~
@
기호를 사용하여 저장소의 이전 상태에 액세스할 수 있는 것과 유사한 방식으로 참조의 이전 상태에 액세스할 수 있습니다.
HEAD@{1}와 HEAD~1의 차이점을 이해하는 데 시간이 좀 걸렸으므로 여기에 약간의 설명이 있습니다.
git init git commit --allow-empty -mOne git commit --allow-empty -mTwo git checkout -b anotherbranch git commit --allow-empty -mThree git checkout master # This changes the HEAD, but not the repository contents git show HEAD~1 # => One git show HEAD@{1} # => Three git reflog
따라서 HEAD~1
은 "HEAD가 현재 가리키는 커밋 전에 커밋으로 이동"을 의미하고 HEAD@{1}
는 "HEAD가 현재 가리키는 위치를 가리키기 전에 HEAD가 가리킨 커밋으로 이동"을 의미합니다.
그러면 잃어버린 커밋을 쉽게 찾고 복구할 수 있습니다.
JetBrains IDE(IntelliJ 기반)를 사용하는 경우 "로컬 기록" 기능을 통해 커밋되지 않은 변경 사항도 복구할 수 있습니다.
파일 트리에서 최상위 디렉토리를 마우스 오른쪽 버튼으로 클릭하고 컨텍스트 메뉴에서 "로컬 기록"을 찾은 다음 "기록 표시"를 선택합니다. 이렇게 하면 최근 편집 내용을 찾을 수 있는 보기가 열리며, 되돌리려는 개정을 찾았으면 해당 버전을 마우스 오른쪽 버튼으로 클릭하고 "되돌리기"를 클릭합니다.
HEAD
가 무엇인지 설명하면서 배경을 추가할 수 있습니다.
First of all what is HEAD?
HEAD
는 단순히 현재 분기의 현재 커밋(최신)에 대한 참조입니다.
주어진 시간에 HEAD
만 있을 수 있습니다. ( git worktree
제외)
HEAD
의 내용은 .git/HEAD
내부에 저장되며 현재 커밋의 40바이트 SHA-1을 포함합니다.
detached HEAD
최신 커밋에 있지 않은 경우 - HEAD
가 기록의 이전 커밋을 가리키고 detached HEAD
라고 합니다.
HEAD
가 현재 분기의 끝을 가리키지 않기 때문에 분기 이름 대신 SHA-1과 같이 표시됩니다.
git checkout
git checkout <commit_id> git checkout -b <new branch> <commit_id> git checkout HEAD~X // x is the number of commits t go back
이것은 원하는 커밋을 가리키는 새 분기를 체크아웃합니다.
이 명령은 주어진 커밋을 체크아웃합니다.
이 시점에서 브랜치를 생성하고 이 시점부터 작업을 시작할 수 있습니다.
# Checkout a given commit. # Doing so will result in a `detached HEAD` which mean that the `HEAD` # is not pointing to the latest so you will need to checkout branch # in order to be able to update the code. git checkout <commit-id> # create a new branch forked to the given commit git checkout -b <branch name>
git reflog
reflog
도 항상 사용할 수 있습니다.
git reflog
HEAD
를 업데이트한 변경 사항을 표시하고 원하는 reflog 항목을 체크아웃하면 HEAD
가 이 커밋으로 다시 설정됩니다.
HEAD가 수정될 때마다 reflog
git reflog git checkout HEAD@{...}
이렇게 하면 원하는 커밋으로 돌아갑니다.
git reset HEAD --hard <commit_id>
원하는 커밋으로 머리를 "이동"하십시오.
# This will destroy any local modifications. # Don't do it if you have uncommitted work you want to keep. git reset --hard 0d1d7fc32 # Alternatively, if there's work to keep: git stash git reset --hard 0d1d7fc32 git stash pop # This saves the modifications, then reapplies that patch after resetting. # You could get merge conflicts, if you've modified things which were # changed since the commit you reset to.
git rebase --no-autostash
도 사용할 수 있습니다.git revert <sha-1>
주어진 커밋 또는 커밋 범위를 "실행 취소"합니다.
reset 명령은 주어진 커밋의 모든 변경 사항을 "실행 취소"합니다.
실행 취소 패치가 포함된 새 커밋이 커밋되고 원래 커밋도 히스토리에 남습니다.
# add new commit with the undo of the original one. # the <sha-1> can be any commit(s) or commit range git revert <sha-1>
이 스키마는 어떤 명령이 무엇을 하는지 보여줍니다.
보시다시피 reset && checkout
HEAD
수정합니다.
나는 이것이 오래된 스레드라는 것을 알고 있습니다 ... 그러나 많은 사람들이 Git에서 항목을 실행 취소하는 방법을 찾고 있기 때문에 여기에서 계속 팁을 제공하는 것이 좋습니다.
"git add"를 수행하거나 git gui에서 왼쪽 상단에서 왼쪽 하단으로 무엇이든 이동하면 파일의 내용이 blob에 저장되고 파일 내용은 해당 blob에서 복구할 수 있습니다.
따라서 커밋되지 않았지만 추가되어야 하는 경우에도 파일을 복구할 수 있습니다.
git init echo hello >> test.txt git add test.txt
이제 blob이 생성되지만 인덱스에서 참조하므로 재설정할 때까지 git fsck에 나열되지 않습니다. 그래서 우리는 재설정 ...
git reset --hard git fsck
당신은 매달린 얼룩을 얻을 것입니다 ce013625030ba8dba906f756967f9e9ca394464a
git show ce01362
파일 내용 "hello"를 다시 제공합니다.
참조되지 않은 커밋을 찾기 위해 어딘가에서 이것을 제안하는 팁을 찾았습니다.
gitk --all $(git log -g --pretty=format:%h)
나는 그것을 git gui의 도구로 가지고 있으며 매우 편리합니다.
방금 잘못된 프로젝트에서 하드 리셋을 수행했습니다. 내 생명을 구한 것은 Eclipse의 현지 역사였습니다. IntelliJ Idea에도 하나가 있다고 말하며 편집자도 확인할 가치가 있습니다.
찾고 있는 커밋을 조금 더 쉽게 찾을 수 있도록 작은 스크립트를 만들었습니다.
git fsck --lost-found | grep commit | cut -d ' ' -f 3 | xargs -i git show \{\} | egrep '^commit |Date:'
예, awk 또는 이와 유사한 것으로 상당히 더 예쁘게 만들 수 있지만 간단하고 필요했습니다. 다른 사람을 30초나 절약할 수 있습니다.
git reflog
및 마지막 HEAD 6a56624(HEAD -> 마스터) HEAD@{0}: 재설정: HEAD~3으로 이동 1a9bf73 HEAD@{1}: 커밋: 모델에 변경 사항 추가 바이너리 생성
이것은 내 생명을 구했습니다: https://medium.com/@CarrieGuss/how-to-recover-from-a-git-hard-reset-b830b5e3f60c
기본적으로 다음을 실행해야 합니다.
for blob in $(git fsck --lost-found | awk '$2 == “blob” { print $3 }'); do git cat-file -p $blob > $blob.txt; done
그런 다음 수동으로 파일을 올바른 구조로 재구성해야 합니다.
요점: 작동 방식을 100% 이해하지 못하면 git reset --hard
사용하지 마십시오. 사용하지 않는 것이 가장 좋습니다.
내 문제는 거의 비슷합니다. git reset --hard
입력하기 전에 커밋되지 않은 파일이 있습니다.
고맙게도. 이 모든 리소스를 건너뛸 수 있었습니다. ctrl-z
)할 수 있다는 것을 알게 된 후. 위의 모든 답변에 이것을 추가하고 싶습니다.
메모. 열리지 않은 파일 ctrl-z
것은 불가능합니다.
git reset --hard - 한 페이지를 되돌리는 데 사용할 수 있으며 그 후에는 원본에서 모든 것을 숨기거나 가져올 수 있습니다.
출처 : http:www.stackoverflow.com/questions/5473/how-can-i-undo-git-reset-hard-head1
performSelector는 선택자를 알 수 없기 때문에 누수를 일으킬 수 있습니다. (0) | 2023.04.20 |
---|---|
setup.py는 무엇입니까? (1) | 2023.04.15 |
Access-Control-Allow-Origin 헤더는 어떻게 작동합니까? (2) | 2023.04.15 |
Javascript의 배열에서 빈 요소 제거 (0) | 2023.04.15 |
require, include, require_once 및 include_once의 차이점은 무엇입니까? (0) | 2023.04.15 |