기능 분기로 Git 병합 마스터


1015

Git에 다음과 같은 상황이 있다고 가정 해 봅시다.

  1. 작성된 저장소 :

    mkdir GitTest2
    cd GitTest2
    git init
    
  2. 마스터에서 일부 수정이 이루어지고 커밋됩니다.

    echo "On Master" > file
    git commit -a -m "Initial commit"
    
  3. Feature1은 마스터에서 분기되었으며 일부 작업이 완료되었습니다.

    git branch feature1
    git checkout feature1
    echo "Feature1" > featureFile
    git commit -a -m "Commit for feature1"
    
  4. 한편, 마스터 코드에서 버그가 발견되고 핫픽스 브랜치가 설정됩니다.

    git checkout master
    git branch hotfix1
    git checkout hotfix1
    
  5. 버그는 핫픽스 분기에서 수정되어 마스터로 다시 병합되었습니다 (아마 풀 풀 요청 / 코드 검토 후).

    echo "Bugfix" > bugfixFile
    git commit -a -m "Bugfix Commit"
    git checkout master
    git merge --no-ff hotfix1
    
  6. feature1에 대한 개발은 계속됩니다.

    git checkout feature1
    

기능 분기에 핫픽스가 필요하다고 가정 해 보겠습니다. 버그가있을 수도 있기 때문일 수 있습니다. 커밋을 기능 분기에 복제하지 않고 어떻게 이것을 달성 할 수 있습니까?

기능 구현과 관련이없는 기능 지점에서 두 개의 새로운 커밋을 얻지 못하게하고 싶습니다. 풀 요청을 사용하는 경우 특히 중요합니다. 이러한 모든 커밋은 풀 요청에도 포함되며 이미 완료되었지만 (핫픽스가 이미 마스터에 있으므로) 검토해야합니다.

git merge master --ff-only"치명적 : 빨리 감기, 중단 할 수 없음"을 수행 할 수 없지만 이것이 도움이되었는지 확실하지 않습니다.


8
지점 feature1이 완전히 로컬 인 경우을 살펴보십시오 git rebase.
Jokester

19
감사합니다, git 초보자로서, git rebase저에게는 흑 마법처럼 보입니다 ....
theomega

13
지점이 기능인 경우 -이 지점의 목적은 새로운 기능을 표시하는 것이므로 버그 수정 만 발생해서는 안됩니다 (적어도 블로킹 버그가 아닌 경우). 수정 사항이있는 커밋이있는 마스터와 병합되면 버그가 수정됩니다.
gipi

21
아마 가치가 초보자를위한 주목할 3에 있음 git branch feature1git checkout feature1결합 될 수있다 git checkout -b feature14. 완전히 감소 될 수있다git checkout -b hotfix1 master
나루토 Sempai

3
현재 허용되는 답변이 끔찍하기 때문에 다시 돌아와서 수락 된 답변을 변경 하시겠습니까?
Omnifarious

답변:


1215

마스터 브랜치를 피처 브랜치로 어떻게 병합합니까? 쉬운:

git checkout feature1
git merge master

여기서 빨리 감기 병합을 수행 할 수는 없습니다. 기능 분기와 마스터 분기에 모두 커밋했습니다. 빨리 감기는 불가능합니다.

GitFlow를 살펴 보십시오 . 그것은 따라갈 수있는 git의 분기 모델이며, 무의식적으로 이미 수행했습니다. 또한 수동으로 수행해야하는 작업을 자동으로 수행하는 새 워크 플로 단계에 대한 명령을 추가하는 Git의 확장입니다.

워크 플로우에서 무엇을 했습니까? 작업 할 두 개의 브랜치가 있으며 feature1 브랜치는 기본적으로 GitFlow 모델의 "개발"브랜치입니다.

master에서 핫픽스 분기를 만들어 다시 병합했습니다. 그리고 지금 당신은 붙어 있습니다.

GitFlow 모델은 핫픽스를 개발 브랜치 (여러분의 경우 "feature1")에도 병합하도록 요청합니다.

따라서 실제 답변은 다음과 같습니다.

git checkout feature1
git merge --no-ff hotfix1

핫픽스 내에서 변경된 모든 기능이 기능 분기에 추가되지만 해당 변경 사항 만 추가 됩니다. 브랜치의 다른 개발 변경 사항과 충돌 할 수 있지만, 기능 브랜치를 다시 마스터로 병합하면 마스터 브랜치와 충돌하지 않습니다.

리베이스에 매우주의하십시오. 변경 사항이 저장소에 로컬로 유지 된 경우에만 리베이스하십시오 (예 : 분기를 다른 저장소로 푸시하지 않은 경우). Rebasing은 지역 커밋을 유용한 순서로 정리하여 세상에 밀어 넣는 데 유용한 도구이지만 나중에 다시 시작하면 여러분과 같은 git 초보자에게 문제가 생길 수 있습니다.


