programing

gitstash pop이 stash 항목에서 추적되지 않은 파일을 복원할 수 없다고 하는 이유는 무엇입니까?

mailnote 2023. 6. 25. 20:24
반응형

gitstash pop이 stash 항목에서 추적되지 않은 파일을 복원할 수 없다고 하는 이유는 무엇입니까?

여러 가지 단계별 및 단계별 변경 사항이 있었는데, 다른 지점으로 빠르게 전환했다가 다시 전환하고 싶었습니다.

그래서 다음을 사용하여 변경 사항을 스테이징했습니다.

$ git stash push -a

(나중에 생각해보면, 아마도 나는 사용할 수 있었을 것입니다.--include-untracked--all)

그리고 나서 제가 창고를 터뜨리러 갔을 때 다음과 같은 방식으로 많은 오류가 발생했습니다.

$ git stash pop
foo.txt already exists, no checkout
bar.txt already exists, no checkout
...
Could not restore untracked files from stash entry

저장소에서 복원된 변경 사항이 없는 것 같습니다.

저도 노력했습니다.$ git stash branch temp하지만 그것은 같은 오류를 보여줍니다.

저는 이 문제를 해결할 방법을 찾았습니다.

$ git stash show -p | git apply

재난은 일단 피했지만 이것은 몇 가지 의문을 제기합니다.

애초에 이 오류가 발생한 이유와 다음 번에는 어떻게 방지해야 합니까?

문제를 다시 만들 수 있었습니다.되지 않은 파일을 ( 되지않파은예저다생해것파같성는다습니하일을당추음적한장일을예▁it(:같것습다니).foo.txt그리고.bar.txt), 그러면 추적되지 않은 파일에 대한 로컬 변경 사항이 적용될 때 덮어쓰게 됩니다.git stash pop.

이 문제를 해결하려면 다음 명령을 사용할 수 있습니다.저장되지 않은 로컬 변경사항은 무시되므로 주의하십시오.

git checkout stash -- .

다음은 이전 명령에서 찾은 추가 정보입니다.

약간의 추가적인 설명으로서, 주의할 점은git stash두 번 커밋하거나 세 번 커밋합니다.입니다. " 값은입 2니다"의 . 다음의 철자를 사용하면 3이 됩니다.--all또는--include-untracked옵션들.

이 두 가지 또는 세 가지 커밋은 한 가지 중요한 점에서 특별합니다. 분기가 없는 커밋입니다.Git는 특별한 이름을 통해 그들을 찾습니다.stash하지만1 가장 중요한 것은 Git가 이 두 세 가지 커밋으로 무엇을 할 수 있는지입니다.이를 이해하기 위해서는 이러한 커밋에 무엇이 있는지 살펴봐야 합니다.

저장고 안에 무엇이 있습니까?

모든 커밋은 하나 이상의 상위 커밋을 나열할 수 있습니다.이것들은 그래프를 형성하며, 나중에 커밋은 이전 커밋을 가리킵니다.일반적으로 저장소에는 두 개의 커밋이 있습니다. 이 커밋은 제가 부르고 싶습니다.i인덱스/스테이지 영역 콘텐츠의 경우w작업 트리 내용에 사용할 수 있습니다.또한 각 커밋에는 스냅샷이 저장됩니다.일반적인 커밋에서 이 스냅샷은 인덱스/스테이징 영역 내용으로 만들어집니다.그래서 그i커밋은 사실 완전히 정상적인 커밋입니다!어떤 지점에도 없습니다.

...--o--o--o   <-- branch (HEAD)
           |
           i

재고를 만약당정재만있다들면고고를인상적이신,▁the▁if있면다▁you▁a,ash만.git stash는 코드메이를 만듭니다.w이제 추적된 모든 작업 트리 파일을 임시 보조 인덱스로 복사합니다.는 이 Git는 이의첫번설부정다니합모의 첫 번째 합니다.w을 가리키도록 약속합니다.HEAD 두 이 commit, 고커가두는부번모째리키커밋을 가리킵니다.i마지막으로, 그것은.stash 이점지자면하적을▁to를 가리키다w커밋:

...--o--o--o   <-- branch (HEAD)
           |\
           i-w   <-- stash

추가하는 경우--include-untracked또는--all약속을 , Git는추가약합니다속을인적▁g▁g.u만드는 사이에i그리고.w다에대스내의 내용은 .u되지 않는 입니다.--include-untracked되지 않는 ()입니다.--all. . 이의 . 이엑라트스.u커밋에 상위 항목이 없는 경우git stashw가 지다w셋째 부모u커밋하면 다음을 얻을 수 있습니다.

