누락 된 파일을 포함하도록 과거 커밋을 변경하는 방법은 무엇입니까?


98

변경 사항을 커밋했고 변경 세트에 파일을 추가하는 것을 잊었습니다. 다른 커밋 후 파일이 HEAD^4커밋 에서 누락되었음을 깨달았습니다 .

누락 된 파일을 포함하도록 이전 커밋을 어떻게 다시 작성합니까?


이 4 개의 커밋을 푸시 했습니까?
mvp

@mvp nope, 그들은 내 로컬 git 저장소에만 있습니다.
kolrie

답변:


53

수정하려는 커밋에 대한 옵션을 사용 git rebase --interactive HEAD~4하고 설정 하십시오 edit.

당신이 기억 이 방법 원격 저장소에 밀어 커밋을 수정합니다. 이 경우 누락 된 파일이있는 새 커밋을 추가하는 것이 좋습니다.


감사. 원격 저장소의 유일한 사용자 인 경우에도 마찬가지입니까? 그것은 나를 수행 할 수없는 것 git push -f확실 업스트림 변경하지 않았다 나는 경우?
kolrie

1
원격 저장소의 유일한 사용자 인 경우 강제 푸시를 수행해도됩니다.
Rafał Rawicki

7
이 지침은 충분히 상세하지 않은 것 같습니다. 처음 시도했을 때 "리베이스 할 수 없음 : 인덱스에 커밋되지 않은 변경 사항이 포함되어 있습니다."라는 메시지가 표시되었습니다. 나는 이미 add누락 된 파일을 -ed 했으므로 "xxx"를 메시지로 커밋했습니다. 그런 다음 rebase 명령을 수행하고 "xxx"커밋을 "pick"에서 "edit"로 변경했습니다. 그런 다음 "git rebase --continue"를 수행했습니다. 이제 히스토리를 살펴보면 최신 커밋으로 "xxx"가 있으며 추가하고 싶었던 이전 커밋은 변경되지 않았습니다! 내 실수가 어디인지 궁금해?
Darren Cook

2
마지막 커밋을 스 쿼싱하면 파일이 HEAD ~ 4에 저장되지 않습니다.
Justin

1
git add editedFiles; git commit -m "Blah"; 자식 rebase -i HEAD ~ 5; // 이제 새 커밋이 추가되었으므로 4 대신 5로 리베이스해야했습니다. 이제 "Blah"커밋을 두 번째 줄로 이동하고 "Pick"에서 "s"(스쿼시)로 변경하여 커밋을 HEAD ~ 5 명령이 위에서 아래로 실행됨에 따라
zstring

274

사람들이 Google에서 더 간단한 답을 찾기 위해 여기로 올 수 있다는 것을 알고 있습니다 . 마지막 커밋이라면 어떨까요? (OP의 질문은 역사상 4 번째 커밋을 수정하는 것입니다)

커밋하고 즉시 파일을 추가하는 것을 잊은 경우 다음을 수행하십시오.

# edited file-that-i-remember.txt
git add file-that-i-remember.txt
git commit

# realize you forgot a file
git add file-that-i-forgot.txt
git commit --amend --no-edit

어디 --no-edit동일한 커밋 메시지를 보관할 것입니다.

쉬워요!


21
이것이 답입니다.
Adam Bittlingmayer

5
커밋이 원격으로 푸시되지 않으면 언급 할 가치가 있습니다.
Ram Patra

1
예, 여기 댓글에서 언급 할 가치가 있습니다 . 푸시 전에 사용하기 위한 것 입니다. 지적 해 주셔서 감사합니다.
Dr Beco

2
한주의 사항 및 이전 커밋 후이다 --amend다른 해시
sonlexqt

5
감사합니다.하지만 그럴 수 없습니다. OP가 HEAD^4. 참조를위한 부록처럼 괜찮습니다. )
박사 BECO

11

이 4 개의 커밋을 푸시하지 않은 경우 다음과 같이 할 수 있습니다.

이러한 모든 커밋에 대한 패치 파일을 만듭니다.

git format-patch -4

커밋 4 개 뒤로 되감기 :

git reset --hard HEAD~4

누락 된 파일 추가 :

git add missing-file

그것을 약속 --amend:

git commit --amend

