힘내 : 특정 커밋에 리베이스하는 방법? topic 에 A — B — C

다른 지점의 HEAD가 아닌 특정 커밋에 리베이스하고 싶습니다.

A --- B --- C          master
 \
  \-- D                topic

A --- B --- C          master
       \
        \-- D          topic

대신에

A --- B --- C          master
             \
              \-- D    topic

어떻게하면 되나요?



답변

원하는 커밋에 임시 브랜치를 만들어 –onto 매개 변수를 사용하지 않고 간단한 형식으로 rebase를 사용할 수 있습니다.

git branch temp master^
git checkout topic
git rebase temp
git branch -d temp

답변

직접 접근 할 수도 있습니다.

git checkout topic
git rebase <commitB>

답변

“onto”옵션을 사용하십시오 :

git rebase --onto master^ D^ D

답변

위의 jsz의 의견은 많은 고통을 덜어주었습니다. 따라서 다른 커밋 위에 커밋을 리베이스 / 이동시키는 데 사용했던 단계별 레시피가 있습니다.

  1. 리베이스 (이동) 할 분기의 이전 분기점을 찾으십시오.이를 이전 상위라고합니다. 위의 예에서 A는
  2. 분기를 이동하려는 커밋을 새 부모라고 부릅니다. Exampe에서 그것은 B입니다
  3. 지점 (이동 지점)에 있어야합니다.
  4. 리베이스를 적용하십시오 : git rebase --onto <new parent> <old parent>

위의 예에서 다음과 같이 간단합니다.

   git checkout topic
   git rebase --onto B A

답변

주제 솔루션

게시 된 질문에 대답하기위한 올바른 명령은 다음 중 하나 일 수 있습니다 (분기 topic가 이미 체크 아웃 되었다고 가정 ).

git rebase --onto B master
git rebase --onto master~1 master
git rebase --onto B A
git rebase --onto B C
git rebase --onto B

topic체크 아웃되지 않은 경우 다음 topic과 같이 명령에 마지막 명령을 추가 하면됩니다 (마지막 명령 제외).

git rebase --onto B master topic

또는 먼저 다음을 사용하여 지점을 확인하십시오.

git checkout topic

모든 커밋 문자열을 대상 커밋으로 리베이스

우리가 필요로하는 명령의 기본 형태는 다음과 같습니다.

git rebase --onto <Target> [<Upstream> [<Branch>]]

<Branch>선택적이며 나머지 명령을 실행하기 전에 지정된 분기를 체크 아웃하기 만하면됩니다. 리베이스하려는 지점을 이미 체크 아웃 한 경우 필요하지 않습니다. 사용자가 지정한해야합니다 <Upstream>지정하기 위해 <Branch>또는 자식이 당신이 지정하는 생각합니다 <Upstream>.

<Target>커밋 문자열을 첨부 할 커밋입니다. 지점 이름을 제공 할 때는 해당 지점의 헤드 커밋을 지정하기 만하면됩니다. <Target>이동되는 커밋 문자열에 포함되지 않는 커밋이 될 수 있습니다. 예를 들면 다음과 같습니다.

A --- B --- C --- D         master
      \
       \-- X --- Y --- Z    feature

전체 기능 지점을 이동하려면, 당신은 선택할 수 없습니다 X, Y, Z, 또는 feature는 AS <Target>그 이후 모든 이동하는 그룹 내부 커밋이다.

<Upstream>두 가지를 의미 할 수 있기 때문에 특별합니다. 체크 아웃 된 브랜치의 조상 인 커밋이면 컷 포인트 역할을합니다. 내가 제공 한 예에서,이없는 어떤 것 C, D또는를 master. <Upstream>체크 아웃 된 지점의 헤드가 이동 될 때까지의 모든 커밋

그러나 <Upstream>조상이 아닌 경우 git은 체크 아웃 된 분기가있는 공통 조상을 찾을 때까지 지정된 커밋에서 체인을 백업합니다 (찾을 수 없으면 중단). 우리의 경우,에서 <Upstream>B, C, D, 또는 master것입니다 커밋의 모든 결과 B절단 지점의 역할. <Upstream>자체는 선택적인 명령이며, 지정하지 않으면 git은 입력 한 것과 동일한 체크 아웃 된 브랜치의 부모를 찾습니다 master.

git은 커밋하고 이동할 커밋을 선택 <Target>했으므로 대상에 이미 적용된 커밋을 건너 뛰기 위해 커밋을 적용합니다 .

흥미로운 예와 결과

이 시작점을 사용하여 :

A --- B --- C --- D --- E         master
            \
             \-- X --- Y --- Z    feature
  • git rebase --onto D A feature
    커밋을 적용 B, C, X, Y, Z커밋하기 D및 스킵하지 않는 BC그들은 이미 적용되어 있기 때문이다.

  • git rebase --onto C X feature
    커밋 을 효과적으로 삭제하고 커밋 을
    적용 Y하고 커밋합니다.ZCX


답변

더 간단한 해결책은 git rebase <SHA1 of B> topic입니다. 이것은 당신의 위치에 관계없이 작동합니다 HEAD.

git rebase doc 에서이 동작을 확인할 수 있습니다

<upstream>비교할 업스트림 브랜치 기존 브랜치 이름뿐만 아니라 유효한 commit 일 수 있습니다 . 현재 분기에 대해 구성된 업스트림이 기본값입니다.


topic위의 명령에서
SHA1을 언급하면 ​​어떻게 될지 생각하고 있습니까?

git rebase <SHA1 of B> <SHA1 of topic>

이것은 또한 작동하지만 rebase는 Topic그렇게 만들어져 새로운 분기를 가리 키지 않으며 HEAD분리 된 상태가됩니다. 따라서 여기에서 이전을 수동으로 삭제 Topic하고 rebase에서 만든 새 분기에 새 분기 참조를 작성해야합니다.


답변

위에서 설명한 여러 가지 솔루션을 사용했습니다.

$ git branch temp <specific sha1>
$ git rebase --onto temp master topic
$ git branch -d temp

읽고 이해하는 것이 훨씬 쉽다는 것을 알았습니다. 수용 된 솔루션으로 인해 병합 충돌이 발생합니다 (손으로 수정하기에는 너무 게으르다).

$ git rebase temp
First, rewinding head to replay your work on top of it...
Applying: <git comment>
Using index info to reconstruct a base tree...
M       pom.xml
.git/rebase-apply/patch:10: trailing whitespace.
    <some code>
.git/rebase-apply/patch:17: trailing whitespace.
        <some other code>
warning: 2 lines add whitespace errors.
Falling back to patching base and 3-way merge...
Auto-merging pom.xml
CONFLICT (content): Merge conflict in pom.xml
error: Failed to merge in the changes.
Patch failed at 0001 <git comment>
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".