7
아니요. 버그를 수정 한 커밋은 지점 이름이 마스터와 개발 지점으로 병합 된 후에 삭제 되더라도 핫픽스 지점에 한 번만 나타납니다. 병합 커밋은 병합에 의해 도입 된 변경 사항 만 표시하며 중복 커밋처럼 보입니다. 그러나 이것은 git의 작동 방식입니다 : Branch and merge back. 실제 개발 작업은 병합되지 않은 커밋에서만 발생하며 병합은 결과가 작동하는 소프트웨어 인 경우에만 허용됩니다.
Sven

42
이것이 정답입니다. GitHub의 풀 요청 기능과도 잘 작동합니다.
Nostalg.io

125
로컬 마스터 사본 git merge master에서 a 가 병합 된다는 점에 주목할 가치가 있다고 생각합니다. 다른 누군가가 다른 지점을 마스터에 병합 한 후 기능 지점에서 작업을 수행 한 경우에도 , 그런 다음 , 그리고 다시 해야합니다 . . git pullgit checkout mastergit pullgit checkout feature1git merge master
damick

50
@damick 또는 단지 git fetchgit merge origin/master
Yngvar Kristiansen이에게

20
@damick @ yngvar-kristiansen git pull origin masterorgin/master현재 지점 으로 자동 병합 됩니다
L422Y

612

마스터에서 브랜치를 리베이스 할 수 있어야합니다.

git checkout feature1
git rebase master

발생하는 모든 충돌을 관리하십시오. 버그 수정 (마스터로 이미)으로 커밋을 받으면 Git은 변경 사항이 없으며 이미 적용되었을 수 있다고 말합니다. 그런 다음 마스터에서 이미 커밋을 건너 뛰면서 리베이스를 계속하십시오.

git rebase --skip

git log기능 분기에서 를 수행 하면 버그 수정 커밋이 한 번만 마스터 부분에 나타납니다.