저장된 모든 패치를 다시 적용하십시오.

git am *.patch

밀었다면이 방법을 사용하지 마십시오. 대신 실수를 인정하고이 문제를 해결하는 HEAD 위에 커밋을 하나 더 만드십시오.


이 단계를 단계별로 수행하려면 수정 된 커밋 후 커밋을 패치로 내보내는 것보다 커밋을 선택하는 것이 더 쉽습니다.
Rafał Rawicki

1
이것은 맛의 문제입니다. 나는 git format-patch/ git am훨씬 낫다. 가장 중요한 것은 무언가를 망칠 경우 더 많은 자신감을줍니다. 실제 파일에 패치로 저장된 커밋은 최고의 안전망입니다.
mvp

진정한 확신은 사실 git 저장소에서 작업 할 때 아무것도 제거하지 않는다는 것입니다. 당신이 실행할 때까지 이전 커밋을 사용할 수 있습니다 git gc:
라팔 Rawicki

이것은 당신과 나에게 사소하고 분명합니다. 그러나 막 시작하고 아마도 git에 대해 전혀 이해하지 못하는 사용자에게는이 사실이 전혀 분명하지 않습니다.
mvp

2
이 지침은 장황한 것처럼 보였지만 매우 간단하고 따르기 쉬웠습니다. 감사. (마지막 단계를 추가하겠습니다. rm *.patch)
Darren Cook

9

허용되는 답변은 정확하지만 리베이스 프로세스 중에 커밋을 편집하는 방법에 대한 자세한 지침이 없습니다.

  • 먼저 리베이스 프로세스를 시작하십시오.

    git rebase --interactive HEAD~4
    
  • 커밋 목록이 표시되면 단어 pick를 변경하여 편집 할 커밋을 선택 edit하고 파일을 저장합니다.

  • 코드에서 필요한 수정을합니다 ( git add새 파일 을 호출 하는 것을 잊지 마십시오 )

  • 모든 수정이 완료된 후 발행하십시오 git commit --amend. 이것은 다음과 같이 표시된 커밋을 수정합니다.edit

  • git rebase --continue프로세스를 완료 할 호출 (으로 표시된 커밋이 더있는 경우 edit위 단계를 반복해야 함)

중요 사항 :

  • pick편집하지 않으려는 줄은 제거 하지 말고 그대로 두십시오. 이 줄을 삭제하면 관련 커밋이 삭제됩니다.

  • GIT stash는 작업 디렉토리가 깨끗하지 않은 경우 리베이스 하기 전에 강제합니다 . 그러나 git stash pop / git stash apply리베이스 중에 이러한 변경 사항 (즉, 리베이스 프로세스를 시작하기 전에 숨겨진 변경 사항)을 다음과 같이 표시된 커밋으로 수정하기 위해edit

  • 무언가 잘못되어 리베이스 프로세스가 완료되기 전에 변경된 사항을 되돌리려면 (즉, 리베이스를 시작하기 전 지점으로 되돌리려는 경우) 다음을 사용하십시오 git rebase --abort.-또한 읽으십시오 : --abort if --abort does ' 일?

  • 받아 들여진 대답에서 말했듯이 :

    이런 방식으로 원격 저장소에 푸시 된 커밋을 수정해서는 안됩니다. 이 경우 누락 된 파일이있는 새 커밋을 추가하는 것이 좋습니다.

    그 이유에 대한 답은 Git Book ( " Rebasing의 위험 "이라는 제목의 단락 )에 있습니다.

    저장소 외부에있는 커밋을 리베이스하지 마십시오.

    이 지침을 따르면 괜찮을 것입니다. 그렇지 않으면 사람들이 당신을 미워할 것이고 당신은 친구와 가족들에게 멸시를 당할 것입니다.

    리베이스 할 때 기존 커밋을 버리고 비슷하지만 다른 커밋을 새로 만듭니다. 커밋을 어딘가에 푸시하고 다른 사람들이 커밋을 풀다운하고 기본 작업을 수행 한 다음 해당 커밋을 git rebase로 다시 작성하고 다시 밀어 올리면 공동 작업자가 작업을 다시 병합해야하며 시도 할 때 작업이 지저분해질 것입니다. 그들의 작업을 당신의 것으로 되돌립니다.

    [...]

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