programing

Git 워크플로우 및 기본 재배치 대 병합 질문

padding 2023. 5. 8. 21:57
반응형

Git 워크플로우 및 기본 재배치 대 병합 질문

저는 지금 Git을 다른 개발자와 함께 프로젝트에 몇 달 동안 사용하고 있습니다.는 SVN에서 몇 년간 일한 경험이 있기 때문에 관계에 짐을 많이 가지고 가는 것 같습니다.

Git이 분기와 합병에 탁월하다고 들었는데, 아직까지는 잘 보이지 않습니다.물론 가지치기는 아주 간단하지만, 합병을 시도하면 모든 것이 엉망이 됩니다.저는 SVN의 그것에 익숙하지만, 제가 보기에는 단지 하나의 하위 버전 시스템을 다른 시스템과 교환한 것 같습니다.

제 파트너는 제 문제가 윌리-닐리 합병에 대한 저의 열망에서 비롯되며, 많은 상황에서 합병 대신 리베이스를 사용해야 한다고 말합니다.예를 들어, 그가 설정한 워크플로우는 다음과 같습니다.

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature
git checkout master
git merge my_new_feature

기본적으로 피쳐 분기를 만들고 마스터에서 분기로 항상 기본 재배치한 다음 분기에서 마스터로 다시 병합합니다.중요한 점은 분기가 항상 로컬로 유지된다는 것입니다.

다음은 시작한 워크플로우입니다.

clone remote repository
create my_new_feature branch on remote repository
git checkout -b --track my_new_feature origin/my_new_feature
..work, commit, push to origin/my_new_feature
git merge master (to get some changes that my partner added)
..work, commit, push to origin/my_new_feature
git merge master
..finish my_new_feature, push to origin/my_new_feature
git checkout master
git merge my_new_feature
delete remote branch
delete local branch

두 가지 기본적인 차이점이 있습니다(제 생각에는).저는 기본 재배치 대신 항상 병합을 사용하고, 기능 분기(및 기능 분기 커밋)를 원격 저장소에 푸시합니다.

원격 지사에 대한 저의 이유는 업무를 수행하면서 업무를 백업해야 하기 때문입니다.저장소는 자동으로 백업되며 문제가 발생할 경우 복원할 수 있습니다.제 노트북은 그렇지 않거나 완전히 그렇지 않습니다.따라서 다른 곳에서 미러링되지 않는 코드를 노트북에 저장하는 것이 싫습니다.

rebase 대신 merge에 대한 저의 이유는 merge가 표준이고 rebase가 고급 기능인 것 같습니다.제 직감은 제가 하려는 것이 고급 설정이 아니기 때문에 리베이스가 필요하지 않아야 한다는 것입니다.저는 Git에 관한 새로운 실용적 프로그래밍 책을 읽었고, 그것들은 광범위하게 병합을 다루고 기본 재배치에 대해서는 거의 언급하지 않았습니다.

어쨌든, 최근 분기에 대한 워크플로우를 추적하고 있었는데, 마스터에 다시 병합하려고 했을 때 모든 것이 엉망이 되었습니다.중요하지 않아야 할 것들과 충돌이 많았습니다.그 갈등들은 저에게 말이 되지 않았습니다.모든 것을 해결하는 데 하루가 걸렸고 결국 원격 마스터에 대한 강제 푸시로 끝이 났습니다. 로컬 마스터는 모든 충돌을 해결했지만 원격 마스터는 여전히 만족하지 못했기 때문입니다.

이와 같은 것에 대한 "올바른" 워크플로우는 무엇입니까?Git는 분기와 합병을 매우 쉽게 만들 것으로 예상됩니다. 하지만 저는 그것을 보지 못하고 있습니다.

2011-04-15 업데이트

이것은 매우 인기 있는 질문인 것 같아서, 저는 제가 처음 질문했을 때부터 2년 동안의 경험으로 업데이트하려고 생각했습니다.

적어도 우리의 경우에는 원래 워크플로우가 정확한 것으로 나타났습니다.다시 말해서, 이것이 우리가 하는 일이고 그것은 작동합니다.

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge my_new_feature