...--o--o--o   <-- branch (HEAD)
           |\
           i-w   <-- stash
            /
           u

Git는 또한 이 시점에서 작업 트리 파일을 제거합니다.u)git clean그렇게 하기 위해).

저장소 복원

저장소를 복원할 때 사용할 수 있는 옵션이 있습니다.--index사용하지 않을 수도 있습니다.은 이말은을 말해줍니다.git stash apply(으로 사용하는 중 apply를 들어, 를들어예와 같은pop)를 사용해야 합니다.i현재 인덱스 수정을 시도하도록 커밋합니다.은 다음과같이 됩니다.

git diff <hash-of-i> <hash-of-i's-parent> | git apply --index

(대략적으로; 여기에는 기본적인 아이디어를 방해하는 많은 사소한 세부 사항들이 있습니다.

를 하면,--index,git stash apply는 완히무니다합시전▁thely▁complete▁ignores완 무시합니다.i저지르다.

커밋이 ,git stash apply이제 적용할 수 있습니다.w저지르다.이것은 전화를 통해 이루어집니다.git merge2 (결과를 일반적인 병합으로 커밋하거나 처리하도록 허용하지 않음), 스택이 만들어진 원래 커밋을 사용합니다.i의 부모님, 그리고w의 첫 번째 를 병합 기준으로 사용합니다.w▁the로서--theirs커밋 및 현재(HEAD) 커밋을 병합 대상으로 지정합니다.병합이 성공하면 모든 것이 좋습니다. 적어도 Git는 그렇게 생각합니다. 그리고.git stash apply그 자체가 성공합니다.를 했다면,git stash pop스택을 적용하기 위해 코드는 이제 3스택을 삭제합니다.병합이 실패하면 Git는 적용이 실패했음을 선언합니다.사용한 경우git stash pop코드는 스택을 유지하고 다음과 같은 실패 상태를 제공합니다.git stash apply.

하지만 그 세 번째 약속이 있다면—만약 있다면.u적용 중인 재고에서 커밋합니다. 그러면 상황이 바뀝니다!커밋이 4존재하지 않는 것처럼 가장하는 옵션은 없습니다.Git는 그것에서 모든 파일을 추출해야 한다고 주장합니다.u현재 작업 트리에 커밋합니다., 해야 합니다.u저지르다.

는 이를위해다사수있다니습용할음을다있니습▁to수▁use▁you,를 사용하면 됩니다.git clean자신은 물론이고 추적되지 않은 파일(무시하든 아니든)은 Git 저장소 내에 존재하지 않으므로 이러한 파일이 모두 파괴될 수 있는지 확인하십시오!디렉터리를 하기 위해 파일을 "" 임시디리를만파안보게전일하기관하위다해있이"를 수행할 수도 .git stash save -u또는git stash save -a그것들은 계속될 것이기 때문에git clean널 위해서.하지만 그것은 당신에게 다른 것을 남깁니다.u에 처리해야 합니다 - 나에처스타재의고일할리중재.


1이것은 사실입니다.refs/stash이것은 당신이 다음과 같은 이름의 지점을 만드는 경우에 중요합니다.stash지점의 전체 이름은 입니다.refs/heads/stash그래서 이것들은 충돌하지 않습니다.하지만 그러지 마세요: Git은 신경쓰지 않겠지만, 당신은 자신을 혼란스럽게 할 것입니다. :-)

2git stash 실로사는코드하를 합니다.git merge-recursive하며, 커밋할 때.이는 여러 가지 이유로 필요하며 충돌을 해결하고 커밋할 때 Git가 병합으로 처리하지 않도록 하는 부작용도 있습니다.

3이것이 제가 피하는 것을 추천하는 이유입니다.git stash pop에찬여하에 git stash apply적용된 내용을 검토하고 실제로 올바르게 적용되었는지 여부를 결정할 수 있는 기회가 제공됩니다.만약 그렇지 않다면, 당신은 여전히 당신의 재고를 가지고 있습니다, 그것은 당신이 사용할 수 있다는 것을 의미합니다.git stash branch모든 것을 완벽하게 회복하기 위해.음, 그 성가신 일이 없다면,u저지르다.

4다음과 같은 것들이 있어야 합니다.git stash apply --skip-untracked뭐 그런 거.또한 모든 커밋 파일을 새 디렉터리에 놓는 것을 의미하는 변형이 있어야 합니다. 예를 들어,git stash apply --untracked-into <dir>아마

