문제

나는 자주 사용한다 git stash 그리고 git stash pop 작업 트리의 변경 사항을 저장하고 복원합니다.어제 작업 트리에 숨겨져 있던 몇 가지 변경 사항을 적용한 다음 작업 트리에 더 많은 변경 사항을 적용했습니다.다시 돌아가서 어제 숨겨둔 변경사항을 검토하고 싶지만 git stash pop 관련 커밋에 대한 모든 참조를 제거하는 것으로 보입니다.

내가 사용하면 알아요 git stash 그 다음에 .git/refs/stash에는 다음이 포함됩니다. 숨김을 생성하는 데 사용된 커밋의 참조입니다.그리고 .git/logs/refs/stash에는 다음이 포함됩니다. 전체 은닉물.하지만 그 언급은 이후 사라졌습니다 git stash pop.커밋이 여전히 내 저장소 어딘가에 있다는 것을 알고 있지만 그것이 무엇인지는 모릅니다.

어제의 숨김 커밋 참조를 복구하는 쉬운 방법이 있나요?

매일 백업이 있고 어제의 작업 트리로 돌아가 변경 사항을 가져올 수 있기 때문에 오늘은 이것이 중요하지 않습니다.더 쉬운 방법이 있을 것 같아서 여쭤봅니다!

도움이 되었습니까?

해결책

삭제한 스태시 커밋의 해시를 알고 나면 이를 스태시로 적용할 수 있습니다.

git stash apply $stash_hash

또는 다음을 사용하여 별도의 분기를 만들 수 있습니다.

git branch recovered $stash_hash

그 후에는 모든 일반 도구를 사용하여 원하는 모든 작업을 수행할 수 있습니다.작업이 끝나면 가지를 날려버리세요.

해시 찾기

방금 팝업을 떴고 터미널이 아직 열려 있다면, 여전히 해시 값이 인쇄되어 있습니다. git stash pop 화면에 (고마워요, 돌다).

그렇지 않으면 Linux, Unix 또는 Windows용 Git Bash를 사용하여 찾을 수 있습니다.

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

...또는 Windows용 Powershell을 사용하여:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

이렇게 하면 더 이상 어떤 브랜치나 태그에서도 참조되지 않는 커밋 그래프 끝 부분에 모든 커밋이 표시됩니다. 지금까지 생성한 모든 스태시 커밋을 포함하여 손실된 모든 커밋은 해당 그래프의 어딘가에 있을 것입니다.

원하는 스태시 커밋을 찾는 가장 쉬운 방법은 해당 목록을 다음으로 전달하는 것입니다. gitk:

gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

...또는 참조하세요 emragins의 답변 Windows용 Powershell을 사용하는 경우.

그러면 저장소 브라우저가 시작되어 다음을 보여줍니다. 저장소의 모든 커밋, 도달 가능 여부에 관계없이.

교체할 수 있습니다 gitk 거기에 같은 것이 있어요 git log --graph --oneline --decorate 별도의 GUI 앱보다 콘솔에서 멋진 그래프를 선호하는 경우.

숨김 커밋을 찾으려면 다음 형식의 커밋 메시지를 찾으세요.

WIP 켜짐 어떤 지점: commithash 오래된 커밋 메시지

메모:커밋 메시지는 메시지를 제공할 때 제공하지 않은 경우에만 이 형식("WIP on"으로 시작)으로 표시됩니다. git stash.

다른 팁

터미널을 닫지 않았다면 터미널의 출력을 살펴보세요. git stash pop 삭제된 숨김의 개체 ID를 갖게 됩니다.일반적으로 다음과 같습니다.

$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

(참고하세요 git stash drop 같은 라인을 생산합니다.)

그 은닉물을 되찾으려면 그냥 실행하세요. git branch tmp 2cae03e, 그리고 당신은 그것을 지점으로 얻게 될 것입니다.이것을 숨김으로 변환하려면 다음을 실행하십시오.

git stash apply tmp
git stash

이를 분기로 사용하면 자유롭게 조작할 수도 있습니다.예를 들어 체리픽(cherry-pick) 또는 병합이 가능합니다.

허용되는 솔루션에 이 추가 사항을 언급하고 싶었습니다.이 방법을 처음 시도했을 때는 명확하지 않았지만(아마도 그랬어야 했을 것입니다), 해시 값에서 숨김을 적용하려면 "git stash apply"를 사용하세요.

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

제가 git을 처음 접했을 때는 이것이 명확하지 않았고 "git show", "git apply", "patch" 등의 다양한 조합을 시도하고 있었습니다.

