IT

리베이스 후 지점으로 밀 수 없습니다

lottoking 2020. 7. 19. 09:05
반응형

리베이스 후 지점으로 밀 수 없습니다


우리는 git을 사용하고 마스터 브랜치와 개발자 브랜치를 가지고 있습니다. 새 기능을 추가 한 다음 커밋을 마스터로 리베이스 한 다음 마스터를 CI 서버로 푸시해야합니다.

문제는 리베이스 중에 충돌이 발생하면 리베이스가 계속해서 원격 분기를 당길 때까지 원격 개발자 분기 (Github에서)를 푸시 할 수 있다는 것입니다. 이더 커밋이 발생합니다. 충돌이 예상대로 작동합니다.

질문 : rebase 및 충돌 해결 후 두 커밋을 만들지 않고 로컬 및 원격 개발자 분기를 어떻게 동기화합니까?

설정 :

// master branch is the main branch
git checkout master
git checkout -b myNewFeature

// I will work on this at work and at home
git push origin myNewFeature

// work work work on myNewFeature
// master branch has been updated and will conflict with myNewFeature
git pull --rebase origin master

// we have conflicts
// solve conflict
git rebase --continue

//repeat until rebase is complete
git push origin myNewFeature

//ERROR
error: failed to push some refs to 'git@github.com:ariklevy/dropLocker.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

// do what git says and pull
git pull origin myNewFeature

git push origin myNewFeature

// Now I have duplicate commits on the remote branch myNewFeature

편집하다

따라서 다음과 같이 들리 워크 플로가 중단됩니다.

myNewFeature 작업 개발자 1 hisNewFeature 작업 개발자 2 모두 마스터를 기본 지점으로 사용

developer2는 myNewFeature를 hisNewFeature로 병합합니다.

developer1은 리베이스하고 충돌을 해결 한 다음 myNewFeature의 원격 지점으로 강제 푸시합니다.

며칠 후 developer2는 myNewFeature를 hisNewFeature에 다시 병합합니다.

이로 인해 다른 개발자가 developer


먼저, 귀하와 함께 일하는 사람들은 주제 / 개발 지점이 공유 개발을위한 것인지 아니면 자신만의 동의해야합니다. 다른 개발자들은 언제라도 리베이스되기 때문에 개발 지점에 합병하지 않는 것을 알고 있습니다. 일반적으로 워크 플로는 다음과 유연합니다.

o-----o-----o-----o-----o-----o       master
 \
   o-----o-----o                      devel0
                \
                  o-----o-----o       devel1

그런 다음 원격으로 최신 상태를 유지하십시오. 다음을 수행하십시오.

 git fetch origin
 git checkout master
 git merge --ff origin/master

나는 두 가지 이유로 이것을한다. 첫 번째는 개발자 브랜치에서 전환 할 필요없이 원격 변경 사항이 있는지 확인할 수 있기 때문입니다. 둘째, 숨김 / 커밋되지 않은 변경 사항을 덮어 쓰지 않도록하는 안전 메커니즘입니다. 또한 마스터 브랜치로 빠르게 병합 할 수 없다면 누군가가 원격 마스터를 리베이스 (심각하게 채찍질해야 함)했거나 실수로 마스터에 전념하여 끝을 정리해야 함을 의미합니다.

그런 다음 리모컨에 변경 사항이 있고 최신 버전으로 빨리 감기면 rebase 할 것입니다.

git checkout devel0
git rebase master
git push -f origin devel0

그런 다음 다른 개발자는 내 최신 버전에서 개발 브랜치를 리베이스해야한다는 것을 알고 있습니다.

git fetch <remote>
git checkout devel1
git rebase <remote>/devel0

그 결과 훨씬 더 깨끗한 기록이 생깁니다.

o-----o                                 master
       \
         o-----o-----o                  devel0
                      \
                        o-----o-----o   devel1

당신의 변덕에 커밋을 앞뒤로 병합 하지 마십시오 . 중복 커밋을 생성하고 기록을 추적 할 수 없게 할뿐만 아니라 특정 변경에서 회귀를 찾는 것이 거의 불가능 해집니다 (이것이 처음에 버전 제어를 사용하는 이유입니다.). 당신이 겪고있는 문제는 바로 이것의 결과입니다.

또한 다른 개발자가 개발자 브랜치에 커밋하는 것처럼 들립니다. 이것을 확인할 수 있습니까?

병합 할 유일한 시간은 주제 브랜치가 master.

참고로. 여러 개발자가 동일한 저장소에 커밋하는 경우 개발자 개발 브랜치를 구분하기 위해 명명 된 브랜치를 모두 고려해야합니다. 예를 들면 :

git branch 'my-name/devel-branch'

따라서 모든 개발자 토픽 브랜치는 자체 중첩 세트 내에 있습니다.