사실, 우리의 작업 흐름은 조금 다릅니다. 생 병합 대신 스쿼시 병합을 하는 경향이 있기 때문입니다.(참고: 이는 논란의 여지가 있습니다. 아래를 참조하십시오.)이를 통해 전체 기능 분기를 단일 커밋 마스터로 전환할 수 있습니다.그런 다음 피쳐 분기를 삭제합니다.이를 통해 우리는 마스터에 대한 커밋을 논리적으로 구성할 수 있습니다. 브랜치가 조금 지저분하더라도 말입니다.우리가 하는 일은 다음과 같습니다.

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git checkout master
git merge --squash my_new_feature
git commit -m "added my_new_feature"
git branch -D my_new_feature

스쿼시 병합 논란 - 몇몇 논평가들이 지적했듯이 스쿼시 병합은 기능 분기의 모든 기록을 버릴 것입니다.이름에서 알 수 있듯이 모든 커밋을 단일 커밋으로 압축합니다.작은 기능의 경우 단일 패키지로 압축되므로 의미가 있습니다.더 큰 기능의 경우, 특히 개별 커밋이 이미 원자적인 경우에는 이 방법이 좋지 않을 수 있습니다.그것은 개인적인 취향에 따라 결정됩니다.

Github 및 Bitbucket(기타?) Pull Requests - 병합/리베이스가 Pull Requests와 어떤 관계가 있는지 궁금할 경우 마스터로 다시 병합할 준비가 될 때까지 위의 모든 단계를 수행하는 것이 좋습니다.수동으로 git와 병합하는 대신 PR을 수락합니다.이렇게 하면 스쿼시 병합이 수행되지 않지만(적어도 기본적으로는 그렇지 않음), 비 스쿼시, 비패스트 포워드 병합이 풀 요청 커뮤니티에서 허용되는 병합 규칙입니다(제가 알기로는).구체적으로 다음과 같이 작동합니다.

clone the remote repository
git checkout -b my_new_feature
..work and commit some stuff
git rebase master
..work and commit some stuff
git rebase master
..finish the feature, commit
git rebase master
git push # May need to force push
...submit PR, wait for a review, make any changes requested for the PR
git rebase master
git push # Will probably need to force push (-f), due to previous rebases from master
...accept the PR, most likely also deleting the feature branch in the process
git checkout master
git branch -d my_new_feature
git remote prune origin

저는 깃을 사랑하게 되었고 다시는 SVN으로 돌아가고 싶지 않습니다.만약 여러분이 어려움을 겪고 있다면, 그냥 그것을 고수하면, 결국 여러분은 터널 끝에서 빛을 보게 될 것입니다.

TL;DR

Gitrebase 워크플로우는 Git Disaster: A Gory Story에서 제안한 것처럼 충돌 해결에 서투른 사용자나 SVN 워크플로우에 익숙한 사용자로부터 사용자를 보호하지 않습니다.이는 충돌 해결을 더 지루하게 만들고 나쁜 충돌 해결에서 복구하는 것을 더 어렵게 만들 뿐입니다.대신 diff3를 사용하면 애초에 그렇게 어렵지 않습니다.


기본 재배치 워크플로우는 충돌 해결에 더 적합하지 않습니다!

나는 역사를 정화하는 것에 대해 매우 찬성합니다.하지만 충돌이 발생하면 즉시 리베이스를 중단하고 대신 병합을 수행합니다.사람들이 충돌 해결을 위한 병합 워크플로우의 더 나은 대안으로 기본 워크플로우를 추천하는 것은 정말 짜증나는 일입니다.

병합 중에 "모든 것이 지옥으로" 간다면, 기본 재배치 중에 "모든 것이 지옥으로" 갈 것이고, 잠재적으로 훨씬 더 지옥으로 갈 것입니다!이유는 다음과 같습니다.

이유 #1: 각 커밋에 대해 한 번이 아닌 한 번의 충돌 해결

병합 대신 기본 재배치를 수행하는 경우 동일한 충돌에 대해 기본 재배치를 커밋한 횟수만큼 충돌 해결을 수행해야 합니다!

실제 시나리오