아직 저장소에 있지만 더 이상 접근할 수 없는 숨김 목록을 얻으려면 다음을 수행하세요.

git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk --grep=WIP

스태쉬에 제목을 지정한 경우 "WIP"를 교체하세요. -grep=WIP 명령 끝에 메시지의 일부를 추가하세요. -grep=Tesselation.

숨김에 대한 기본 커밋 메시지의 형식이 다음과 같기 때문에 이 명령은 "WIP"를 검색합니다. WIP on mybranch: [previous-commit-hash] Message of the previous commit.

방금 잃어버린 숨김 커밋을 찾는 데 도움이 되는 명령을 구성했습니다.

for ref in `find .git/objects | sed -e 's#.git/objects/##' | grep / | tr -d /`; do if [ `git cat-file -t $ref` = "commit" ]; then git show --summary $ref; fi; done | less

이는 .git/objects 트리의 모든 객체를 나열하고 커밋 유형의 객체를 찾은 다음 각 객체에 대한 요약을 표시합니다.이 시점부터는 적절한 "WIP on work:"를 찾기 위해 커밋을 살펴보는 것뿐이었습니다.6a9bb2"("work"는 내 브랜치이고 619bb2는 최근 커밋입니다).

"git stash pop" 대신 "git stash apply"를 사용하면 이 문제가 발생하지 않으며 "git stash save"를 사용하면 메시지" 그러면 커밋을 찾기가 더 쉬웠을 것입니다.

업데이트:Nathan의 아이디어를 사용하면 이 내용이 더 짧아집니다.

for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less

git fsck --unreachable | grep commit 반환되는 목록이 상당히 클 수 있지만 sha1을 표시해야 합니다. git show <sha1> 원하는 커밋인지 표시됩니다.

git cherry-pick -m 1 <sha1> 커밋을 현재 분기에 병합합니다.

잃어버린 보관함을 다시 복원하려면 먼저 잃어버린 보관함의 해시를 찾아야 합니다.

Aristotle Pagaltzis가 제안했듯이 git fsck 당신을 도와야합니다.

개인적으로 나는 내 log-all 상황을 더 잘 볼 수 있도록 모든 커밋(복구 가능한 커밋)을 표시하는 별칭:

git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d' ' -f3)

"WIP on" 메시지만 찾는 경우 훨씬 더 빠른 검색을 수행할 수 있습니다.

sha1을 알고 나면 stash reflog를 변경하여 이전 stash를 추가하면 됩니다.

git update-ref refs/stash ed6721d

아마도 관련 메시지가 있는 것을 선호할 것입니다. -m

git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d

그리고 이것을 별칭으로 사용하고 싶을 수도 있습니다.

restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1

gitk를 사용하는 Windows PowerShell과 동일:

gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })

하나의 파이프에서 이 작업을 수행하는 더 효율적인 방법이 있을 수 있지만 이것이 작업을 수행합니다.

나는 Aristotle의 접근 방식을 좋아했지만 GITK를 사용하는 것을 좋아하지 않았습니다...나는 명령줄에서 GIT를 사용하는 데 익숙하기 때문입니다.

대신, 나는 매달린 커밋을 가져와 코드 편집기에서 검토할 수 있도록 코드를 DIFF 파일로 출력했습니다.

git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) > ~/stash_recovery.diff

이제 결과 diff/txt 파일(홈 폴더에 있음)을 txt 편집기에 로드하고 실제 코드와 결과 SHA를 볼 수 있습니다.

그럼 그냥 사용

git stash apply ad38abbf76e26c803b27a6079348192d32f52219

git v2.6.4가 설치된 OSX에서는 실수로 git stash drop을 실행한 다음 아래 단계를 통해 발견했습니다.

숨김 이름을 알고 있으면 다음을 사용하십시오.

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>

그렇지 않으면 다음을 사용하여 수동으로 결과에서 ID를 찾을 수 있습니다.

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show

그런 다음 커밋 ID를 찾으면 git stash apply {commit-id}를 누르십시오.

이것이 누군가에게 빨리 도움이 되기를 바랍니다.

사람들은 왜 이런 질문을 할까요?그들은 아직 리플로그에 대해 모르거나 이해하지 못하기 때문입니다.

이 질문에 대한 대부분의 답변은 거의 누구도 기억하지 못할 옵션이 포함된 긴 명령을 제공합니다.그래서 사람들은 이 질문에 답하고 필요하다고 생각하는 것은 무엇이든 복사하여 붙여넣고 거의 즉시 잊어버립니다.

