Git 브랜치를 마스터로 병합하는 가장 좋고 안전한 방법은 무엇입니까?


2102

에서 새로운 지점 master이 생성됩니다 test.

master다른 브랜치를 만들거나 다른 브랜치를 만들거나 나중에 병합 하는 여러 개발자가 있습니다 master.

작업에 test며칠이 걸리고 test내부 커밋 으로 지속적으로 업데이트 하고 싶다고 가정 해 봅시다 master.

내가 할 것이라고 git pull origin master에서 test.

질문 1 : 이것이 올바른 접근입니까? 다른 개발자는 내가 btw와 같은 파일을 쉽게 작업 할 수있었습니다.


작업 test이 완료되었으며에 다시 병합 할 준비가되었습니다 master. 내가 생각할 수있는 두 가지 방법은 다음과 같습니다.

ㅏ:

git checkout test
git pull origin master
git push origin test
git checkout master
git pull origin test 

비:

git checkout test
git pull origin master
git checkout master
git merge test

--rebase이해 하지 못 하기 때문에 rebase는 변경 사항을 가져 와서 그 master위에 쌓을 수 있으므로 다른 사람들이 변경 한 내용을 덮어 쓸 수 있기 때문에 사용하지 않습니다 .

질문 2 : 이 두 가지 방법 중 어느 것이 옳습니까? 차이점은 무엇입니까?

이 모든 것의 목표는 내 test지점을 최신 상태로 업데이트 master하고 나중에 master타임 라인을 최대한 선형으로 유지하기 위해 다시 병합 할 수 있도록하는 것입니다.


18
rebase는 절대 덮어 쓰지 않고 단지 더 깔끔한 기록을 달성하려고합니다. 주인의 말기에 역사를 다시
붙이

7
rebase는 커밋을 덮어 쓰지 않습니다. 커밋을 취소하고 마스터 브랜치의 커밋을 테스트 브랜치에 적용한 다음 커밋을 다시 테스트에 적용합니다.
zundi

답변:


2992

내가 어떻게 할까

git checkout master
git pull origin master
git merge test
git push origin master

원격 지점의 로컬 지점이 있으면 다른 지점을 원격 지점과 병합하는 것이 불편합니다. 또한 푸시하려는 내용이 마음에들 때까지 변경 사항을 푸시하지 않으며 또한 나와 내 로컬 저장소에만 해당하는 사항을 전혀 푸시하지 않습니다. 당신의 설명에서 그것은 test당신만을위한 것입니까? 따라서 게시 할 이유가 없습니다.

git은 항상 당신과 다른 사람들의 변화를 존중하려고 노력합니다 --rebase. 나는 그것을 적절하게 설명 할 수 없다고 생각 하므로 Git 책-Rebasing 또는 git-ready : 약간의 설명을 위해 rebasing소개하십시오 . 아주 멋진 기능입니다


2
git merge test나에게 준다 fatal: 'test' does not point to a commit. git log테스트 브랜치에서 커밋 지점 을 찾아서 마스터 브랜치로 다시 전환 한 다음 수행해야 git merge 0f37d3154abbf52a4cbbbb5109f08af6a7567234합니다.
Duncanmoo

17
@Duncanmoo 글쎄, 물론 지점 test이 존재해야합니다. 커밋 해시를 대신 사용할 수 있지만 일반적으로 브랜치 이름을 사용하는 것이 더 쉽습니다. 내부적 HEAD으로는 지점 의 해시를 검색합니다 .
KingCrunch

44
@shanyangqu 리모컨에서 최신 변경 사항을 가져옵니다. 혼자 작업하고 하나의 시스템으로 만 작업해도 아무런 문제가 없습니다. 그러나 다른 시스템 (아마도 다른 개발자의 시스템)에서 변경 사항이 적용되면 병합을 되돌리려 고하면 (4 단계) 충돌이 발생합니다. 이제 유일한 해결책은 로컬 마스터를 원격 마스터에 병합하는 것입니다.이 마스터는 꽤 못생긴 "원본 / 마스터로 병합 된 마스터"병합 커밋으로 끝납니다. 따라서 합병하기 전에 항상 노력하는 것이 좋습니다.
KingCrunch

7
"당신의 설명에서, 그 테스트는 당신만을위한 것 같습니다. 그래서 그것을 출판 할 이유가 없습니다." 예를 들어, 해당 서버가 로컬 드라이브 장애에 대한 백업을 제공하거나 백업을 수행 할 다른 방법이없는 경우 로컬 분기를 서버로 푸시 할 수 있습니다.
Eric

