git stash blunder : git stash pop은 병합 충돌로 끝났습니다.


200

나는 git stash pop병합 충돌로 끝났습니다. 파일 시스템에서 파일을 제거하고 git checkout아래와 같이했지만 파일이 여전히 병합되지 않은 것으로 생각합니다. 그런 다음 파일을 바꾸고 git checkout다시 동일한 결과 를 시도했습니다 . 나는 -f깃발 로 그것을 강요하려고했습니다 . 도움을 주시면 감사하겠습니다!

chirag-patels-macbook-pro:haloror patelc75$ git status
app/views/layouts/_choose_patient.html.erb: needs merge
app/views/layouts/_links.html.erb: needs merge
# On branch prod-temp
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   db/schema.rb
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       unmerged:   app/views/layouts/_choose_patient.html.erb
#       unmerged:   app/views/layouts/_links.html.erb

chirag-patels-macbook-pro:haloror patelc75$ git checkout app/views/layouts/_choose_patient.html.erb
error: path 'app/views/layouts/_choose_patient.html.erb' is unmerged
chirag-patels-macbook-pro:haloror patelc75$ git checkout -f app/views/layouts/_choose_patient.html.erb
warning: path 'app/views/layouts/_choose_patient.html.erb' is unmerged

참고 : 국가를 복원 하기 전에 (가) git stash apply/pop망할 놈의 2.5 (2015 년 2 분기)에 쉽게해야, 작업 트리 지금은 깨끗해야하므로 다음을 참조 아래에 내 대답을
VonC

답변:


219

man git merge를 참조하십시오 ( 충돌 해결 방법 ) :

충돌을 본 후 두 가지 작업을 수행 할 수 있습니다.

  • 병합하지 않기로 결정하십시오. 필요한 정리는 인덱스 파일을 HEAD 커밋으로 재설정하여 2를 반대로하고 2와 3으로 작성된 작업 트리 변경을 정리하는 것입니다. git-reset --hard를 사용할 수 있습니다.

  • 충돌을 해결하십시오. 힘내 작업 트리에서 충돌을 표시합니다. 파일을 모양으로 편집하고 git을 색인에 추가하십시오. git commit을 사용하여 거래를 봉인하십시오.

그리고 TRUE MERGE 아래에서 (2와 3이 무엇을 참조하는지) :

변경 사항을 조정하는 방법이 명확하지 않은 경우 다음이 발생합니다.

  1. HEAD 포인터는 동일하게 유지됩니다.

  2. MERGE_HEAD 참조는 다른 분기 헤드를 가리 키도록 설정되어 있습니다.

  3. 깔끔하게 병합 된 경로는 색인 파일과 작업 트리에서 모두 업데이트됩니다.

  4. ...

따라서 git reset --hard작업 트리에서 숨김 변경 사항을 제거하거나 git reset인덱스를 정리하고 작업 트리의 충돌을 그대로두고 손으로 병합하려는 경우 사용하십시오.

에서 남자 자식 은닉 ( 옵션, 팝 ) 당신은 추가로 읽을 수 있습니다 :

상태를 적용하면 충돌로 실패 할 수 있습니다. 이 경우 숨김 목록에서 제거되지 않습니다. 수동으로 충돌을 해결하고 git stash drop을 수동으로 호출하십시오.


9
실제로, 숨김을 삭제 한 후에도 변경 세트가 여전히 저장소에 있기 때문에 다시 검색하는 것이 더 어렵습니다 (더 어렵지만). stackoverflow.com/search?q=git+recover+dropped+stash
phils

3
@nalply : 좋은가요 나쁜가요? 당신은 처음에 그것을 이해하지 못한 내 대답을 향상시킬 수 있습니다 ...
tanascius

1
소스 코드 개정은 복잡한 문제 영역이라고 생각합니다. 혼동되기 쉽습니다. 나는 여전히 당신의 대답이 나의 접근 방식을 재확인했기 때문에 좋은 것이라고 생각합니다.
nalply

1
내가 가지고있는 것으로 가정 된 스 태쉬가 제거되지 않았다는 것을 인식하는 데 많은 도움이되었을뿐만 아니라, 이것이 확실하지 않은 경우에도 스 태쉬가 계속 자라는 이유를 설명합니다.
Thor84no

11
"상태를 적용하면 충돌로 인해 실패 할 수 있습니다.이 경우 숨김 목록에서 제거되지 않습니다." 이것은 내 의견으로는 게시물의 가장 중요한 부분입니다. 답을 수정하여 크고 친숙한 글자로 작성 하지 마십시오 라는 단어와 함께 표시하십시오 . (하지만 이미 +1) 감사합니다.
Patrick M

42

나는 나에게 비슷한 일이 일어났다. 파일을 아직 준비하고 싶지 않아서 파일을 추가 git add한 다음 수행했습니다 git reset. 이것은 기본적으로 내 변경 사항을 추가 한 다음 단계를 취소했지만 병합되지 않은 경로를 지우 었습니다.


4
reset --hard병합 문제가있는 파일을 제외하고 파일을 덮어 쓰지 않기 때문에 사용하는 것보다 낫습니다 . 감사!
sinelaw