git이 브랜치 끝에 커밋을 추가 할 것으로 예상하는 줄 아래로 커밋을 이동 했으므로 강제로 푸시해야합니다. git push -f origin myNewFeature문제를 해결할 것입니다.

팁 : 위는 강제 푸시의 합법적 인 사용입니다. 공개적으로 액세스 할 수있는 저장소에 역사를 다시 쓰지 마십시오. 그렇지 않으면 많은 사람들이 당신을 싫어할 것입니다.


여기서 명심해야 할 가장 중요한 것은 풀과 리베이스가 배후에서하는 일입니다.

풀은 기본적으로 가져 오기와 병합이라는 두 가지 작업을 수행합니다. --rebase를 포함하면 병합 대신 rebase를 수행합니다.

리베이스는 분기 이후의 모든 로컬 변경 사항을 숨기고, 분기를 대상의 최신 커밋으로 빠르게 전달하고, 변경 사항을 순서대로 해제하는 것과 거의 같습니다.

(이는 리베이스를 수행 할 때 여러 충돌 해결 프롬프트를받을 수있는 이유와 병합으로 얻을 수있는 하나의 충돌 해결을 얻을 수있는 이유를 설명합니다. 그렇지 않으면 커밋을 보존하기 위해 리베이스되는 각 커밋에 대한 충돌을 해결할 기회가 있습니다. )

이것은 기록을 다시 작성하기 때문에 리 기반 변경 사항을 원격 분기에 푸시하고 싶지 않습니다. Ofcoarse, never는 거의 항상 예외가 있기 때문에 조금 강합니다. 예를 들어 특정 환경에서 작업하기 위해 로컬 저장소의 원격 버전을 유지해야하는 경우입니다.

이렇게하려면 강제를 사용하여 때때로 리베이스 변경 사항을 푸시해야합니다.

git push -f origin newfeature

또는 경우에 따라 관리자가 강제 기능을 제거했을 수 있으므로 삭제하고 다시 만들어야합니다.

git push origin :newfeature
git push origin newfeature

두 경우 모두 다른 사람이 원격 지점에서 귀하와 협력하고있는 경우 귀하가 무엇을하고 있는지 확실히 알고 있어야합니다. 이것은 처음에 병합으로 함께 작업하고 마스터로 이동하고 작업 브랜치를 제거하기 직전에 더 관리하기 쉬운 커밋 형식으로 리베이스한다는 것을 의미합니다.

다음을 활용하여 거의 항상 git의 GC를 대체 할 수 있습니다.

git reflog

모든 rebase / conflict 관리에서 길을 잃은 경우보다 안정적인 상태로 다시 재설정 할 수 있으므로 이것은 엄청난 생명의 은인입니다.


강제 푸시를 수행해야합니다. git push -f origin myNewFeature

아, 그리고 사람들이 여러분의 개발 브랜치에 아무것도 기반하지 않도록하는 것이 좋습니다. 일반적으로 여러분은 히스토리를 전혀 다시 쓰는 브랜치를 게시해서는 안됩니다 (또는 게시 된 후에는 히스토리를 다시 작성하지 말 것). 한 가지 방법은 wip/myNewFeature다음 과 같은 브랜치 이름을 사용한 다음 wip브랜치가 수시로 마스터로 리베이스 될 것이라고 언급하는 것입니다.


이미 주어진 일반적인 대답 ( git push -f origin myNewFeature리베이스 변경을 추진할 때 사용 )은 좋은 출발점입니다. 워크 플로가 중단되는지 여부에 대한 편집 문제를 해결하기 위해이 답변을 작성하고 있습니다.

git pull --rebase ...원격 브랜치에 강제 푸시를 사용 (또는 일부 변형)을 수행 할 것이라고 가정하면 예제에서 워크 플로를 중단하는 것은 developer2에 병합 myNewFeature하는 것 hisNewFeature입니다. 다른 사람이 해당 분기에 대해 작업하지 않는 한 고유 한 기능 분기를 리베이스 할 수 있으므로 분기 영역을 구분하는 규칙이 필요합니다.

a) 병합 할 수없는 규칙을 설정 master하거나 b) develop자신의 myNewFeature브랜치 를 기반으로 하는 집합 브랜치를 생성하고 병합 할 수있는 규칙을 설정하여이 문제를 해결할 수 있습니다 develop. master그런 다음 이정표 또는 릴리스 (또는 설정하려는 경우)에만 예약 develop되며 다른 기능 분기에 통합 할 준비가되면 각 기능을 푸시 할 수 있습니다.

저는 이것이 Gitflow 워크 플로의 단순화 된 버전으로 간주 될 수 있다고 생각합니다.


나는 동의 MrCholo , 어쩌면 트레버 노리스 의 업데이트 고려할 수 있습니다 좋은 답변을 교체

git push -f origin devel0

git push --force-with-lease origin devel0

참고 URL : https://stackoverflow.com/questions/15143042/cant-push-to-branch-after-rebase

반응형