저는 복잡한 방법을 브랜치에서 리팩터링하기 위해 마스터에서 분기합니다.리팩터링 작업은 리팩터링 작업과 코드 리뷰를 받기 위해 총 15개 커밋으로 구성되어 있습니다.리팩터링에는 이전에 마스터에 존재했던 혼합 탭과 공간을 수정하는 작업이 포함됩니다.이것은 필요하지만 유감스럽게도 마스터에서 이 방법을 나중에 변경하는 것과 충돌합니다.아니나 다를까, 내가 이 방법을 작업하는 동안 누군가가 마스터 분기에서 내 변경사항과 병합되어야 하는 동일한 방법을 간단하고 합법적으로 변경합니다.

브랜치를 마스터와 다시 병합할 때 두 가지 옵션이 있습니다.

git 병합:갈등이 생기네요.저는 그들이 제 지점을 마스터하고 통합하기 위해 변경한 사항을 알고 있습니다.다 했어요.

Gitrebase:저는 첫 번째 약속과 충돌을 겪습니다.나는 갈등을 해결하고 기지를 계속합니다.는 두 번째 약속과 충돌을 일으킵니다.나는 갈등을 해결하고 기지를 계속합니다.는 세 번째 약속과 충돌을 겪습니다.나는 갈등을 해결하고 기지를 계속합니다.는 제 네 번째 약속과 상충됩니다.나는 갈등을 해결하고 기지를 계속합니다.는 다섯 번째 약속과 충돌을 겪습니다.나는 갈등을 해결하고 기지를 계속합니다.는 제 여섯 번째 약속에 대해 갈등을 겪었습니다.나는 갈등을 해결하고 기지를 계속합니다.일곱 번째 약속과 충돌이 생깁니다.나는 갈등을 해결하고 기지를 계속합니다.는 제 여덟 번째 약속과 상충됩니다.나는 갈등을 해결하고 기지를 계속합니다.는 제 9의 약속과 충돌을 겪습니다.나는 갈등을 해결하고 기지를 계속합니다. 번째 약속과 상충됩니다.나는 갈등을 해결하고 기지를 계속합니다.저는 열한 번째 약속으로 갈등을 겪습니다.나는 갈등을 해결하고 기지를 계속합니다.는 제 열두 번째 약속과 상충됩니다.나는 갈등을 해결하고 기지를 계속합니다.저는 제 13번째 약속과 갈등을 겪습니다.나는 갈등을 해결하고 기지를 계속합니다.저는 14번째 약속과 상충됩니다.나는 갈등을 해결하고 기지를 계속합니다.저는 15번째 약속과 충돌을 겪습니다.나는 갈등을 해결하고 기지를 계속합니다.

이것이 당신이 선호하는 워크플로우라면 농담이겠지요.마스터에서 변경한 내용 하나와 충돌하는 공백 수정만 있으면 모든 커밋이 충돌하므로 해결해야 합니다.이것은 단순한 시나리오입니다. 공백 충돌만 있을 뿐입니다.파일 간의 주요 코드 변경과 관련된 실제 충돌이 발생하는 것은 금지되어 있으며 여러 번 해결해야 합니다.

당신이 해야 할 추가적인 갈등 해결로, 그것은 당신이 실수할 가능성을 증가시킬 뿐입니다.하지만 실수는 되돌릴 수 있으니까 괜찮아요, 그렇죠?물론...

이유 #2: 기본 재배치를 사용하면 실행 취소가 없습니다!

저는 우리 모두가 갈등 해결이 어려울 수 있고, 어떤 사람들은 그것을 매우 못 한다는 것에 동의할 수 있다고 생각합니다.그것은 실수를 하기가 매우 쉬우며, 이것이 git가 쉽게 되돌릴 수 있도록 하는 이유입니다!

분기를 병합할 때 Git는 충돌 해결이 제대로 수행되지 않을 경우 삭제하거나 수정할 수 있는 병합 커밋을 만듭니다.잘못된 병합 커밋을 이미 공개/권한 있는 저장소에 푸시한 경우에도git revert병합에 의해 발생한 변경 사항을 취소하고 새 병합 커밋에서 병합을 올바르게 다시 실행합니다.

분기를 재배치할 때 충돌 해결이 잘못될 가능성이 있는 경우에는 실패합니다.이제 모든 커밋에 잘못된 병합이 포함되어 있으므로 기본 재배치를 다시 수행할 수 없습니다*.기껏해야 다시 돌아가서 영향을 받는 각 커밋을 수정해야 합니다.재미없어요.