파일을 아직 준비하고 싶지 않아 추가했습니다add . 작업 트리에서 색인으로 콘텐츠를 준비 하지 않습니까? 나는 당신의 답변이 설명에서 왜 작동하는지 이해하지 못한다고 생각합니다.
Drew Noakes

2
git add무대 git reset뒤에서 내가 무대 뒤에서하는 무대를 펼칩니다. 본질적으로 병합되지 않은 경로를 지우고 git out을 통해 정상적인 작업 트리로 돌아갑니다.
Aaron 3

3
git add가는 경우 필요하지 않습니다 git reset. git reset효과적으로 "상태 해제"를 git add. git reset( --mixed<-default)는 작업 디렉토리를 효과적으로 건드리지 않으므로 작업 디렉토리에 있던 내용, 병합 충돌 및 모두가 그대로 유지됩니다. 인덱스 (및 기술적으로 분기 헤드)는 재설정됩니다 (참조가 없으면 다시 재설정됩니다 HEAD. 이는 아마도 분기 헤드에 대한 변경이 없으며 git add인덱스에 대한 모든 작업을 효과적으로 취소 하고 병합되지 않은 경로 상태를 지우는 것을 의미합니다) .
bambams

3
순서 , 편집 / 해결 , git reset그리고 git stash drop잘 작동합니다. 그것은 무엇을합니까 git stash pop충돌없이 함께 할 것입니다. git add필요하지 않은 것 같습니다 . 유용 할 수도 있지만 충돌하는 많은 파일이 있습니다. 각각이 해결 되면 추가하고 git status추적 할 수 있습니다 .
artless noise

13

나처럼 일반적으로 원하는 것이 작업 디렉토리의 내용을 숨김 파일의 내용으로 덮어 쓰는데 여전히 충돌이 발생 git checkout --theirs -- .하면 루트에서 사용하여 충돌을 해결하는 것이 좋습니다 .

그 후에 git reset충돌이 발생하지 않은 파일에 대한 변경 사항이 색인에 남아 있기 때문에 색인에서 작업 디렉토리로 모든 변경 사항을 가져올 수 있습니다 .

git stash drop [<stash name>]나중에 git stash pop충돌을 제거 하지 않기 때문에 숨김을 제거하기 위해 나중에 실행할 수도 있습니다 .


2

참고 힘내 2.5 (2015 년 2 분기) 미래의 Git은 그 시나리오를 불가능하게 만들려고 노력할 것입니다.

참조 ed178ef 커밋 에 의해 제프 킹 ( peff) 22 년 4 월 2015
(에 의해 합병 Junio C 하마노 - gitster에 - 05c3967 커밋 , (19) 2015 월)

참고 : 이것은 되돌 렸습니다. 아래를 참조하십시오 .

stash: 깨끗한 인덱스를 적용 / 적용해야합니다

문제

색인에 내용을 준비하고 " stash apply/pop"을 (를) 실행 한 경우 충돌이 발생하여 색인에 새 항목을 넣을 수 있습니다.
이 시점에서 "git reset --keep"과 같은 도구는 준비된 것을 날려 버리기 때문에 원래 상태로 복구하기가 어렵습니다 .

다시 말해:

" git stash pop/apply"는 작업 트리뿐만 아니라 인덱스도 깨끗해야합니다.
후자는 숨김 애플리케이션이 충돌 할 수 있고 인덱스가 충돌 해결에 사용되므로 중요합니다.

해결책

단계적 변경이있을 때 적용을 거부함으로써이를보다 안전하게 만들 수 있습니다.

즉, 수정 된 파일에 숨김을 적용하여 (추가되었지만 커밋되지 않은) 이전에 병합이 있었다면 이제 숨김 적용 / 팝이 즉시 중지되므로 병합되지 않습니다.

Cannot apply stash: Your index contains uncommitted changes.

변경 사항을 커밋한다는 것은 병합의 경우를 사용하여 초기 상태 (before git stash apply/pop)를 쉽게 복원 할 수 있음을 의미합니다 git reset --hard.


참조 1,937,610 커밋 (2015년 6월 15일을), 및 ed178ef 커밋 에 의해 (2015 4월 22일) 제프 킹 ( peff) .
(의해 병합 Junio C 하마노 - gitster-커밋 bfb539b 24 유월 2015)

이 커미트는 애플리케이션 프로세스가 충돌하는 색인 ​​항목을 작성하고 원래 색인 상태를 복원하기 어렵 기 때문에 숨김 적용의 안전성을 개선하려는 시도였습니다.

불행히도 이로 인해 다음 git stash -k과 같은 " "관련 일반적인 워크 플로가 손상됩니다 .

git add -p       ;# (1) stage set of proposed changes
git stash -k     ;# (2) get rid of everything else
make test        ;# (3) make sure proposal is reasonable
git stash apply  ;# (4) restore original working tree

단계 (3)과 (4) 사이에 "git commit"을하면 이것이 작동합니다. 그러나 이러한 단계가 사전 커미트 후크의 일부인 경우 해당 기회가 없습니다 (테스트 통과 또는 실패 여부에 관계없이 원래 상태를 복원해야 함).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.