2017-01-03 15 views
1

저는 커밋 된 8 개의 커밋을 편집하는 중대한 대화 형 리베이스를하고있었습니다. 이것은 git commit --amend으로 완료됩니다. 내 문제는 내가 한 번도 알지 못했던 병합 충돌이 있다는 것입니다. 따라서 순진한 수정을 계속했습니다. git rebase --continue -ing. 분명히 지금은 하나에 여러 커밋을 개정하고 내 커밋 중 약 4 rebase 완료 후 사라 졌어요. 변경 사항이 다른 커밋으로 수정되었습니다.대화식 리베이스에서 충돌을 해결하는 대신 수정했습니다. 실행 취소 할 수 있습니까?

내가 이러한 수정을 취소하거나 사라진 커밋을 다시 적용 할 수있는 방법이 있습니까?

물론입니다. 한 가지 해결책은 돌아가서 rebase를 다시하는 것이지만 rebase에서 많은 수정 작업을했기 때문에 모든 작업을 다시 할 필요가 없습니다. 내가이 곤경에 빠지게 된 것은 또 다른 이야기입니다.

망할 놈의 나무 예 : REBASE 후 A-B-C-D-E-F

: REBASE 전에

A-B-C-F (C 지금 개정 D와 E의 변경이있다) 예, 당신이 할 수있는

+0

'C' 커밋을 여러 원본 조각으로 풀어 낼 방법을 모르겠습니다. 나는 개인적으로 rebase를 다시 할 것이다. –

+0

여기에 2017가 있습니다. – Automatico

+0

아마도 다른 사람이 당신을 위해 은색 총알을 가지고있을 것입니다. 내가 말할 수있는 것부터 끝내면 더 나쁜 것이 될 것이다. –

답변

3

.

일반적으로 모든 것을 다시하고 다시 실행 하겠지만 문제를 이해할 수 있습니다. 이미 리베이스에 많은 시간을 투자 한 것처럼 들리므로 다시 시도 할 필요가 없습니다.

예에서 F의 내용이 정확히 최종 결과를 원하는 것으로 가정하면 DE 커밋이 누락 된 것입니다. 작업 디렉토리가 F 포함되도록

git checkout C    # "git status" should be empty right now 
git checkout F . 
git reset . 
git add only-changes-from-D ; git commit -m D 
git add only-changes-from-E ; git commit -m E 
git add -A ; git commit -m F 

git checkout F . ; git reset . 그것을 만들지 만, 머리는 여전히 C에 놓고, 아무것도 인덱스에 없습니다 :

은 당신이 할 수있는 일은 이것이다. git status은 이제 CF 사이의 완전한 차이점을 보여줍니다.

좋아하는 추가/커밋 도구 (예 : git gui)를 가져 와서 원래 D에 속한 모든 변경 사항을 선택하고 승인합니다. E에 대해 반복하십시오. 그 후에는 F의 변경 사항 만 있습니다. 한 번에 추가하고 커밋 할 수 있습니다. 물론, EF 사이에 더 많은 것이 있으면 씻어서 반복해야합니다.

이렇게하면 실제로 아무것도 변경할 필요가 없다는 이점이 있습니다. 최종 결과는 정확하게 F이지만, 필요에 따라 몇 가지 중간 커밋을 얻게됩니다.

2

커밋을 리베 제팅/수정 한 후에도 원래 커밋이 계속됩니다. 지점을 통해 도달 할 수 없더라도 git log에는 나타나지 않습니다.

나는 git reflog의 도움으로 당신이 원하는 것을 할 수 있다고 생각합니다.

git reflog //identify the hash of the commits you want, look for your commit --amend that you want to undo git checkout B git cherry-pick hash-of-commit-C-as-resolved-during-rebase-but-before-amending git cherry-pick hash-of-commit-C-after-amending-with-D git cherry-pick hash-of-commit-C-after-amending-with-E git cherry-pick F

3

모든 당신이 만든 수정 또는하지 않는 것이 커밋, "거기에"아직, 그들은 모두 찾을-수있는 reflogs을 통해.이는 git commit --amend이 아니기 때문에 실제로 변경 일 뿐이므로 은 그랬듯이 "이전의 것을 깎아 내림"이라고 말합니다.

이 (git commit이 커밋하기를 거부 있도록 충돌 상태가 인덱스가 있다면 즉,) 물론, 저장되지 않았습니다하지 메이크업을 한 것을 커밋합니다.

각 커밋을 찾으려면 git reflog (또는 git reflog HEAD)을 사용하십시오. [email protected]{3} 등의 쉬운 이름 지정 방법은 모두 상대적이며 계속 이동하므로 잘라 내기 및 붙여 넣기 용 파일에 원시 해시 ID를 저장할 수 있습니다. ([email protected]{3}을 무엇 즉, 당신이 HEAD 조정 때마다, augh, 결국 [email protected]{198}, 이제 곧 [email protected]{7}[email protected]{4}, [email protected]{5}, 그리고! :-)) 당신이하지 않은 경우

당신은 또한 (바로 다시 원래의 사슬을 얻을 수 있습니다 다른 명령을 실행하십시오.) 이름은 ORIG_HEAD입니다. 즉, git rebase -i을 실행 한 다음 편집, 수정 커밋 등을 수행하고 마지막으로 완료하면 git rebase은 원래 분기 팁을 ORIG_HEAD이라는 이름으로 저장합니다. 당신은 그 원래의 커밋에 새로운 지점 또는 태그 이름 지점을 확인한 다음 원래 (사전 REBASE)을 다시 참조 할 name, name~1, name~2 등 사용할 수 있습니다 커밋 :

git tag oops ORIG_HEAD 

을 지금 oops입니다 커밋 F, oops~1E 등입니다.

당신은 어떤 git checkout <commit-id> -- <path> 등등 즉 현재의 위치로 델타로 커밋 적용, 그것의 git cherry-pick <commit-id>을 파일을 얻을하고, 커밋 git show 수 있습니다.