GIT를 사용하여 한 커밋의 변경 사항을 다른 '포크'에 선택적으로 병합하려면 어떻게해야합니까?


81

이 시나리오를 취하십시오.

  1. github.com에서 코드베이스를 '포크'하기로 결정하고 내 루틴을 시작합니다. Edit-Commit-Push; 일명 해킹 해킹 해킹.
  2. 몇 가지를 변경 한 후 다른 사람이 같은 프로젝트에서 변경 한 내용을보고 마음에 듭니다!
  3. 나는 그것들을 내 것으로 병합하기로 결정했습니다. 문제는 그가 만든 여러 커밋 중 하나의 특정 커밋의 '부분'만 원한다는 것입니다.

선택한 변경 사항을 '포크'에 병합하는 가장 효율적인 방법은 무엇입니까?



답변:


119

IRC 세계의 물결을 트롤링 한 후 누군가가 훌륭한 해결책을 제시했습니다.

git cherry-pick SHA1 --no-commit
git add --patch

같은 질문을 가진 다른 사람에게 도움이되기를 바랍니다.

편집 : 좋아, 어쩌면 그렇게 간단하지 않을 수도 있습니다. 전체 단계는 다음과 같습니다.

  1. 먼저 저장소에 있어야하며 필요한 cd-ing을 수행 하여 작업 디렉토리로 이동합니다.

  2. 이제 원격 분기를 추가 한 다음 가져와야합니다. 다음과 같이하십시오.

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. 이제 git log someUser/master'부분적으로'병합하려는 커밋 SHA1을 찾는 것과 같은 명령을 실행할 수 있습니다 .

  4. SHA가 있으면 이제 다음을 실행할 수 있습니다.

    git cherry-pick -n SHA1

    SHA1커밋 SHA는 어디에 있습니까 ?

  5. 커밋이 얼마나 오래되었는지, 프로젝트의 특정 영역이 얼마나 자주 변경되는지에 따라 충돌이있을 수 있습니다. 죄송합니다. 신뢰할 수있는 편집자와 수동으로 해결해야합니다. 따라서 VIM 또는 기타 사용하는 모든 것을 꺼내고 변경 사항이 마음에 드는 단계에 도달 할 때까지 충돌을 제거하십시오.

  6. 이제 인덱스를 HEAD 개정판으로 재설정 한 다음 신뢰할 수있는 GIT add --patch명령을 사용하여 원하는 변경 사항을 선택하고 선택할 수 있습니다.

    git reset HEAD

    git add --patch 또는 git add -p

  7. 예이! 커밋 시간 :

    git commit -m "I merged a select amount of changes"

  8. 엉망인 부분을 정리하고 (에서 아니요라고 말한 git add --patch내용) 선택한 변경 사항 만 작업 저장소에 유지하려면 다음을 실행합니다.

    git reset --hard HEAD

    분명히 git checkout -f또 다른 옵션입니다.


당신이 찾아서 다행입니다 git add -p. 매우 강력합니다. 문제의 커밋이 이미있는 경우 (예 : --no-commit체리 픽에서 사용하지 않았 거나 커밋 중 하나 인 경우) git reset HEAD^을 사용 하여 커밋을 다시 인덱스로 되 감은 다음을 사용 하여 변경 사항을 다시 추가하여 git add -p단계적으로 커밋 할 수 있습니다. . 커밋이 분기 팁에 없으면 해당 커밋을 사용 git rebase -i하고 편집하도록 선택할 수 있습니다 .
Cascabel

3
멋진 연습. 그냥 원하는 경우 기억 전체가 커밋 그냥 방출, -n이 같이 4 단계에서 :git cherry-pick SHA1
Hulvej

여기서 핵심은 git remote add <user> <fork-url>-그러면 git cherry-pick정상적으로 할 수 있습니다 .

2

나는 당신이 원하는 것을 명확하지 않습니다. 다른 포크에서 특정 커밋 만 가져 오려면을 사용할 수 있습니다 git cherry-pick SHA. gitready에 대한 전체 설명 .


특정 커밋의 '부분'/ '섹션'/ '몇 줄'만 내 저장소에 병합됩니다. 특정 파일이 아닙니다.
Tim

이 경우 git format-patch SHA, git apply <patch>는 옵션입니다
hgmnz

2

나는 Tim의 솔루션을 정말 좋아하지만 때로는 vimdiff에서 땜질하는 것을 좋아합니다. 이 문제에 대한 내 해결책은 조잡하지만 vim을 좋아하기 때문에 저에게 효과적입니다.

vimdiff를 내 difftool로 설정 한 다음 선택적으로 병합하려면 분기를 비교합니다.

git difftool <branch> <file>

그런 다음 현재 분기 버전이있는 창으로 이동하여 vim에서 원본을 편집하고 (때로는 필요하지 않지만 때때로 vimdiff가 / tmp에서 버전을 엽니 다) 읽기 전용 모드를 비활성화합니다.

:e <file>
:set readonly!

이제 do및 같은 vim의 패치 도구를 사용 dp하여 원하는 것을 적용 하고 진행 하면서 다른 작은 편집을 할 수 있습니다. 완료되면 파일을 저장하고 vim을 종료 한 다음 일반 편집처럼 git에서 파일을 준비하고 커밋합니다.

내가 말했듯이 이것은 특별히 정교하지는 않지만 매우 강력하며 여전히 순전히 명령 줄에 있습니다. git은 자동으로 병합 메시지를 포함하지 않으므로 명확한 커밋 메시지를 추가하십시오.

vimdiff 예제 http://j.mp/1dZVllt


나는이 답변이 독립적 인 완전한 답변이 될 가치가 있다고 생각하지 않습니다. 유용한 정보이지만 특별히 관련이 없습니다. (왜 대답의 상단이 있나요?)
마이크 Kormendy

1

커밋 포트만 원한다면 원하는 커밋을 선택하고 손대지 않으려는 파일을 재설정하는 것이 가장 좋습니다.

git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN

물론 파일에 수정 된 부분이 여러 개 있고 일부만 유지하려는 경우 파일을 수동으로 편집하여 변경 사항을 잘라낼 수밖에 없습니다.


2
여기에서 체크 아웃이 필요합니까? cherry pick 명령이 작업 디렉토리에 변경 사항을 적용하지 않습니까?
Casey Watson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.