source

Git에서 손실된 저장소를 복구하려면 어떻게 해야 합니까?

bestscript 2023. 5. 20. 22:52

Git에서 손실된 저장소를 복구하려면 어떻게 해야 합니까?

는 자주사다니합용ently를 자주 사용합니다.git stash그리고.git stash pop작업 트리의 변경 내용을 저장하고 복원합니다.어제, 저는 제 작업 트리에 저장하고 터뜨린 몇 가지 변경 사항이 있었고, 그리고 나서 제 작업 트리에 더 많은 변경 사항을 적용했습니다. 돌아가서 어제의 변경 사항을 다시돌아어숨제변겨진사검싶경다고토습니하을항서의가▁i싶다▁but,습.git stash pop연결된 커밋에 대한 모든 참조를 제거하는 것으로 나타납니다.

만약 내가 사용한다면 나는 알고 있습니다.git stash그러면 .git/refs/stash에 stash를 생성하는 데 사용된 커밋의 참조가 포함됩니다..git/logs/refs/stash에는 전체 저장소가 포함됩니다.하지만 그 언급들은 그 후에 사라졌습니다.git stash pop커밋이 아직 내 저장소 어딘가에 있다는 것은 알지만, 그게 무엇이었는지는 모르겠습니다.

어제의 stash commit reference를 복구하는 쉬운 방법이 있습니까?

삭제한 stash commit의 해시를 알고 나면 이를 stash로 적용할 수 있습니다.

git stash apply $stash_hash

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

git branch recovered $stash_hash

그 후에, 여러분은 모든 일반적인 도구로 여러분이 원하는 것을 할 수 있습니다.다 먹고 나면, 그냥 나뭇가지를 날려버리세요.

해시 찾기

만약 당신이 방금 그것을 터뜨렸고 터미널이 여전히 열려 있다면, 당신은 여전히 화면에 에 의해 인쇄된 해시 값을 가지고 있을 입니다(고맙습니다, 돌다).

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

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

...또는 Windows용 PowerShell 사용:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $_.ToString().Split(" ")[2] }

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

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

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

...또는 Windows용 PowerShell을 사용하는 경우 Emragin에서 답변을 확인할 수 있습니다.

연결 가능 여부에 관계없이 리포지토리의 모든 커밋을 보여주는 리포지토리 브라우저가 시작됩니다.

▁you▁can있습수를 대체할 수 있습니다.gitk▁▁something에▁with기▁there고와 같은 것이 있습니다.git log --graph --oneline --decorate별도의 GUI 앱보다 콘솔에 있는 멋진 그래프를 선호하는 경우.

저장 커밋을 찾으려면 다음 형식의 커밋 메시지를 찾습니다.

일부 분기의 WIP: commitash 일부 오래된 커밋 메시지