자세한 내용은 이 정확한 사용 사례를 다루는 Git 서적 git rebase( https://git-scm.com/docs/git-rebase )을 참조하십시오 .

================ 추가 컨텍스트 편집 =====================

이 답변은 특정 상황을 고려하여 @theomega가 질문 한 내용을 위해 특별히 제공되었습니다. 이 부분에 유의하십시오.

기능 구현과 관련이없는 기능 분기에서 [...] 커밋을 방지하고 싶습니다.

개인 브랜치를 마스터에 기반을 두는 것이 바로 그 결과를 가져옵니다. 반면에 마스터를 자신의 브랜치에 병합하면 자신이 구체적으로 원하지 않는 일을 정확하게 수행 할 수 있습니다.

질문 제목을 읽는 사용자를 해결하려면 질문의 실제 내용과 컨텍스트를 건너 뛰고 항상 (다른) 유스 케이스에 적용된다고 가정하고 최상위 답변 만 맹목적으로 읽으십시오.

  • 개인 브랜치 만 리베이스하십시오 (즉, 로컬 저장소에만 존재하고 다른 사람들과 공유하지 않은 것). 공유 지점을 리베이스하면 다른 사람들이 가질 수있는 사본을 "파손"할 수 있습니다.
  • 브랜치 (마스터 또는 다른 브랜치)의 변경 사항을 퍼블릭 브랜치로 통합하려면 (예 : 브랜치를 푸시 요청을 열도록 푸시했지만 이제는 마스터와 충돌하므로 업데이트해야합니다. 이러한 충돌을 해결하려면 지사를 통합해야합니다 (예 : git merge master@Sven의 답변에서 와 같이).
  • 원하는 경우 지점을 로컬 개인 지점으로 병합 할 수도 있지만 지점에서 "외국"커밋이 발생한다는 점에 유의하십시오.

마지막으로 @theomega에 대한 답변이이 답변이 현재 상황에 가장 적합하지 않다는 사실에 불만이있는 경우 아래에 의견을 추가해도 도움이되지 않습니다. 어떤 답변을 선택했는지는 결정하지 않습니다. @theomega 만합니다.


136
아니요, 안전하지 않습니다. 리베이스하는 경우 지점 기록을 변경하여 지점을 가져간 개발자에게 영향을 미칩니다. 기본적으로 git은 기본적으로 rebased 브랜치를 푸시 할 수 없습니다 -f. rebased 버전으로 브랜치를 덮어 쓰 려면 강제로 업데이트해야합니다 . 조심해!
David Sulc

17
자식을 사용하는 전문 팀은이 문제를 어떻게 처리합니까? 그냥주의를 기울이고 신중하게 생각한 다음 수행 -f합니까? 또는 내가 필요하기 때문에 전체 워크 플로에 결함이 -f있습니까?
theomega

30
글쎄, 나는 "신성한"규칙에 합의했다. 당신은 공유 된 코드에 근거를 두지 않거나 커밋 히스토리를 바꾸지 않는다는 것이다. 그것은 오직 당신의 지역 코드만을위한 것이다. 기본적으로 변경 사항을 공유하기 전에 "정리"로 변경해야합니다. 귀하의 경우, 새로운 재 기반 지점 (다른 이름을 가짐)을 푸시하고 동료들에게 해당 지점에서 변경 사항의 기초를 두도록 요청할 수 있습니다 (예 : 위와 같이 로컬 지점을 새로운 지점에서 리베이스). 그런 다음 feature1Github 에서 삭제하십시오 .
David Sulc

19
내가 작업 한 대부분의 전문 팀은 리베이스를 거의 사용하지 않습니다. 기본적으로 모든 항목을 병합하기 때문에 기록 수정이 발생하지 않습니다. 이것이 내가 선호하는 작업 방식입니다. 그들을 밀어 넣기 전에 반면에, 일부 팀은 '정리'커밋에 REBASE를 사용 (하지만 결코 누른 후.)
조나단 하틀리

11
그렇습니다. 공공 지점을 리베이스하지 마십시오. 그러나 OP의 질문은 새로운 커밋을 master개인 브랜치 에 통합하는 것을 다루는 것처럼 보였다 (그는 "그의"로컬 브랜치를 언급한다). 이 경우 rebase에는 괜찮으며 언급 한 "정리"와 동일한 사용 사례입니다.
David Sulc

69

이 기사를 기반으로 다음 을 수행해야합니다.

  • 새 버전의 마스터를 기반으로 새 분기를 만듭니다.

    git branch -b newmaster

  • 기존 기능 지점을 새 기능 지점으로 병합

    git checkout newmaster

  • 새로운 기능 브랜치에서의 충돌 해결

처음 두 명령은에 결합 될 수 있습니다 git checkout -b newmaster.

이렇게하면 다시 병합 할 필요가 없기 때문에 기록이 명확하게 유지됩니다. 또한 Git 리베이스를 수행 할 필요가 없으므로 매우주의 할 필요가 없습니다.


7
관련 git 명령이 각 지점을 따르도록하면 좋을 것입니다. 그렇지 않으면 이것이 실제로 더 안전하고 깨끗한 옵션 인 것 같습니다.
VirgileD

@zimi 원격 지사가있는 경우는 어떻습니까? 새 업데이트 기능 분기를 다시 작성합니까? 아니면 그냥 원격 업스트림을 설정할 수 있습니까?
BILL

@VirgileD 방금 관련 git 명령을 포함하여 자세한 내용과 함께 내 자신의 답변 을 게시했습니다 .
jkdev

29

git merge

아래 단계를 수행 할 수 있습니다

1. origin/master지점을 feature지점으로 병합

# step1: change branch to master, and pull to update all commits
$ git checkout master
$ git pull

# step2: change branch to target, and pull to update commits
$ git checkout feature
$ git pull

# step3: merge master to feature(⚠️ current is feature branch)
$ git merge master

2. feature지점을 origin/master지점으로 병합

origin/master원격 마스터 브랜치 인 반면 master로컬 마스터 브랜치는

$ git checkout master
$ git pull origin/master

$ git merge feature
$ git push origin/master




리베이스가 과장된 느낌! 좋은 오래된 병합 :)!
Foreever

27

Zimi의 답변 은이 프로세스를 일반적으로 설명합니다. 구체적인 내용은 다음과 같습니다.

  1. 새 분기를 작성하고 전환하십시오. 새 분기가 기반이되는지 확인하여 master최신 핫픽스가 포함되도록하십시오.

    git checkout master
    git branch feature1_new
    git checkout feature1_new
    
    # Or, combined into one command:
    git checkout -b feature1_new master
    
  2. 새 지점으로 전환 한 후 기존 기능 지점의 변경 사항을 병합하십시오. 이것은 핫픽스 커밋을 복제하지 않고 커밋을 추가합니다.

    git merge feature1
    
  3. 새 지점에서 기능과 마스터 지점 간의 충돌을 해결하십시오.

끝난! 이제 새 브랜치를 사용하여 기능을 계속 개발하십시오.


2
이것의 문제점은 개발자가 마스터에 대해 업데이트해야 할 때 새로운 지점을 지속적으로 생성하는 데 시간을 낭비한다는 것입니다. 우리는 활발한 작업을하는 동안 하루에 3 번 정도 많은 가지를 만들 것입니다. 모든 로컬 휴지통을 정리하고 원격으로 제거하는 방법에 대한 지침을 작성해야합니다. 혼동하지 않도록 이러한 모든 브랜치의 이름을 지정하는 데 대한 조언이 필요합니다. 이 비트가 없으면 분기 시스템이 혼란에 빠지게됩니다.
pauljohn32

4
당신 말이 맞아, 이것은 항상 끝나서는 안된다. 기능에 (1) 마스터의 변경이 필요하거나 (2) 지점을 마스터와 병합하려고 할 때만 충돌이 발생할 수 있습니다. 혼란을 피하기 위해 병합 된 분기를 삭제할 수 있습니다.
jkdev 2016 년

11

다음은 마스터 브랜치를 현재 브랜치로 병합하는 데 사용할 수있는 스크립트입니다.

스크립트는 다음을 수행합니다.

  • 마스터 브랜치로 전환
  • 마스터 브랜치
  • 현재 지점으로 다시 전환
  • 마스터 분기를 현재 분기로 병합

이 코드를 배치 파일 (.bat)로 저장하고 스크립트를 리포지토리의 어느 곳에 나 두십시오. 그런 다음 그것을 클릭하여 실행하면 설정됩니다.

:: This batch file pulls current master and merges into current branch

@echo off

:: Option to use the batch file outside the repo and pass the repo path as an arg
set repoPath=%1
cd %repoPath%

FOR /F "tokens=*" %%g IN ('git rev-parse --abbrev-ref HEAD') do (SET currentBranch=%%g)

echo current branch is %currentBranch%
echo switching to master
git checkout master
echo.
echo pulling origin master
git pull origin master
echo.
echo switching back to %currentBranch%
git checkout %currentBranch%
echo.
echo attemting merge master into %currentBranch%
git merge master
echo.
echo script finished successfully
PAUSE

10

정확한 '체리 픽'을 할 수 있습니다.기능 분기에 필요한 커밋 .

를 수행 git checkout hotfix1핫픽스 1 분기에 얻을. 그런 다음git log 를 해당 커밋의 SHA-1 해시 (커밋을 고유하게 식별하는 임의의 문자 및 숫자 시퀀스)를 가져옵니다. 그 (또는 처음 10 자 정도)를 복사하십시오.

그때, git checkout feature1 기능 분기로 돌아갑니다.

그때, git cherry-pick <the SHA-1 hash that you just copied>

즉 커밋 당긴 것입니다 기능 분기로 . 그 변화는 지점에있을 것입니다-당신은 단지 그것을 "체리-픽"했습니다. 그리고 나서, 당신의 마음의 내용에 대한 작업을 다시 시작하고, 편집하고, 커밋하고, 푸시하는 등의 일을하십시오.

결국, 한 브랜치에서 피처 브랜치로 (또는 그 반대로) 다른 병합을 수행하면 Git은 해당 커밋 에서 이미 병합 된 것을 인식 하고 다시 만들 필요가 없음을 알고 있습니다. "건너 뛰세요".


나는 이것을 좋은 생각으로 생각하지 않습니다. 그런 다음 IMO, 핫픽스 커밋은 실제로 기능 분기의 기록에 표시되며 기본적으로 원하지 않습니다.
Martin Pecka

1
“결국 한 지점에서 기능 지점으로 (또는 그 반대로) 다른 병합을 수행하면 git은 이미 [...]를 병합했음을 인식합니다. 실제로 작동하는 방식입니까? 나는 git merge이것이 당신이 암시하고있는 것처럼 보이는이“재생 커밋”방식에서 작동 한다고 생각하지 않습니다 (“그냥 건너 뛰십시오”). 체리 따기와 병합을 혼합하면 분명히 문제가 발생할 수 있습니다. 참조 : news.ycombinator.com/item?id=3947950
Guildenstern

0

기능 분기에 있으며 리팩토링을 수행했습니다. 이제 마스터 변경 사항을 기능 분기에 병합하고 싶습니다. 나는 훨씬 뒤에있다. 참고 기능 분기에 모듈이 한 위치에서 다른 위치로 이동했기 때문에 마스터 변경 사항을 로컬로 가져 가고 싶지 않습니다 . 풀없이 아래에서 수행하는 것이 효과가 없다는 것을 알았습니다. "이미 최신 상태입니다."라고 표시되어 있습니다.

 //below does not get the latest from remote master to my local feature branch without git pull
    git checkout master 
    git fetch 
    git checkout my-feature-branch 
    git merge master

아래에서 작동합니다 .git merge origin / master를 사용하십시오.

 git checkout master 
    git fetch 
    git checkout my-feature-branch 
    git merge origin/master
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.