한 지점에서 다른 지점으로 커밋을 복사하는 방법은 무엇입니까?


727

내 주인에게서 두 가지가 있습니다.

  • v2.1 : (버전 2) 몇 달 동안 작업했습니다.
  • wss : 어제 마스터에 하나의 특정 기능을 추가하기 위해 생성했습니다 (제작 중)

어제의 커밋을 wss에서 v2.1로 복사하는 방법이 있습니까?


한 분기에서 다른 분기로 커밋 (또는 커밋 범위)을 복사하기 위해이 답변이 가장 도움이되었습니다. stackoverflow.com/questions/1994463/…
caramba

답변:


564

실제로 다음을 병합하여이 모든 작업을 수행 할 수있는 워크 플로가 있어야합니다.

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (wss)

따라서해야 할 일은 git checkout v2.1git merge wss입니다. 어떤 이유로 든 실제로 이것을 할 수없고 git rebase 를 사용 하여 wss 브랜치를 올바른 위치로 옮길 수없는 경우 단일 커밋을 어딘가에서 가져 와서 다른 곳에서 적용하는 명령은 git cherry-pick 입니다. 적용하려는 지점을 확인하고 실행하십시오 git cherry-pick <SHA of commit to cherry-pick>.

rebase가 당신을 구할 수있는 몇 가지 방법 :

당신의 역사가 다음과 같다면 :

- x - x - x (v2) - x - x - x (v2.1)
           \
            x - x - x (v2-only) - x - x - x (wss)

git rebase --onto v2 v2-only wsswss를 v2로 직접 이동 하는 데 사용할 수 있습니다 .

- x - x - x (v2) - x - x - x (v2.1)
          |\
          |  x - x - x (v2-only)
           \
             x - x - x (wss)

그런 다음 병합 할 수 있습니다! 당신은 정말, 정말, 경우 정말 병합 할 수있는 점에 얻을 수 효과적으로 한 번에 여러 체리 픽을 수행하려면, 당신은 여전히 REBASE를 사용할 수 있습니다 :

# wss-starting-point is the SHA1/branch immediately before the first commit to rebase
git branch wss-to-rebase wss
git rebase --onto v2.1 wss-starting-point wss-to-rebase
git checkout v2.1
git merge wss-to-rebase

참고 :이 작업을 수행하기 위해 추가 작업이 필요한 이유는 저장소에 중복 커밋을 생성하기 때문입니다. 이것은 쉬운 일이 아닙니다. 쉬운 분기 및 병합의 요점은 커밋을 한 곳에서 만들고 필요한 곳으로 병합하여 모든 것을 할 수 있다는 것입니다. 중복 커밋은 두 가지 분기를 병합하지 않으려는 의도를 의미합니다 (나중에 결정하려는 경우 충돌이 발생 함).


1
이 답변에 더 동의하지 못했습니다. +1. 체리 따기의 결과를 설명하기 위해 내 이전 답변을 참조하십시오 : stackoverflow.com/questions/881092/…
VonC

18
이 방법을 올바르게 수행하는 방법에 대한 훌륭한 답변 ! ASCII 다이어그램을 작성하기 위해 두 번의 투표를 할 수 있기를 바랍니다.
gotgenes

@VonC : 지원해 주셔서 감사합니다. 왜 체리 픽을하지 말아야하는지에 대한 추가 정보입니다. @gotgenes : 감사합니다! 나는 그것이 노력할만한 가치가 있다고 생각합니다 .git-rebase 맨 페이지를보십시오. 그것을 설명하는 더 좋은 방법은 없습니다.
Cascabel

병합 할 수없는 이유는 무엇입니까-Git 병합은 git-svn과 잘 어울리지 않습니다. 하나의 SVN 브랜치에서 다른 SVN 브랜치로 일련의 커밋을 복사하기 위해 결국 체리 피킹을 한 다음 대화 형 리베이스 / 리워드를 수행하여 다시 git-svn-id참조하기 전에 잘못된 참조 를 제거 dcommit했습니다. 아마도 체리 픽 단계를 생략하고 리베이스를 사용했습니다.
Bob

1
내 유스 케이스는 다음과 같습니다. 중요한 버그 수정이 기능 분기에 적용되었습니다. 지금 생산에 들어가려면 마스터가 필요합니다. 이것은 내 엉덩이를 저장합니다.
Captain Hypertext

910

사용하다

git cherry-pick <commit>

현재 지점 에 적용 <commit>합니다 .

나는 아마도 내가 선택한 커밋을 교차 확인하고 gitk대신 커밋 항목을 마우스 오른쪽 버튼으로 클릭하여 선택합니다.


보다 자동으로 (모든 위험을 감수하고) 어제 wss에서 발생한 이후의 모든 커밋을 가정하면 git log( --prettyJefromi 가 제안한) 커밋 목록을 생성 할 수 있습니다

git log --reverse --since=yesterday --pretty=%H

그래서 당신이 사용한다고 가정하는 모든 것 bash

for commit in $(git log --reverse --since=yesterday --pretty=%H);
do
    git cherry-pick $commit