참고: 커밋 메시지는 메시지를 제공하지 않은 경우에만 이 양식("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

또한 분기로 사용하면 체리 선택 또는 병합과 같이 자유롭게 조작할 수 있습니다.

승인된 솔루션에 이 추가 사항을 언급하고 싶습니다.이 방법을 처음 시도했을 때는 분명하지 않았지만(아마도 그랬어야 했을 것입니다) 해시 값에서 스택을 적용하려면 "gitstash 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"의 "WIP.-grep=WIP메시지의 일부와 함께 명령의 끝에 있습니다.-grep=Tesselation.

가 stash " "WIP" "greping " 이 "WIP입니다.WIP on mybranch: [previous-commit-hash] Message of the previous commit.

커을찾았커적용다니합밋을면으와 함께 합니다.git stash apply <commit_hash>

방금 잃어버린 저장소 커밋을 찾는 데 도움이 되는 명령어를 만들었습니다.

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 트리에 있는 모든 개체를 나열하고 commit 유형의 개체를 찾은 다음 각 개체에 대한 요약을 표시합니다.이 시점부터 적절한 "WIP on work: 6a9bb2"("work"는 나의 분기, 619b2는 최근의 커밋)를 찾기 위해 커밋을 검토하는 것이었습니다.

"gitstash pop" 대신 "gitstash apply"를 사용하면 이 문제가 발생하지 않을 것이고, "gitstash save message"를 사용하면 커밋을 찾기가 더 쉬울 수 있습니다.

업데이트: Nathan의 아이디어로 이 작업은 더 짧아졌습니다.

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

gitk를 사용하는 Windows PowerShell 동등 제품:

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

한 파이프에서 이 작업을 수행하는 데 더 효율적인 방법이 있을 수 있지만, 이 방법이 효과적입니다.

git fsck --unreachable | grep commitsha1이 표시되어야 하지만 반환되는 목록이 상당히 클 수 있습니다. git show <sha1>원하는 커밋인지 여부가 표시됩니다.

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

손실된 저장소를 다시 저장하려면 먼저 손실된 저장소의 해시를 찾아야 합니다.

아리스토텔레스 파갈치스가 제안한 것처럼.git fsck도움이 될 겁니다

으로 저는 제 개적으나나를 합니다.log-all 잘 커밋(커밋)을 별칭: "commit" (사용 가능한 커밋)은 다음과 .

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

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

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

제가 가장 좋아하는 것은 이 한 줄입니다.

git log --oneline  $( git fsck --no-reflogs | awk '/dangling commit/ {print $3}' )

이것은 기본적으로 이 대답과 같은 생각이지만 훨씬 더 짧습니다.물론, 당신은 여전히 추가할 수 있습니다.--graph트리와 같은 디스플레이를 얻을 수 있습니다.

목록에서 커밋을 찾았으면 다음을 사용하여 적용합니다.

git stash apply THE_COMMIT_HASH_FOUND

나는, 사기하를 합니다.--no-reflogs분실된 창고 항목을 드러냈지만,--unreachable(다른 많은 답변에서 발견된 바와 같이) 그렇지 않았습니다.

Windows 아래에 있을 때 gitbash에서 실행합니다.

학점:위의 명령에 대한 자세한 내용은 https://gist.github.com/joseluisq/7f0f1402f05c45bac10814a9e38f81bf 에서 확인할 수 있습니다.

아리스토텔레스의 접근법은 좋았지만 GITK를 사용하는 것은 싫었습니다...명령 줄에서 GIT를 사용하는 데 익숙하기 때문입니다.

대신, 저는 매달리는 커밋을 가져다가 코드 편집기에서 검토하기 위해 코드를 DIF 파일로 출력했습니다.

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

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

그럼 그냥 사용하세요.

git stash apply ad38abbf76e26c803b27a6079348192d32f52219

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

git fsck --unreachable

연결할 수 없는 커밋 해시 확인 -

git show hash

최종적으로 저장된 아이템을 찾으시면 신청하세요.

git stash apply hash

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

그런 다음 commit-id를 찾으면 git stash 적용 {commit-id}

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

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

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

저는 이 질문을 하는 모든 사람들에게 그 이상은 하지 말고 reflog(git reflog)를 확인하라고 조언하고 싶습니다.모든 커밋 목록을 확인하면 원하는 커밋을 확인하고 해당 커밋을 선택하거나 분기를 만들 수 있는 수백 가지 방법이 있습니다.이 과정에서 reflog와 다양한 기본 git 명령에 대한 유용한 옵션에 대해 배우게 됩니다.

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

  • 번째 실행:git fsck --unreachable | findstr "commit"
  • 출력을 메모장에 복사
  • replace 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 파일로 저장하고 실행합니다.
  • 스크립트는 각 커밋을 표시하는 명령 창을 엽니다.
  • 다음을 하세요: 찾고있파찾경실다우행다니합음을은일는을:▁if다▁run.git stash apply (your 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'를 누릅니다.

아리스토텔레스가 수락한 답변은 비재고형 커밋을 포함하여 도달할 수 있는 모든 커밋을 보여줍니다.노이즈를 필터링하려면:

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개의 상위 커밋(스택에 포함됨)이 있고 메시지에 "WIPON"이 포함된 커밋만 포함됩니다.

메와함저예장경한우께지시예경(우:▁(▁message▁keep▁you▁your한장ash▁)와 저장한 경우하십시오.git stash save "My newly created stash" 이렇게 "WIPON...", "WIPON..."(으)로 재정의됩니다.메시지를 보냅니다.

메시지를 커밋하는 등 각 정보를 할 수 .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 환경에서 복구하는 데 도움이 되었습니다(2022년).

이 단계에서는 삭제된 Git Stash 또는 분기를 복구하는 방법에 대해 개략적으로 설명합니다(가비지 수집에 의해 영구적으로 삭제되지 않은 경우).

  1. 프로젝트가 있는 디렉터리로 이동합니다.

  2. 명령을 합니다.git fsck --no-reflogs | find "dangling commit" 여기에 이미지 설명 입력

  3. 커밋을 매달기 위한 해시 목록이 나타납니다.삭제된 분기 및 스택으로 구성됩니다.목록 끝 근처에 해시를 복사하여 붙여넣는 것으로 시작하여 저장소 또는 분기를 찾습니다.를 들어, 다음 합니다.git log -1 [hash]

  4. 을 사용하여하십시오." " 해해시당복경일다명다사복해니원"git stash apply [hash]

터미널에서 커밋을 보려면 관심 있는 커밋만 필터링하면 됩니다.

git log --oneline --all --grep="^WIP on .*: [a-f0-9]\+" --grep="^On [^ ]*:" --grep="^index on [^ ]*:" $( env LANG=C git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

이것은 아리스토텔레스 파갈치스의 대답에 근거한 것입니다.

제가 여기에 온 것은 제가 대출한 것과 상관없이 어떻게 실제로 재고를 되찾을 수 있는가 하는 것입니다.특히, 저는 무언가를 저장하고, 이전 버전을 확인한 다음, 팝업을 표시했습니다. 하지만 그 저장은 그 이전 시점에서는 사용할 수 없었습니다. 그래서 저장은 사라졌습니다. 저는 그냥 할 수 없었습니다.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그리고 매번 적용하고 싶은 작은 패치가 있었습니다.bisectstep.요: 텝이내, 제할가일은.

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

다음 단계를 사용하여 복구:

  1. 삭제된 해시 코드 식별:

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

  2. 체리 픽 더 스테이시:

    git cherry-pick -m 1 $stash_message_code

  3. 다음을 사용하는 경우 충돌 해결:

    깃머제 도구

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

  1. 이전 커밋으로 하드 재설정을 사용한 다음 이 변경 사항을 다시 적용합니다.
  2. 또한 변경사항을 저장하고, 기본값을 다시 지정한 후 다시 지정할 수 있습니다.

저장된 커밋만 보고, 커밋이 첨부된 위치 및 내용을 클릭

결과 샘플

Checking object directories: 100% (256/256), done.
2022-08-31 10:20:46 +0900 8d02f61 WIP on master: 243b594 add css
A       favicon.ico

지휘권

git fsck --dangling | awk '/dangling commit/ {print $3}' | xargs -L 1 git --no-pager show -s --format="%ct %h" | sort | awk '{print $2}' | { while read hash; do status=$(git stash show $hash --name-status 2>/dev/null); if (( $? == 0 )); then git show $hash -s --format="%C(green)%ci %C(yellow)%h %C(blue)%B"; echo "$status"; fi; done; }
  • 해시를 를 합니다.%h%H
  • 시간을 위해 를 fsck, fsck, fsck처럼 .git fsck --dangling | tail -100 | awk ...

샘플을 회수합니다.

대략적인 파일 이름과 해당 위치를 알고 삭제된 저장 파일을 찾을 수 있었으며 경로에 대한 매달린 커밋을 그랩핑할 수 있었습니다.

for i in $(git fsck --no-reflogs | awk '/dangling commit/ {print $3}'); do
  if git log -5 --name-only -u $i | grep -q "<path-to-files>/.*<partial-file-name>.*"; then
    echo "found something in commit $i";
  fi;
done

다음 프로세스를 단계별로 수행할 수 있습니다.

1- 아래를 사용하여 연결할 수 없는 모든 커밋 gitfsck --unconnectable을 나열합니다.

2 - git show hash를 사용하여 도달할 수 없는 커밋 해시를 표시합니다.

3 - 모든 로그를 복사합니다. log like, 도달 불가능한 blob, commit, tree를 볼 수 있습니다.

4 - 커밋 해시 git stash를 적용하도록 로그와 함께 git stash 적용 [해시 바꾸기]

재고를 확보하기 위한 정확한 답변은 아니지만, 처음에는 저장했다가 다른 지점에 표시된 커밋되지 않은 변경 사항을 얻는 것이 목표인 경우 두 가지 모두에 대해 의미가 있으며 다음과 같은 방법으로 수행됩니다.

  1. 에서 합니다.branch_a
  2. git stash
  3. 에서 branch_b branch_a
  4. git stash apply

않은 사항을 그런다커않변내복원으로 합니다.branch_a:

  1. git checkout branch_a
  2. git merge branch_b
  3. git reset HEAD~1

언급URL : https://stackoverflow.com/questions/89332/how-do-i-recover-a-dropped-stash-in-git