5
"... 또한 내가 푸시하려는 것에 만족할 때까지 변경 사항을 푸시 하지 않겠다 ..." 죽었다?
Rich Stone

400

이것은 매우 실용적인 질문이지만 위의 모든 답변이 실용적이지는 않습니다.

처럼

git checkout master
git pull origin master
git merge test
git push origin master

이 방법에는 두 가지 문제있습니다 .

  1. 테스트 브랜치와 마스터 브랜치간에 충돌이 있는지 여부를 알 수 없기 때문에 안전하지 않습니다.

  2. 마스터에서 모든 테스트 커밋을 하나의 병합 커밋으로 "압착"합니다. 즉, 마스터 브랜치에서 테스트 브랜치의 모든 변경 로그를 볼 수는 없습니다.

따라서 충돌이 있다고 생각되면 다음과 같은 git 작업을 수행 할 수 있습니다.

git checkout test
git pull 
git checkout master
git pull
git merge --no-ff --no-commit test

merge전에 테스트 commit하고 다음으로 빨리 커밋을 피하십시오 --no-ff.

충돌이 발생하면 충돌에 git status대한 세부 정보를 확인하고 해결을 시도 할 수 있습니다.

git status

우리가 갈등을 해결하거나 갈등이 없다면, 우리 commitpush그들

git commit -m 'merge test branch'
git push

그러나이 방법으로 테스트 브랜치에 기록 된 변경 히스토리를 잃게되므로 다른 개발자가 프로젝트 히스토리를 이해하기 어려운 마스터 브랜치를 만들게됩니다.

따라서 가장 좋은 방법은 rebase대신에 사용해야 합니다 merge(이 시점에서 지점 충돌을 해결했다고 가정하십시오).

다음은 고급 작업을위한 간단한 샘플입니다. http://git-scm.com/book/en/v2/Git-Branching-Rebasing

git checkout master
git pull
git checkout test
git pull
git rebase -i master
git checkout master
git merge test

그러나, 당신이 상위를 완료하면 모든 테스트 브랜치의 커밋이 마스터 브랜치의 헤드로 이동됩니다. 리베이스의 주요 이점은 선형적이고 훨씬 깨끗한 프로젝트 기록을 얻는 것입니다.

피해야 할 것은 rebase마스터 브랜치와 같은 퍼블릭 브랜치에서 절대 사용하지 않는 것 입니다.

다음과 같은 작업을 수행하지 마십시오 .

git checkout master
git rebase -i test

https://www.atlassian.com/git/tutorials/merging-vs-rebasing/the-golden-rule-of-rebasing에 대한 세부 사항

부록:


4
나중에 마스터로 병합하기 위해 테스트 브랜치를 리베이스하는 것이 좋습니다. 다른 답변도 정확합니다. 이것은 버전 관리 시스템의 목적인 "라이너와 훨씬 더 깨끗한 프로젝트를 얻습니다"라고 언급 한 것처럼 마스터의 헤드에서 브랜치 테스트의 변경 기록을 유지합니다.
le0diaz

16
"하나의 안전 방법은 아니며 테스트 브랜치와 마스터 브랜치간에 충돌이 있는지 알 수없는 원인"이라는 말은 사실이 아닙니다. 항상 병합을 중단 할 수 있습니다. 충돌이없는 경우에도 푸시하지 않는 한 항상 마지막 로컬 커밋을 취소 할 수 있습니다. 자식에 대한 정확한 이해가 없다면 어떤 것이 약간 무섭거나 불분명 해 보일 수 있지만 "안전하지 않은"은 어떤 식 으로든 부정확합니다. 다른 사람과 잘못된 정보를 혼동하지 않도록주의하십시오.
Paul van Leeuwen

4
@PaulvanLeeuwen에 동의 하면 테스트 브랜치를 마스터에 병합 하면 충돌에 대한 알림과 변경 사항을 단계별로 병합 할 수 있습니다. 완료되면 병합을 커밋하고 뒤로 밀게됩니다. 후회하거나 올바르게 병합 할 수없는 경우 항상 작업을 버리고 마스터에서 다시 가져올 수 있습니다. 따라서 안전하지 않습니다 ..
Juan

3
왜 rebase -i?
MushyPeas 2016 년

8
리베이스는 기본적으로 병합보다 안전하지 않습니다. rebasing을보다 안전한 병합 옵션으로 제안하는 것은 잘못되었습니다. 리베이스는 유효한 전략이지만, 사용자가주의해야 할 경고가 더 많이 있습니다.
Ikke

90

리베이스 나 합병으로 인해 누군가의 변경 사항을 덮어 쓰면 안됩니다 (충돌을 해결할 때 선택하지 않는 한).

