source

깃체리픽 vs 리베이스

ittop 2023. 9. 9. 10:17
반응형

깃체리픽 vs 리베이스

저는 최근에 깃과 함께 일하기 시작했습니다.

Git book을 온라인으로 살펴보니 "Git Rebase" 섹션 아래에 다음이 있습니다.

rebase 명령을 사용하면 한 분기에서 커밋된 모든 변경 내용을 가져다가 다른 분기에서 다시 재생할 수 있습니다.

(인용: http://git-scm.com/book/en/Git-Branching-Rebasing)

이것이 깃체리픽의 정확한 정의라고 생각했습니다(현재 체크아웃된 분기에서 커밋 또는 커밋 개체 집합을 다시 적용).

그 둘의 차이점은 무엇입니까?

git cherry-pick커밋을 할 수 , 그 , 진화라고 ;-)을할는을고수만소로그한다은릴고렴은러,)한다;릴d고만렴은소s,;eoo)eeeye을gots러

진정한 차이는 두 가지 도구를 모두 만들려는 독창적인 의도에 있습니다.

  • git rebase의 작업은 일부 업스트림 브랜치의 버전 X에 대해 생성된 개인 저장소에 있는 개발자의 일련의 변경 사항을 해당 브랜치의 버전 Y(Y > X)로 포워딩하는 것입니다.이는 해당 일련의 커밋의 기반을 효과적으로 변경하므로 "재베이스"합니다.

    (또한 개발자가 임의의 커밋에 일련의 커밋을 이식할 수도 있지만, 이는 덜 명백한 용도입니다.)

  • git cherry-pick한 개발 라인에서 다른 개발 라인으로 흥미로운 커밋을 가져오는 것입니다. 것을 들 수 . 서 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δmerge말도 안 돼요. 원치 않는 변화를 가져올 테니까요.

    한 이래로, 부터 .git cherry-pick한 번에 여러 명의 커밋을 하나씩 선택할 수 있었습니다

두큰입니다. 즉, 의 은 를 입니다 하는 입니다 하는 를 은 의 git cherry-pick일반적으로 다른 곳에서 커밋을 가져와 현재 지점 위에 적용하여 새로운 커밋을 기록합니다.git rebase현재 분기를 사용하여 일련의 자체 팁 커밋을 어떤 식으로든 다시 작성합니다.네, 이건 뭐에 대한 설명인데요git rebase할 수는 있지만, 의도적인 것은 일반적인 생각을 가라앉히려고 하는 것입니다.

사용 예를 보다 자세히 설명하기 위해 업데이트git rebaseg

상황을 할 때, ,
a state of the repo before rebasing
은 다음과 같이 기술합니다.

하지만 또 다른 방법이 있습니다: C3에 도입된 변경의 패치를 가져다가 C4 위에 다시 붙일 수 있습니다.Git에서는 이것을 rebasing이라고 부릅니다.rebase 명령을 사용하면 한 분기에서 커밋된 모든 변경 내용을 다른 분기에 적용할 수 있습니다.

이 예제에서는 다음을 실행합니다.

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

여기서 "잡힌 점"은 이 예에서 "실험" 분기(리베이스 대상)는 원래 "마스터" 분기에서 분기되었으므로 C0부터 C2까지의 커밋을 공유한다는 것입니다. 효과적으로 "실험"은 C2와 커밋 C3을 포함하는 "마스터"입니다. (이는 가능한 가장 간단한 경우입니다. 물론,"실험"은 원래 기반 위에 수십 개의 커밋을 포함할 수 있습니다.)