done

여기에 문제가 발생하면 (많은 가능성이 있습니다) 이것이 라이브 체크 아웃에서 작동하기 때문에 문제가 발생하므로 수동 체리 픽을 수행하거나 Jefromi가 제안한 rebase를 사용하십시오.


--pretty 옵션의 모든 자리 표시자는 git-log 맨 페이지에 있습니다. 원하는 형식을 얻을 수 있습니다. 특히 스크립트에 원하는 필드를 쉽게 파싱 가능한 형식으로 가져 오는 데 유용합니다.
Cascabel

또한 중복 커밋을 실제로 만들고 싶다고 가정하면 git rebase내 대답에 사용하는 방법 이 더 강력 하다는 것을 지적하고 싶습니다 . 특히, 이와 같은 for 루프를 사용하면 cherry-picks 중 하나가 실패해도 나머지 모든 작업을 계속 시도합니다. 이것은 ... 매우 좋지 않습니다.
Cascabel

2
동의했다. 그렇기 때문에 나는 그것을 사용하지 않지만 수동으로하십시오. 그러나 체리 픽은 여전히 ​​질문 제목에 대한 답입니다. 응답을 수정했습니다.
Benjamin Bannier

1
누군가가 오래된 / 잘못된 지점에 커밋하고 cherry-pick을 사용하면 해당 커밋을 올바른 지점에 넣을 수 있습니다 (커밋으로 유지하십시오). 완전한.
Patrick

8
드문 광경, git답이 답을 얼마나 잘 알고 있는지 확인하기 위해 자식의 복잡성을 통해 구불 구불하지 않고 솔루션에 간단하고 직선적 인 답변.
Przemek D

74

git cherry-pick : 기존 커밋이 도입 한 변경 사항을 적용합니다

(X, Y, Z) 커밋 이있는 분기 A 가 있다고 가정합니다 . 이러한 커밋을 분기 B 에 추가해야합니다 . 우리는 cherry-pick작업 을 사용할 것 입니다.

우리가 사용하는 경우 cherry-pick, 우리는 브랜치에 커밋을 추가해야합니다 B 커밋이 지점에 표시하는 것과 같은 순으로 .

cherry-pick은 다양한 커밋을 지원하지만 해당 범위에 병합 커밋이 있으면 실제로 복잡해집니다.

git checkout B
git cherry-pick SHA-COMMIT-X
git cherry-pick SHA-COMMIT-Y
git cherry-pick SHA-COMMIT-Z

워크 플로우 예 :

여기에 이미지 설명을 입력하십시오

옵션cherry-pick 과 함께 사용할 수 있습니다

-e 또는 --edit :이 옵션을 사용하면 git cherry-pick을 사용하여 커밋하기 전에 커밋 메시지를 편집 할 수 있습니다.

-n 또는 --no-commit : 일반적으로 명령은 커밋 순서를 자동으로 만듭니다. 이 플래그는 커밋하지 않고 명명 된 각 커밋을 작업 트리 및 인덱스에 체리 픽 픽킹하는 데 필요한 변경 사항을 적용합니다. 또한이 옵션을 사용하면 인덱스가 HEAD 커밋과 일치하지 않아도됩니다. 체리 픽은 인덱스의 시작 상태에 대해 수행됩니다.

흥미로운 이곳까지 기사 와 관련된를 cherry-pick.


19

당신은 할 수 패치 만들 당신이 복사하려는 커밋에서 패치를 적용 대상 지점에 있습니다.


16
어떤 이유로 든 체리 픽 / 리베이스 대신 패치를 사용하고 싶을지라도 git format-patch <revision range>and 를 사용하는 간단한 방법 git am *.patch입니다.
Cascabel

checkout다른 지점에 필요 합니다.
CoolMind

12

아니면 당신이 전도자의 편에 조금 덜 있다면 당신은 내가 사용하는 약간 못생긴 방법을 할 수 있습니다. deploy_template에는 마스터에 분기 배포로 복사하려는 커밋이 있습니다.

git branch deploy deploy_template
git checkout deploy
git rebase master

그러면 deploy_template에 새 분기 배포 (-f를 사용하여 기존 배포 분기를 덮어 씁니다)를 만든 다음이 새 분기를 마스터로 리베이스하여 deploy_template을 그대로 둡니다.


1

브랜치 wss에서 v2.1로 마지막 커밋을 복사하는 간단한 경우, 간단히 커밋 ID ( git log --oneline | head -n 1) 를 가져 와서 다음을 수행 할 수 있습니다 .

git checkout v2.1
git merge <commit>

이를 위해서는 다른 지점을 체크 아웃해야합니다.
CoolMind

1

cherry-pick 명령은 표준 입력에서 커밋 목록을 읽을 수 있습니다.

다음 명령 cherry-picks는 "develop"브랜치에는 있지만 "release"브랜치에는없는 John 사용자가 작성한 커밋 순서대로 커밋합니다.

git log develop --not release --format=%H --reverse --author John | git cherry-pick --stdin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.