개발하는 동안 일반적인 접근 방식은

git checkout master
git pull
git checkout test
git log master.. # if you're curious
git merge origin/test # to update your local test from the fetch in the pull earlier

마스터로 다시 병합 할 준비가되면

git checkout master
git log ..test # if you're curious
git merge test
git push

당신이 합병에서 무언가를 깨뜨리는 것에 대해 걱정한다면, 당신을 git merge --abort위한 것입니다.

병합 수단으로 푸시 앤 풀을 사용하는 것은 어리석은 일입니다. 또한 왜 테스트를 원점으로 진행하는지 잘 모르겠습니다.


1
이 프로세스는 분기 사이를 전환 할 때마다 분기를 커밋해야하는 커밋 수를 증가시킵니다.
iBug

2
뭐? 분기를 전환 할 때마다 커밋 수가 증가한다고 말하고 있습니까? 아니면 지점을 전환 할 때마다 "지점을 커밋"해야합니까? 첫 번째는 사실이 아니며 두 번째 의미가 무엇인지 잘 모르겠습니다.
raylu

체크 아웃하기 전에 지점을 커밋해야합니다. 이것이 내가 말하는 것입니다
iBug

11
당신은하지 않습니다 : 그것은 (사물 중 하나) git stash입니다.
msanford

1
또는 마지막 커밋 (로컬 지점에서)을 수정하고 푸시하기 전에 완벽한 커밋으로 만들 수 있습니다.
whihathac

42

먼저 병합 할 지점을 최대한 깨끗하게 만듭니다. 테스트를 실행하고 원하는 상태인지 확인하십시오. git squash로 새로운 커밋을 정리하십시오 .

KingCrunches 답변 외에도 사용하는 것이 좋습니다.

git checkout master
git pull origin master
git merge --squash test
git commit
git push origin master

다른 브랜치에서 많은 커밋을 만들었을 수 있습니다. 마스터 브랜치는 한 번의 커밋이어야합니다. 커밋 히스토리를 가능한 한 깨끗하게 유지하기 위해 테스트 브랜치의 모든 커밋을 마스터 브랜치에서 하나의 커밋으로 스쿼시하고 싶을 수도 있습니다 ( Git : 스쿼시 또는 스쿼시? ). 그런 다음 커밋 메시지를 매우 표현적인 것으로 다시 작성할 수도 있습니다. 코드를 파지 않고 읽고 이해하기 쉬운 것.

편집 : 당신은에 관심이있을 수 있습니다

따라서 GitHub에서 기능 분기에 대해 다음을 수행합니다 mybranch.

원산지에서 최신을 얻으십시오

$ git checkout master
$ git pull origin master

병합 기본 해시를 찾으십시오.

$ git merge-base mybranch master
c193ea5e11f5699ae1f58b5b7029d1097395196f

$ git checkout mybranch
$ git rebase -i c193ea5e11f5699ae1f58b5b7029d1097395196f

이제 첫 번째 만 확인 pick하고 나머지는 s다음과 같습니다.

pick 00f1e76 Add first draft of the Pflichtenheft
s d1c84b6 Update to two class problem
s 7486cd8 Explain steps better

다음으로 매우 좋은 커밋 메시지를 선택하고 GitHub로 푸시하십시오. 그런 다음 풀 요청을하십시오.

풀 요청을 병합 한 후 로컬로 삭제할 수 있습니다.

$ git branch -d mybranch

그리고 GitHub에서

$ git push origin :mybranch

" 마스터 브랜치에서 오직 하나의 커밋이어야한다 " 것은 아니다. 당신은 wekk 역사를 유지하고 싶을 수도 있습니다
Cocowalla

확실한. 그러나 단순히 커밋을 스쿼시하지 마십시오
Martin Thoma

제 생각에 첫 부모가 최선의 해결책 인 것 같습니다. davidchudzicki.com/posts/first-parent
bkribbs

7

오래된 실이지만, 나는 그것을하는 방법 을 찾지 못했습니다 . rebase로 작업하고 마스터의 (기능) 브랜치에서 모든 커밋을 병합하려는 사람에게 유용 할 수 있습니다. 도중에 충돌이있는 경우 모든 커밋마다 충돌을 해결할 수 있습니다. 프로세스 중에는 모든 권한을 유지하며 언제든지 중단 할 수 있습니다.

마스터 및 지점을 최신 상태로 유지하십시오.

git checkout master
git pull --rebase origin master
git checkout <branch_name>
git pull --rebase origin <branch_name>

마스터 위에 지점 병합 :

git checkout <branch_name>
git rebase master

선택 사항 : 리베이스 중에 충돌이 발생하는 경우 :

