나는 많은 단계적 및 비 단계적 변경 사항이 있었고 다른 분기로 빠르게 전환 한 다음 다시 전환하고 싶었습니다.
그래서 다음을 사용하여 변경 사항을 준비했습니다.
$ 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
지금은 재난을 피했지만 이로 인해 몇 가지 의문이 제기됩니다.
이 오류가 처음에 발생한 이유는 무엇이며 다음에 어떻게 방지합니까?
답변
약간의 추가 설명 git stash
으로 두 번의 커밋 또는 세 번의 커밋을 수행합니다. 기본값은 2입니다. --all
또는 --include-untracked
옵션의 철자를 사용하면 3 개를받습니다 .
이 두 가지 또는 세, 커밋은 하나의 중요한 방법으로 특별하다 : 그들은에있는 어떤 지점입니다. 힘내는 특별한 이름을 통해 그들을 찾습니다 stash
. (1 개) 가장 중요한 것은, 그래도 힘내 당신을-하고 있습니다 무엇을 만들어 이 두 개 또는 세 개의 커밋으로 당신이 할 일. 이를 이해하려면 해당 커밋에 무엇이 있는지 살펴 봐야합니다.
은신처 안에있는 것
모든 커밋은 하나 이상의 상위 커밋을 나열 할 수 있습니다 . 이들은 나중에 커밋이 이전 커밋을 가리키는 그래프를 형성합니다. 숨김은 일반적으로 두 개의 커밋을 보유하고 있는데 i
, 색인 / 스테이징 영역 콘텐츠와 w
작업 트리 콘텐츠에 대해 호출 하고 싶습니다 . 또한 각 커밋에는 스냅 샷이 포함되어 있습니다. 일반 커밋에서이 스냅 샷은 인덱스 / 스테이징 영역 콘텐츠 에서 만들어집니다 . 따라서 i
커밋은 사실 완벽하게 정상적인 커밋입니다! 어떤 지점에도 없습니다.
...--o--o--o <-- branch (HEAD)
|
i
일반 숨김을 만드는 경우 git stash
코드는 w
추적 된 모든 작업 트리 파일을 임시 보조 인덱스로 복사하여 만듭니다 . Git은이 w
커밋 의 첫 번째 부모가 커밋을 가리키고 HEAD
두 번째 부모가 commit을 가리 키도록 설정 i
합니다. 마지막 stash
으로이 w
커밋 을 가리 키도록 설정 합니다 .
...--o--o--o <-- branch (HEAD)
|\
i-w <-- stash
--include-untracked
또는 을 추가 --all
하면 Git은 u
만들기 i
와 w
. 의 스냅 샷 내용 u
은 추적되지 않지만 무시되지 않은 --include-untracked
파일 ( ) 또는 무시 되더라도 추적되지 않는 파일 ( --all
)입니다. 이 추가 u
투입은 없습니다 에는 부모, 다음 경우 git stash
차종은 w
, 그것은 설정 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
완전히는 무시 i
커밋합니다.
숨김에 두 개의 커밋 만있는 경우 git stash apply
이제 w
커밋을 적용 할 수 있습니다 . git merge
2 를 호출 하여 (결과를 일반 병합으로 커밋하거나 처리하도록 허용하지 않고) 숨김이 생성 된 원래 커밋 ( i
‘s parent 및 w
‘s first parent)을 병합 기반 w
으로 사용합니다. --theirs
커밋하고 현재 (HEAD) 커밋을 병합 대상으로 지정합니다. 병합이 성공하면 모든 것이 좋습니다. 적어도 Git 은 그렇게 생각하고 git stash apply
있습니다. git stash pop
숨김을 적용한 경우 코드는 이제 숨김을 삭제 합니다. 3 병합이 실패하면 Git은 적용이 실패했다고 선언합니다. 사용한 경우git stash pop
, 코드는 숨김을 유지하고와 동일한 오류 상태를 제공합니다 git stash apply
.
그러나 세 번째 커밋이있는 경우 u
-적용중인 숨김에 커밋 이 있으면 모든 것이 변경됩니다! 커밋이없는 척할 수있는 옵션 u
이 없습니다. 4 Git은 해당 커밋의 모든 파일 을u
현재 작업 트리로 추출하도록 고집합니다 . 이것은 파일이 전혀 존재하지 않거나 u
커밋 에서와 동일한 내용을 가져야 함을 의미합니다 .
그렇게하려면 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
또는 무언가. 또한 수단이있는 변형이 있어야 모든 드롭 u
새로운 디렉토리에 파일을 커밋 , 예를 들면 git stash apply --untracked-into <dir>
, 아마.
답변
나는 당신의 문제를 재현했습니다. 추적되지 않은 파일을 숨긴 다음 해당 파일 (예 : foo.txt
및 bar.txt
)을 생성하면 git stash pop
.
이 문제를 해결하려면 다음 명령을 사용할 수 있습니다. 이렇게하면 저장되지 않은 로컬 변경 사항 이 무시 되므로주의하십시오.
git checkout stash -- .
다음은 이전 명령에서 찾은 추가 정보 입니다.
답변
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}
출처 :
- git stash가 추가 된 파일을 덮어 쓰도록 강제합니다 (Daniel Smith의 답변에 링크 됨)
- git stash에서 추적되지 않은 파일을 어떻게 체크 아웃 할 수 있습니까? (매직
stash^3
커밋 에 대한 정보 ) - git stash에 대한 Atlassian 가이드 (내부 커밋에 대한 자세한 내용은 “git stash 작동 방식”확인)
답변
다른 답변 외에도 약간의 트릭을
- 모든 새 파일 삭제 (이미 기존 파일, 예 : 질문의 foo.txt 및 bar.txt)
git stash apply
(적용, 팝 등 모든 명령을 사용할 수 있습니다.)