Daniel Smith의 대답으로 확장하기: 그 코드는 당신이 사용했더라도 추적된 파일만 복원합니다.--include-untracked(또는)-u를) 할 수 있습니다.을 클릭합니다.필요한 전체 코드는 다음과 같습니다.

git checkout stash -- .
git checkout stash^3 -- .
git stash drop

# Optional to unstage the changes (auto-staged by default).
git reset

내용이 됩니다.stash및되지 않은 내용( )에stash^3 저장소를 를 선택한 다음, 스택을 삭제합니다.몇 가지 참고 사항:

  • 모든 내용을 저장 내용으로 덮어쓰게 되므로 주의하십시오.
  • 을다사여로 git checkout모든 것이 자동으로 준비되도록 하기 때문에, 나는 추가했습니다.git reset모든 것을 해체하기 위해.
  • 는 일부리사를 사용합니다.stash@{0}그리고.stash@{0}^3내 테스트에서는 사용 여부와 상관없이 동일하게 작동합니다.@{0}

출처:

다른 대답들 외에도, 저는 약간의 속임수를 썼습니다.

  • 모든 새 파일(이미 존재하는 파일, 예: foo.txt 및 bar)을 삭제했습니다.질문의 txt)
  • git stash apply할 수 .)

이 문제를 해결하는 쉬운 방법은 충돌하는 기존 파일의 이름을 충돌하지 않는 파일로 변경하는 것입니다.

를 들어, 예들어경을 하면 실할행우가 .git stash apply/pop다음 항목을 가져옵니다.

foo.md already exists, no checkout
error: could not restore untracked files from stash

이름변시도경도의 이름을 변경해 .foo.mdfoo.new.md 방송재를 다시 실행합니다.git stash apply/pop하지 않고 두 오류가 합니다.foo.md그리고.foo.new.md자유로이

저는 방금 이 문제가 있었습니다.위의 답변은 파일이 저장된 파일에서 손실되지 않고 작동하지 않았기 때문에, 저는 즉흥적으로 작업했습니다.

다음을 사용하여 만든 내 재고git stash -u새로 추가된 파일을 추적하지 않았습니다.이러한 파일 중 일부는 코드 생성에서 가져온 것으로, 제가 스택을 팝업하기 전에 마스터 분기에 개별적으로 커밋되었습니다.제가 창고를 터뜨렸을 때, 저는 다음과 같은 것을 얻었습니다.

> git stash pop
web-app/src/app/rest-services/api/models/model1.ts already exists, no checkout
web-app/src/app/rest-services/api/models/model2.ts already exists, no checkout
web-app/src/app/rest-services/api/models/model3.ts already exists, no checkout
web-app/src/app/rest-services/api/models/model4.ts already exists, no checkout
error: could not restore untracked files from stash

Git가 두 개의 다른 새 파일을 병합할 수 없다는 이론에 따라, 저는 제 작업 디렉토리에서 각각의 이름이 붙은 파일을 삭제했습니다.그러면 누락된 파일이나 오류 없이 전체 스택을 적용할 수 있었습니다.

작동하기 위해 수행한 단계는 다음과 같습니다.

  1. 저는 제 작업 디렉토리의 메시지에 언급된 각 파일을 삭제했습니다.
  2. 스테이징되지 않은 상태로 재고를 다시 적용했습니다.

스택의 모든 파일은 오류 없이 적용되어야 합니다.

(로컬 분기)로 명명된 분기를 로컬 변경 사항과 함께 저장하면 됩니다.파일 A, 파일 B 및 새로 추가된 파일 C를 가정해 보겠습니다.파일 C는 분기에 코드를 저장하는 동안 추적 해제 단계에 있습니다.

나중에 한 도그 풀로 최신 코드 양식 마스터를 가져오면 A 파일이 업데이트됩니다.이후 분기에 저장된 파일을 적용하려고 하지만 추적되지 않은 파일은 제공되지 않습니다.꺼내기 요청을 수행하는 동안 업데이트된 A 파일의 충돌로 인해 C 파일.이는 GIT의 새 버전에 대한 제한 사항입니다.

해결 방법 또는 해결 방법: 파일 A가 업데이트되지 않은 로컬 지점장을 가리키고 스택 코드를 적용하면 이제 세 개의 파일을 트랙 해제 파일로 변환하거나 원하는 대로 복사할 수 있습니다.git pull 명령을 사용하여 분기 헤드를 업데이트하고 자체 코드도 가지고 있습니다(스택에서 가져오거나 복사한 경우 수동으로 붙여넣을 수 있음).

언급URL : https://stackoverflow.com/questions/51275777/why-does-git-stash-pop-say-that-it-could-not-restore-untracked-files-from-stash

반응형