지금이다git rebase"실험"을 "마스터"의 현재 팁에 기초하라고 지시하고,git rebase다음과 같습니다.

  1. 실행 git merge-base"실험"과 "마스터"가 공유하는 마지막 약속이 무엇인지 확인합니다(다시 말해 주의를 딴 데로 돌리는 이유가 무엇인지 확인합니다).C2입니다.
  2. 전환 시점 이후의 모든 커밋을 저장합니다. 장난감 예에서는 C3뿐입니다.
  3. 헤드(작업이 실행되기 전에 "실험"의 팁 커밋을 가리킴)를 되감기하여 "마스터"의 팁을 가리킵니다. 이를 기준으로 다시 설정합니다.
  4. 저장된 각각의 커밋을 적용하려고 합니다(예: 에 해당).git apply 예에서입니다.우리의 장난감 예에서 그것은 단지 하나의 커밋인 C3입니다.애플리케이션이 커밋 C3'을 생성한다고 가정해 보겠습니다.
  5. 모든 것이 잘 진행된 경우, 마지막으로 저장된 커밋(C3')을 적용한 커밋을 가리키도록 "실험" 참조가 업데이트됩니다.

이제 다시 질문으로 돌아가겠습니다.보시다시피, 여기 기술적으로 git rebase실제로 "실험"에서 "마스터"의 끝에 일련의 커밋을 이식하므로 이 과정에 실제로 "또 다른 분기"가 있음을 알 수 있습니다.하지만 요점은 "실험"의 팁 커밋이 결국 "실험"의 새로운 팁 커밋이 되었고, 그 기본을 바꿨다는 것입니다.
state after merging

다시 말하지만, 엄밀히 따지면 당신은git rebase여기에는 "마스터"의 특정 커밋이 포함되어 있으며, 이것은 절대적으로 정확합니다.

체리픽을 사용하면 원래 커밋/브랜치가 주변에 고정되고 새로운 커밋이 생성됩니다.rebase를 사용하면 분기가 재생된 커밋을 가리키는 상태로 전체 분기가 이동됩니다.

시작은 다음과 같습니다.

      A---B---C topic
     /
D---E---F---G master

밑줄 바꾸기:

$ git rebase master topic

다음을 얻을 수 있습니다.

              A'--B'--C' topic
             /
D---E---F---G master

체리픽:

$ git checkout master -b topic_new
$ git cherry-pick A^..C

다음을 얻을 수 있습니다.

      A---B---C topic
     /
D---E---F---G master
             \
              A'--B'--C' topic_new

git에 대한 자세한 내용은 이 책이 대부분 가지고 있습니다(http://git-scm.com/book) .

체리피킹은 개인적인 행위에 효과가 있습니다.

기준을 다시 설정하면 분기의 헤드에 기록에 있는 모든 커밋이 적용됩니다.

둘 다 한 분기의 커밋을 다른 분기 위에 다시 쓰기 위한 명령입니다. 차이점은 어느 분기에 있는지에 있습니다 - "당신의"(현재 체크아웃된 상태).HEAD) 또는 "branch"(브랜치가 명령에 인수로 전달됨) - 가 이 재작성의 기준이 됩니다.

git rebase 시작 커밋을 수행하고 자신의 커밋을 자신의 커밋(시작 커밋)을 따라오는 것으로 재생합니다.

git cherry-pick세트의 커밋을 받고 그 커밋을 당신의 것(당신의 것)에 따라 재생합니다.HEAD).

즉, 두 명령어는 핵심 동작(서로 다른 성능 특성, 호출 규칙 및 향상 옵션 무시)에서 대칭: 분기 체크아웃bargit rebase foo를 합니다.bar기과은기로기로기h은oesgytfoogit cherry-pick ..bar할을 설정할 입니다.foo경으로 )foo이 이어집니다.bar).

이름 지정 방식으로 두 명령의 차이점은 각 명령이 현재 분기에 대해 수행하는 작업을 설명한다는 점에서 기억할 수 있습니다.rebase다른 머리를 당신의 변화를 위한 새로운 기반으로 만드는 반면,cherry-pick다른 가지에서 변경 사항을 선택하여 사용자의 가지 에 올립니다(순대 위의 체리 등).

두 가지 모두 매우 유사한 일을 합니다. 주요 개념적 차이는 다음과 같습니다.

  • rebase는 커밋을 현재 분기에서 다른 분기로 이동합니다.

  • 체리픽 복사본이 다른 분기에서 현재 분기로 커밋됩니다.

@Kenny Ho의 답변과 유사한 도표를 사용하여:

이 초기 상태를 고려할 때:

A---B---C---D master
     \
      E---F---G topic

그리고 당신이 커밋을 받기를 원한다는 가정하에topic살서시는지efpyhdn시에서 위master브랜치, 두 가지 옵션이 있습니다.

  1. 기본 재배치 사용:당신이 먼저 가보는게 좋을거에요.topicgit checkout topic합니다. , 을 합니다 를 합니다 를 git rebase master :

    A---B---C---D master
                 \
                  E'---F'---G' topic
    

    결과: 현재 분기topic에 근거를 두었습니다.master.
    topic branch는master나뭇가지는 제자리에 있었습니다.

  2. 체리픽 사용하기: 먼저 다음으로 이동합니다.mastergit checkout master하고, 을 를 합니다 합니다 를 .git cherry-pick topic~3..topic이와 하게, )git cherry-pick B..G),:), 생산

    A---B---C---D---E'---F'---G' master
         \
          E---F---G topic
    

    결과: 의 커밋 수topic로 복사되었습니다.master.
    master branch는topic나뭇가지는 제자리에 있었습니다.


물론 여기서는 체리픽에게 범위 표기를 사용하여 일련의 커밋을 선택하라고 명시적으로 말해야 했습니다. foo..bar 같이 지점명을 했다면. 을 처럼 이 처럼 이 git cherry-pick topic과 같은 를 얻었을

A---B---C---D---G' master
     \
      E---F---G topic

간단한 대답:

  • 깃 체리 픽은 더 "낮은 레벨"입니다.
  • 이와 같이 깃베이스를 에뮬레이션 할 수 있습니다.

위에 제시된 답변은 좋습니다. 저는 단지 그들의 상호관계를 증명하기 위해 예를 들어 보고 싶었습니다.

"깃 리베이스"를 이러한 일련의 행동으로 대체하는 것은 권장되지 않으며, 단지 "개념의 증명"일 뿐이며, 이는 일이 어떻게 작동하는지 이해하는 데 도움이 되기를 바랍니다.

주어진 장난감 저장소:

$ git log --graph --decorate --all --oneline
* 558be99 (test_branch_1) Test commit #7
* 21883bb Test commit #6
| * 7254931 (HEAD -> master) Test commit #5
| * 79fd6cb Test commit #4
| * 48c9b78 Test commit #3
| * da8a50f Test commit #2
|/
* f2fa606 Test commit #1

예를 들어, 마스터에 몇 가지 매우 중요한 변경 사항(커밋 #2~#5)이 있으며 이를 test_branch_1에 포함하고자 합니다.보통 우리는 지점을 바꿔서 "깃 리베이스 마스터"를 합니다.하지만 우리는 "깃 체리 픽"만 장착한 척 하고 있기 때문에 다음과 같은 일을 합니다.

$ git checkout 7254931                # Switch to master (7254931 <-- master <-- HEAD)
$ git cherry-pick 21883bb^..558be99   # Apply a range of commits (first commit is included, hence "^")    

이러한 작업이 모두 끝나면 커밋 그래프는 다음과 같습니다.

* dd0d3b4 (HEAD) Test commit #7
* 8ccc132 Test commit #6
* 7254931 (master) Test commit #5
* 79fd6cb Test commit #4
* 48c9b78 Test commit #3
* da8a50f Test commit #2
| * 558be99 (test_branch_1) Test commit #7
| * 21883bb Test commit #6
|/
* f2fa606 Test commit #1

보시다시피 7254931(마스터의 팁 커밋)에 대해 6번과 7번 커밋이 적용되었습니다.HEAD가 이동되어 기본적으로 기본 분기의 일부인 커밋을 가리킵니다.이제 이전 분기 포인터를 삭제하고 새 분기 포인터를 만들면 됩니다.

$ git branch -D test_branch_1
$ git checkout -b test_branch_1 dd0d3b4

이제 test_fault_1이 최신 마스터 위치에서 루팅됩니다.알았어!

이들은 매우 다릅니다.

  • 리베이스는 분기를 업데이트하기 위해 분기를 수정하는 "마법적인" 작업입니다.
  • 대조적으로 체리 픽은 복사가 커밋하는 세밀한 작업입니다.

사실, 체리 픽은 리베이스를 대체하는데 사용될 수도 있습니다.

오래된 분기 문제:

구식 지사는 일상적인 시나리오입니다.

  1. 당신은 "마스터" 지점에서 분점하셨고,
  2. 몇 가지 변화를 일으켰고,
  3. 병행하는 동안 초기 "마스터" 분기도 변경되었습니다.

problem case

위에서 설명한 바와 같이, 이 초기 상태를 묘사하는 몇 가지 방법이 있습니다.

  • 여러 지점에서 동일한 커밋을 수행할 때 일종의 "가지된" 다이어그램을 표시하는 경향이 있습니다.실제로 각 분기에는 자체 커밋 라인이 있으며, 일부는 동일한 해시 코드를 가지고 있습니다.
  • 그 안에 있는 가지들 사이에 '마스터'나 '아이' 같은 것이 존재하지 않는다는 것을 깨닫는 것이 중요합니다.이 모든 것은 단지 명명 규칙에 의해 조정될 뿐입니다.

또한 대부분의 지점에는 로컬 버전과 원격 버전의 두 가지 버전이 있습니다.따라서 가능한 한 상세히 설명하고 싶다면 다음과 같이 설명합니다.

A--B--D      (remote) origin/master
     
A--B--C--E   (remote) origin/feature/foo
A--B--C--E   (local) feature/foo

는 commit 된 을 하기 입니다 하는 의 을 는 하는 입니다 을 의 는 하기 D하는 데는 두 . 그리고 이를 달성하는 데는 사실 두 가지 방법이 있습니다.

기저용액

Rebase는 실제로 기능 분기를 업데이트하는 마법의 명령어입니다.커밋( 커밋된밋즉여을다밋e여즉i을t된((go밋sys)밋g,D두 개의 커밋을 "뒤에" 있는 지점에.그리고 새로운 커밋 앞에 커밋을 추가함으로써 그렇게 합니다.

rebase

리베이스 후에 결과를 푸시하여 업데이트된 버전으로 원격 브랜치를 업데이트하기만 하면 됩니다.

A--B--D         (remote) origin/master
     
A--B--D--C--E   (remote) origin/feature/foo
A--B--D--C--E   (local) feature/foo

또는 그것이 종종 시각화되곤 했듯이.

look it moved

그리고 이는 우리의 기능 지점이 "이동"했다는 인상을 주는 반면, 실제로는 조금 더 길어졌습니다.

체리픽액

"하드 리셋"을 여러 개의 "체리 픽"과 결합하면 실제로 동일한 작업을 수행할 수 있습니다.같은 문제부터 시작해서 체리픽을 이용해 '수동 리베이스'를 해보겠습니다.

cherry pick rebase

리베이스와 같은 결과를 가져올 것입니다.

A--B--D         master
       \
        C--E    feature/foo

언급URL : https://stackoverflow.com/questions/11835948/git-cherry-pick-vs-rebase

반응형