기본 재배치 후에는 원래 커밋의 일부였던 것과 잘못된 충돌 해결의 결과로 도입된 것을 확인할 수 없습니다.

*Git의 내부 로그에서 이전 ref를 발굴할 수 있거나, rebase 전에 마지막 커밋을 가리키는 세 번째 분기를 생성하면 rebase를 실행 취소할 수 있습니다.

분쟁 해결에서 지옥을 제거하세요: diff3를 사용하세요.

이 충돌을 예로 들어 보겠습니다.

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

갈등을 보면 각 지부가 무엇을 바꿨는지, 의도가 무엇이었는지 알 수 없습니다.이것이 갈등 해결이 혼란스럽고 어려운 가장 큰 이유라고 생각합니다.

구조를 위해 diff3!

git config --global merge.conflictstyle diff3

diff3를 사용하면 각 새 충돌에는 세 번째 섹션, 즉 병합된 공통 조상이 있습니다.

<<<<<<< HEAD
TextMessage.send(:include_timestamp => true)
||||||| merged common ancestor
EmailMessage.send(:include_timestamp => true)
=======
EmailMessage.send(:include_timestamp => false)
>>>>>>> feature-branch

먼저 병합된 공통 조상을 조사합니다.그런 다음 각 변을 비교하여 각 분지의 의도를 확인합니다.HEAD가 EmailMessage를 TextMessage로 변경한 것을 확인할 수 있습니다.TextMessage에 사용되는 클래스를 변경하여 동일한 매개 변수를 전달합니다.또한 feature-branch의 의도가 :include_timestamp 옵션에 대해 true가 아닌 false를 전달하는 것임을 알 수 있습니다.이러한 변경 사항을 병합하려면 다음 두 가지를 모두 결합합니다.

TextMessage.send(:include_timestamp => false)

일반적으로:

  1. 공통 조상을 각 분기와 비교하고 가장 단순한 변경 사항을 가진 분기 결정
  2. 다른 분기의 코드 버전에 단순 변경사항을 적용하여 보다 단순하고 복잡한 변경사항을 모두 포함합니다.
  3. 방금 변경사항을 병합한 섹션을 제외한 충돌 코드의 모든 섹션 제거

대체:분기의 변경 사항을 수동으로 적용하여 해결

마지막으로, 어떤 갈등은 diff3로도 이해하기가 끔찍합니다.이는 특히 diff가 의미론적으로 공통적이지 않은 공통 라인을 찾을 때 발생합니다(예: 두 분기 모두 동일한 위치에 빈 라인이 있음!).예를 들어, 분기 하나가 클래스 본문 들여쓰기를 변경하거나 유사한 메서드를 재정렬합니다.이러한 경우 병합의 양쪽에서 변경 사항을 검토하고 다른 파일에 수동으로 diff를 적용하는 것이 더 나은 해결 전략이 될 수 있습니다.

그럼 이제 병합을 할 때을 해결할 수 origin/feature1lib/message.rb갈등들.

  1. 된 지점지점)을합니다.HEAD또는--ours하는 분기()origin/feature1또는--theirs를 적용하면 사항이 더 는 적용하기 쉬운 변경 사항입니다.dot (트리플 도트와 함께 하기)git diff a...b에는 에 사항이 있습니다.b와의 마지막 분기 이후.a와 b의 공통 조상인 a와b를 .

    git diff HEAD...origin/feature1 -- lib/message.rb # show the change in feature1
    git diff origin/feature1...HEAD -- lib/message.rb # show the change in our branch
    
  2. 더 복잡한 버전의 파일을 확인해 보세요.이렇게 하면 모든 충돌 마커가 제거되고 선택한 쪽이 사용됩니다.

    git checkout --ours -- lib/message.rb   # if our branch's change is more complicated
    git checkout --theirs -- lib/message.rb # if origin/feature1's change is more complicated
    
  3. 복잡한 변경 사항을 체크 아웃한 상태에서 간단한 변경 사항의 차이를 늘립니다(1단계 참조).이 디프의 각 변경 사항을 충돌하는 파일에 적용합니다.