먼저 파일 충돌을 해결하십시오. 그때:

git add .
git rebase --continue

당신의 리베이스 지점을 밀어 :

git push origin <branch_name>

이제 두 가지 옵션이 있습니다.

  • A) PR을 생성하고 (예 : GitHub에서) UI를 통해 병합합니다.
  • B) 커맨드 라인으로 돌아가서 브랜치를 마스터로 병합하십시오.
git checkout master
git merge --no-ff <branch_name>
git push origin master

끝난.


6

이것은 팀과 함께 일할 때 사용하는 워크 플로입니다. 시나리오는 설명한대로입니다. 먼저, 작업을 test마치면 test지점 에서 작업하는 동안 마스터에 추가 된 내용을 가져 오기 위해 master와 rebase합니다 .

git pull -r upstream master

test분기 를 분기 한 후 변경 사항을 마스터로 가져 와서 적용한 다음 현재 변경 사항을 "마스터"상태로 테스트하기 위해 변경 한 내용을 적용합니다. 다른 사람들이 테스트에서 편집 한 것과 동일한 파일을 변경 한 경우 여기에 충돌이있을 수 있습니다. 있으면 수동으로 수정하고 커밋해야합니다. 그렇게 한 후에는 마스터 브랜치로 전환하여 test문제없이 통합하는 것이 좋습니다 .


3
git checkout master
git pull origin master
# Merge branch test into master
git merge test

병합 후 파일이 변경되면 병합 할 때 "충돌 해결"오류가 발생합니다.

따라서 모든 충돌을 해결 한 다음 모든 변경 사항을 다시 커밋 한 다음

git push origin master

테스트 브랜치에서 누가 변경을했는지 알고 있기 때문에 누가 테스트 브랜치에서 변경을 수행했는지가 더 좋습니다.


3

rebase 방법을 사용합니다. 대부분 사건이 의미 론적으로 완벽하게 반영되기 때문입니다. 당신이하고 싶은 것은 현재 브랜치의 상태를 갱신하고 마치 최신을 기반으로하는 것처럼 "가장"하는 것입니다.

따라서 체크 아웃하지 않아도 master:

git fetch origin
git rebase -i origin/master
# ...solve possible conflicts here

물론 원점에서 가져 오는 것만 master으로 병합 의 로컬 상태가 새로 고쳐 지지는 않지만 시간을 절약하기 위해 전환 목적을 피하고 싶습니다.


2

@KingCrunch의 답변은 많은 경우에 효과가 있습니다. 발생할 수있는 한 가지 문제는 테스트에서 최신을 가져와야하는 다른 컴퓨터에있을 수 있다는 것입니다. 먼저 테스트를하는 것이 좋습니다. 개정판은 다음과 같습니다.

git checkout test
git pull
git checkout master
git pull origin master
git merge test
git push origin master

0

잡아 당기는 것은 마스터로 병합하는 것을 의미하고 병합하려면 작업 트리가 필요하기 때문에 분기를 당겨서 가져와야합니다.

git checkout master
git pull

먼저 확인할 필요가 없습니다. rebase는 두 가지 주장으로 옳은 일을한다

git rebase master test  

git checkout master
git merge test

기본적으로 git push는 여기와 원격에 존재하는 모든 분기를 푸시합니다

git push
git checkout test

0

제목에 "Best way"라고 표시되어 있으므로 인내 병합 전략 을 고려하는 것이 좋습니다 .

보낸 사람 : https://git-scm.com/docs/merge-strategies

이 옵션을 사용하면 '병합 재귀'는 중요하지 않은 일치하는 줄 (예 : 개별 함수의 중괄호)로 인해 때때로 발생하는 혼동을 피하기 위해 약간의 추가 시간을 소비합니다. 병합 할 브랜치가 심하게 분기 된 경우이 옵션을 사용하십시오. git-diff [1] --patience도 참조하십시오.

용법:

git fetch
git merge -s recursive -X patience origin/master

힘내 별칭

나는 항상 이것에 대한 별칭을 사용합니다 (예 : 한 번 실행).

 git config --global alias.pmerge 'merge -s recursive -X patience'

이제 당신은 할 수 있습니다 :

git fetch
git pmerge origin/master

0

이것은 GitLab에서 온 것입니다. 지침을 따르십시오.

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


0

개발 및 기능 분기별로 답변하겠습니다.

기능 분기에 있고 아래 명령을 사용하여 develop으로 업데이트 해야하는 경우 : git checkout develop git pull git checkout feature / xyz git merge develop

이제 기능이 개발로 업데이트되어 변경 사항을 적용 할 수 있습니다.

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