나는 이 질문이 있는 모든 사람에게 reflog(git reflog)를 확인하라고 조언하고 싶습니다. 그 이상은 아닙니다.모든 커밋 목록을 보면 찾고 있는 커밋이 무엇인지 확인하고 해당 커밋을 선별하거나 여기에서 브랜치를 생성할 수 있는 수백 가지 방법이 있습니다.이 과정에서 reflog와 다양한 기본 git 명령에 대한 유용한 옵션에 대해 배우게 됩니다.

터미널에 다음 명령을 작성하여 연결할 수 없는 모든 커밋을 나열할 수 있습니다.

git fsck --unreachable

도달할 수 없는 커밋 해시를 확인하세요 -

git show hash

마지막으로 숨겨둔 아이템을 찾으면 신청해주세요~

git stash apply hash

gitk를 사용할 수 없거나 출력용 X가 없는 경우 모든 변경 사항을 처리할 수 있는 또 다른 좋은 방법을 허용된 솔루션에 추가하고 싶습니다.

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

그런 다음 해당 해시에 대한 모든 차이점이 차례로 표시됩니다.다음 차이점으로 이동하려면 'q'를 누르세요.

Aristotle의 승인된 답변에는 숨김이 아닌 커밋을 포함하여 도달 가능한 모든 커밋이 표시됩니다.소음을 필터링하려면:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3

여기에는 정확히 3개의 상위 커밋(스태쉬에 포함됨)이 있고 메시지에 "WIP on"이 포함된 커밋만 포함됩니다.

메시지와 함께 보관함을 저장한 경우(예: git stash save "My newly created stash"), 이는 기본 "WIP on..." 메시지를 무시합니다.

각 커밋에 대한 추가 정보를 표시할 수 있습니다.커밋 메시지를 표시하거나 다음으로 전달합니다. git stash show:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3 | \
xargs -n1 -I '{}' bash -c "\
  git log -1 --format=medium --color=always '{}'; echo; \
  git stash show --color=always '{}'; echo; echo" | \
less -R

간단한 명령 창(내 경우에는 Windows 7)에서 Windows에서 작업하기 위한 답변을 얻을 수 없었습니다. awk, grep 그리고 Select-string 명령으로 인식되지 않았습니다.그래서 저는 다른 접근 방식을 시도했습니다.

  • 첫 번째 실행: git fsck --unreachable | findstr "commit"
  • 출력을 메모장에 복사
  • "도달할 수 없는 커밋"을 다음으로 대체하세요. start cmd /k git show

다음과 같이 보일 것입니다 :

start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e

  • .bat 파일로 저장하고 실행하세요.
  • 스크립트는 여러 명령 창을 열어 각 커밋을 보여줍니다.
  • 원하는 것을 찾았다면 다음을 실행하세요. git stash apply (your hash)

최선의 해결책은 아닐 수도 있지만 나에게는 도움이 되었습니다.

내가 여기에서 찾고 있는 것은 내가 무엇을 확인했는지에 관계없이 실제로 숨겨둔 것을 다시 가져오는 방법입니다.특히, 나는 무언가를 숨긴 다음 이전 버전을 확인한 다음 그것을 터뜨렸지만 그 이전 시점에는 숨김이 아무 작동도 하지 않았기 때문에 숨김이 사라졌습니다.난 그냥 할 수 없었어요 git stash 스택에 다시 밀어 넣습니다.이것은 나에게 효과적이었습니다.

$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use "git add" to track)
Dropped refs/stash@{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^    # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.

돌이켜보면, 나는 사용했어야 했어 git stash apply ~ 아니다 git stash pop.나는하고 있었다 bisect 매번 적용하고 싶은 작은 패치가 있었습니다. bisect 단계.이제 나는 이것을 하고 있다:

$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.

다음 단계를 사용하여 복구했습니다.

  1. 삭제된 숨김 해시 코드를 식별합니다.

    gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

  2. 체리 픽 더 은닉물:

    git 체리-픽 -m 1 $stash_hash_code

  3. 다음을 사용하여 충돌을 해결합니다.

    자식 병합 도구

또한 gerrit를 사용하는 경우 커밋 메시지에 문제가 있을 수 있습니다.다음 대안을 따르기 전에 변경 사항을 보관하십시오.

  1. 이전 커밋으로 하드 리셋을 사용한 다음 이 변경 사항을 다시 커밋합니다.
  2. 변경 사항을 숨기고, 리베이스하고, 다시 커밋할 수도 있습니다.

실수로 GitUP 앱에서 숨김 파일을 제거했습니다.Ctrl+Z를 눌러 취소하면 됩니다.

어쩌면 누군가에게 도움이 될 수도 있습니다;)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top