"충돌"은 "동일한 내용의 병렬 진화"를 의미합니다.따라서 병합 중에 "모든 것이 지옥으로" 간다면 동일한 파일 집합에 대해 엄청난 발전이 있을 것입니다.

리베이스가 병합보다 나은 이유는 다음과 같습니다.

  • 마스터의 로컬 커밋 기록을 다시 작성합니다(그리고 나서 작업을 다시 적용하여 충돌을 해결).
  • 최종 병합은 마스터의 모든 커밋 기록과 사용자의 변경사항만 다시 적용하기 때문에 확실히 "빠른 이전" 병합이 될 것입니다.

이 경우 올바른 워크플로우(공통 파일 집합의 진화)가 먼저 기본 재배치된 다음 병합되는지 확인합니다.

그러나 백업을 위해 로컬 분기를 푸시한 경우에는 다른 사용자가 해당 분기를 풀(또는 적어도 사용)해서는 안 됩니다(커밋 기록이 연속적인 기본 재배치에 의해 다시 작성되기 때문입니다).


이 주제(기본 재배치 후 워크플로우 병합)에 대해 바론토는 댓글 randyfay.com 의 두 가지 흥미로운 게시물을 언급합니다.

이 기술을 사용하면 작업이 항상 최신 패치처럼 공용 분기의 맨 위로 이동합니다.HEAD.

(바자에 대해서도 유사한 기법이 존재)

  • 기트 재해 피하기: 괴이한 이야기: 위험에 대하여git push --force의 경우)git pull --rebase예를 들어)

워크플로우에서 저는 최대한 기본을 변경합니다(그리고 자주 하려고 노력합니다).불일치가 누적되지 않도록 하면 지점 간 충돌의 양과 심각도가 크게 감소합니다.

그러나 대부분 기본 재배치 기반 워크플로우에서도 병합할 수 있습니다.

병합은 실제로 두 개의 부모가 있는 노드를 만듭니다.이제 다음과 같은 상황을 고려해 보겠습니다.저는 두 개의 독립적인 기능 브랜치 A와 B를 가지고 있으며, A와 B가 검토되는 동안 A와 B 모두에 의존하는 기능 브랜치 C에 대한 내용을 개발하고 싶습니다.

그러면 제가 하는 일은 다음과 같습니다.

  1. A 위에 지점 C를 생성(및 체크아웃)합니다.
  2. B와 병합

이제 C 지점은 A와 B의 변경 사항을 모두 포함하고 있으며, 저는 계속해서 개발할 수 있습니다.A를 변경하면 다음과 같은 방법으로 분기 그래프를 재구성합니다.

  1. A의 새 맨 위에 분기 T 생성
  2. T와 B를 병합하다
  3. C를 T로 베이스 변경
  4. 분기 T 삭제

이렇게 하면 실제로 분기의 임의 그래프를 유지할 수 있지만 상위 항목이 변경될 때 기본 재배치를 수행하는 자동 도구가 없다는 점에서 위에서 설명한 상황보다 더 복잡한 작업을 수행하는 것은 이미 너무 복잡합니다.

거의 모든 상황에서 git push origin을 사용하지 마십시오.

로컬 상자에 없는 원격 분기가 모두 지워지므로 이 작업을 수행할지 여부를 묻는 메시지가 표시되지 않으며, 확인하는 것이 좋습니다.

http://twitter.com/dysinger/status/1273652486

당신의 상황에서 저는 당신의 파트너가 옳다고 생각합니다.기본 재배치의 좋은 점은 외부자에게 변경 사항이 모두 자체적으로 깨끗한 순서로 발생한 것처럼 보인다는 것입니다.이것은 의미합니다.

  • 변경사항은 검토하기 매우 쉽습니다.
  • 당신은 계속해서 멋지고 작은 커밋을 만들 수 있지만, 동시에 그러한 커밋 세트를 공개(마스터로 병합)할 수 있습니다.
  • 공개 마스터 분기를 보면 여러 개발자가 서로 다른 기능에 대해 서로 다른 일련의 커밋을 볼 수 있지만 이들이 모두 혼합되지는 않을 것입니다.

백업을 위해 개인 개발 분기를 원격 저장소로 계속 밀어넣을 수는 있지만, 다른 사람들은 기본 재배치를 수행하기 때문에 이를 "공개" 분기로 취급해서는 안 됩니다.BTW, 이를 위한 쉬운 명령은 다음과 같습니다.git push --mirror origin.

Git를 사용한 패키징 소프트웨어 기사는 병합과 재베이스화의 트레이드오프를 설명하는 데 매우 유용합니다.이것은 약간 다른 맥락이지만 원칙은 같습니다. 기본적으로 지점이 공용인지 비공개인지 그리고 지점을 메인 라인에 어떻게 통합할 것인지에 따라 결정됩니다.

당신의 설명을 읽고 한 가지 질문이 있습니다.당신이 한 번도 한 적이 없는 것일 수도 있나요?

git checkout master
git pull origin
git checkout my_new_feature

기능 분기에서 'gitrebase/gitrebase master'를 수행하기 전에?

마스터 분기는 친구의 리포지토리에서 자동으로 업데이트되지 않기 때문입니다.당신은 그것을 그것과 함께 해야 합니다.git pull origin예를 들어, 당신은 항상 변하지 않는 지역 마스터 지점에서 기반을 재배치할 수 있습니까?그런 다음 푸시 시간이 되면 보지 못한 (로컬) 커밋이 있는 저장소를 밀어넣어 푸시가 실패합니다.

어쨌든, 최근 분기에 대한 워크플로우를 추적하고 있었는데, 마스터에 다시 병합하려고 했을 때 모든 것이 엉망이 되었습니다.중요하지 않아야 할 것들과 충돌이 많았습니다.그 갈등들은 저에게 말이 되지 않았습니다.모든 것을 해결하는 데 하루가 걸렸고 결국 원격 마스터에 대한 강제 푸시로 끝이 났습니다. 로컬 마스터는 모든 충돌을 해결했지만 원격 마스터는 여전히 만족하지 못했기 때문입니다.

파트너의 워크플로우나 제안된 워크플로우에서 이해할 수 없는 충돌이 발생해서는 안 됩니다.제안된 워크플로우를 따르는 경우에도 해결 후 '강제' 푸시가 필요하지 않습니다.이는 밀어넣던 분기를 실제로 병합하지는 않았지만 원격 팁의 하위 항목이 아닌 분기를 밀어넣어야 했다는 것을 나타냅니다.

무슨 일이 있었는지 잘 살펴보셔야 할 것 같습니다.로컬 분기를 생성한 시점과 로컬 분기에 다시 병합을 시도한 시점 사이의 원격 마스터 분기를 다른 사용자가 (의도적이든 아니든) 되돌렸을 수 있습니까?

다른 많은 버전 제어 시스템에 비해 Git을 사용하는 것이 도구와의 싸움을 덜 수반하고 소스 스트림에 기본적인 문제를 해결할 수 있다는 것을 알게 되었습니다.Git는 마법을 수행하지 않기 때문에 충돌하는 변경 사항은 충돌을 유발하지만 커밋 부모를 추적하여 쓰기 작업을 쉽게 수행할 수 있어야 합니다.

"지점이 몇 개 안 되는 단일 개발자라도 리베이스를 사용하는 습관을 들이고 적절히 병합하는 것이 가치가 있습니다.기본 작업 패턴은 다음과 같습니다.

  • 기존 분기 A에서 새 분기 B 생성

  • 분기 B에서 변경 사항 추가/커밋

  • A 지점의 기본 업데이트 재배치

  • B 지점에서 A 지점으로 변경사항 병합"

https://www.atlassian.com/git/tutorials/merging-vs-rebasing/

제가 관찰한 바로는, git merge는 병합 후에도 분기를 분리하여 유지하는 경향이 있는 반면, rebase 후 merge는 하나의 분기로 결합합니다.후자는 훨씬 더 깨끗하게 나오는 반면, 전자에서는 병합 후에도 어떤 커밋이 어느 분기에 속하는지 쉽게 찾을 수 있습니다.

Git를 사용하면 "올바른" 워크플로우가 없습니다.당신의 배를 띄우는 것은 무엇이든 사용하세요.그러나 지점을 병합할 때 지속적으로 충돌이 발생하는 경우 동료 개발자와 더 잘 조정해야 할 수도 있습니다.두 분이 계속 같은 파일을 편집하시는 것 같네요.또한 공백 및 하위 버전 키워드(예: "$Id$" 및 기타)를 주의하십시오.

리베이스 워크플로우만 사용합니다. 왜냐하면 리베이스 워크플로우는 시각적으로 더 선명하기 때문입니다(GitKraken 뿐만 아니라 Intellij 및 in).gitk하지만 첫 번째 것을 가장 추천합니다): 당신은 브랜치를 가지고 있고, 그것은 마스터로부터 시작되고, 그것은 마스터에게 돌아갑니다.도표가 깨끗하고 아름다울 때, 당신은 어떤 것도 지옥에 가지 않는다는 것을 알게 될 것입니다.

여기에 이미지 설명 입력

내 워크플로우는 당신의 워크플로우와 거의 동일하지만, 단 한 가지 작은 차이점이 있습니다.isquash이전에 내 지역 지점에 있는 하나로 커밋합니다.rebase에 대한 최신 변경 사항에 대한 나의 분기.master이유:

rebase 커밋에 기초한 작업

즉, 만약 당신이 15개의 커밋이 있다면 같은 라인을 변경합니다.master스쿼시를 하지 않으면 15번 확인해야 하는데, 중요한 것은 최종 결과죠?

따라서 전체 워크플로우는 다음과 같습니다.

  1. master합니다.

  2. 여기서 새 분기를 만듭니다.

  3. 그곳에서 당신의 일을 하세요, 당신은 자유롭게 여러 번 약속할 수 있고, 그것은 당신의 지점이기 때문에 걱정 없이 원격으로 밀고 나갈 수 있습니다.

  4. 다른 사용자가 "내 PR/MR이 승인되었습니다. 이제 마스터에 병합되었습니다."라고 말하면 해당 사용자를 가져오거나 끌 수 있습니다.언제든지 또는 6단계에서 수행할 수 있습니다.

  5. 모든 작업을 수행한 후에 커밋하고 여러 커밋이 있는 경우에는 해당 커밋을 제거합니다(모두 사용자의 작업이며 코드 줄을 몇 번 바꾸든 상관없습니다. 중요한 것은 최종 버전입니다.밀든 말든 상관없어요.

  6. master,pull최신 정보를 확인하기 위해 다시 한 번master.다이어그램은 다음과 유사해야 합니다.

여기에 이미지 설명 입력

보다시피, 당신은 당신의 지역 지점에 있으며, 이것은 당신의 오래된 상태로부터 시작됩니다.master,하는 동안에master(로컬 및 원격 모두) 동료의 변경 사항을 진행했습니다.

  1. 지점으로 다시 체크아웃하고 마스터로 다시 기본 설정합니다.이제 하나의 커밋만 있으므로 충돌을 한 만 해결할 수 있습니다.(그리고 GitKraken에서는 가지를 끌면 됩니다.master "베이스"를 합니다. "베이스또 다른 이유입니다라고 말합니다. 제가 좋아하는 또 다른 이유입니다.)그 후에는 다음과 같이 됩니다.

여기에 이미지 설명 입력

  1. 이제, 당신은 최근의 모든 변화를 가지고 있습니다.master지점의 변경 사항과 결합됩니다.이제 리모컨으로 밀 수 있으며, 이전에 밀었던 경우에는 강제로 밀어야 합니다. Git는 단순히 앞으로 밀 수 없다고 알려줍니다.기본 재배치로 인해 분기의 시작점이 변경된 것은 정상입니다.하지만 두려워해서는 안 됩니다. 현명하게 힘을 사용하세요. 하지만 두려움은 없습니다.결국, 리모트도 당신의 브랜치이므로 당신은 영향을 받지 않습니다.master당신이 잘못을 하더라도.

  2. /MR을 생성합니다.master당신의 공헌이 있을 것입니다.축하합니다!이제 체크아웃할 수 있습니다.master변경사항을 풀하고 로컬 분기를 삭제하여 다이어그램을 정리합니다.마스터에 병합할 때 원격 분기도 삭제해야 합니다.

최종 다이어그램은 깨끗하고 명확합니다.

여기에 이미지 설명 입력

언급URL : https://stackoverflow.com/questions/457927/git-workflow-and-rebase-vs-merge-questions

반응형