리베이스와 푸시 된 커밋을 리베이스하는 것은 무엇을 의미합니까?


109

이미 푸시 한 커밋을 리베이스해서는 안된다고 종종 말합니다. 그게 무슨 의미일까요?

답변:


80

ProGit 책은좋은 설명을 .

질문에 대한 구체적인 답변은 " 리베이스의 위험 "섹션에서 찾을 수 있습니다 . 해당 섹션의 인용문 :

리베이스 할 때 기존 커밋을 버리고 비슷하지만 다른 커밋을 새로 만듭니다. 커밋을 어딘가에 푸시하고 다른 사람들이 커밋을 풀다운하고 기본 작업을 수행 한 다음 해당 커밋을 git rebase로 다시 작성하고 다시 밀어 올리면 공동 작업자가 작업을 다시 병합해야하며 시도 할 때 작업이 지저분해질 것입니다. 그들의 작업을 당신의 것으로 되돌립니다.

업데이트 :
아래 의견에 따르면 Git 워크 플로에 문제가있는 것 같습니다. 다음은 도움이 될 수있는 몇 가지 참고 자료입니다.


설명 해주셔서 감사합니다. 따라서 이해를 더 명확하게하기 위해 특정 변경 사항을 푸시 한 후에는 git rebase(--interactive?)를 사용 하여 해당 기록을 다시 작성해서는 안되며 이는 확실한 실패의 비결입니다. 다른 개발자가 주제 브랜치를 변경 한 후 다시 리베이스하는 것이 완벽하게 정상입니다. 본질적으로 나는 merge꽤 오랫동안 사용해 왔지만 우리는 darwinweb.net/articles/86 과 같은 배를 타고 있으며 역사는 거의 사용할 수 없습니다.
Hemant Kumar

@Hemant : 공개 저장소로 푸시 한 후 커밋을 리베이스하는 것은 일반적으로 나쁜 생각입니다. 즉, 당신이 인용 한 darwinweb 기사의 조언은 당신의 워크 플로우가 그들의 것과 비슷하다면 합리적으로 들립니다. 도움이 될 수있는 다른 참조 목록은 업데이트 된 응답을 참조하십시오.
Tim Henigan

하는 "개인 관리 팀"에 대해 "ProGit"페이지에 대한 링크를 업데이트하시기 바랍니다 git-scm.com/book/en/...
Eimantas

따라서 기술적으로 git 커밋은 동일하게 유지되지만 "기존 커밋을 포기하고 유사하지만 다른 새 커밋을 생성"하는 것은 sha1 ID가 다른 동일한 커밋입니까? 이것이 내가 왜 공동 작업자들이 자신의 작업을 다시 병합해야하는지에 대해 생각할 수있는 유일한 방법 일 것입니다!
Ciasto piekarz

@Ciastopiekarz, 업스트림 저장소에서 기록을 다시 작성하고 있고 다른 개발자의 로컬 저장소에 이에 대한 포인터가있을 수 있기 때문입니다. 이제 포인터가 오래되었습니다. git 클라이언트는 이전 포인터를 사용하고 나머지를 정렬하기 위해 사람에게 의존하는 것 외에는 대안이 없습니다. 이것은 재 병합이며, 수동으로 분류해야하는 많은 혼란스러운 변경으로 인해 매우 지저분해질 수 있습니다! 따라서 이미 업스트림 리포지토리로 푸시 된 항목을 리베이스하지 않는 것이 좋습니다. 이것은 좋은 조언이며 당신이 깊은 지식을 가진 전문가가 아니라면 무시해서는 안됩니다.
Forbin 2011

240

이것을 이해하려면 git의 작동 방식에 대해 조금 이해해야합니다. git 저장소는 트리의 노드가 커밋되는 트리 구조입니다. 다음은 매우 간단한 저장소의 예입니다. 포크 할 때

마스터 브랜치에 4 개의 커밋이 있고 각 커밋에는 ID (이 경우 a, b, c 및 d)가 있습니다. d가 현재 마스터 브랜치의 최신 커밋 (또는 HEAD)임을 알 수 있습니다. 여기에 이미지 설명 입력

여기에는 master와 my-branch의 두 가지 분기가 있습니다. master와 my-branch는 모두 커밋 a와 b를 포함하지만 분기하기 시작하는 것을 볼 수 있습니다. master에는 c와 d가 포함되고 my-branch에는 e와 f가 포함됩니다. b는 master와 비교하여 my-branch의 "병합 기반"또는 더 일반적으로 "기본"이라고합니다. 의미가 있습니다. my-branch가 이전 버전의 master를 기반으로한다는 것을 알 수 있습니다.

따라서 my-branch가 오래되어 최신 버전의 master로 업데이트하려고한다고 가정 해 보겠습니다. 다시 말해서 my-branch는 c와 d를 포함해야합니다. 병합을 수행 할 수 있지만 이로 인해 분기에 풀 요청 검토를 훨씬 더 어렵게 만드는 이상한 병합 커밋이 포함됩니다. 대신 리베이스를 수행 할 수 있습니다.

여기에 이미지 설명 입력

리베이스 할 때 git은 브랜치의베이스 (이 경우 b)를 찾고 해당베이스와 HEAD (이 경우 e와 f) 사이의 모든 커밋을 찾은 다음 브랜치의 HEAD에서 해당 커밋을 재생합니다. 당신은 (이 경우 마스터) 리베이스하고 있습니다. Git은 실제로 master 위에 변경 사항이 어떻게 보이는지 나타내는 새로운 커밋을 생성합니다. 다이어그램에서 이러한 커밋은 e '및 f'라고합니다. Git은 이전 커밋을 지우지 않습니다. e와 f는 그대로 유지되며 리베이스에 문제가 발생하면 예전 방식으로 바로 돌아갈 수 있습니다.

많은 다른 사람들이 프로젝트에서 시뮬레이션 작업을하는 경우 풀 요청이 빠르게 부실해질 수 있습니다. "부실한"풀 요청은 더 이상 주요 개발 라인에서 최신 상태가 아니며 프로젝트에 병합하기 전에 업데이트해야합니다. pull 요청이 부실한 가장 일반적인 이유는 충돌 때문입니다. 두 개의 pull 요청이 모두 동일한 파일에서 유사한 줄을 수정하고 하나의 pull 요청이 병합되면 병합되지 않은 pull 요청에 충돌이 발생합니다. 때로는 풀 요청이 충돌없이 부실 할 수 있습니다. 코드베이스의 다른 파일을 변경하려면 새 아키텍처를 준수하기 위해 풀 요청에 상응하는 변경이 필요하거나 실수로 실패한 단위 테스트를 마스터 브랜치. 이유에 관계없이


68

리베이스는 기록을 다시 작성합니다. 그 역사에 대해 아무도 모른다면 그것은 완벽하게 괜찮습니다. 그러나 그 기록이 공개적으로 알려진 경우 Git에서 기록을 다시 작성하면 실제 세계에서와 똑같이 작동합니다. 음모가 필요합니다.

음모는 정말 함께 유지하기 어렵 기 때문에 처음에 공개 지점을 리베이스하지 않는 것이 좋습니다.

가 있습니다 있습니다 : 성공적인 음모의 예 puJunio C. 하마노의 자식 저장소의 브랜치 (망할 놈의 SCM의 공식 저장소) 자주으로 업데이트되어가. 이것이 작동하는 방식은 사용하는 거의 모든 사람들 pu이 Git 개발자 메일 링리스트에도 가입되어 있다는 것입니다. 그리고 pu브랜치가 리베이스 된다는 사실 은 메일 링리스트와 Git 웹 사이트에 널리 공개됩니다.


4
+1. pugit.git 브랜치는 (공개) 워크 플로에서 rebase를 사용하는 방법에 대한 매우 유용한 예 라고 생각합니다 . 익숙하지 않은 사람들을 위해 일반적인 아이디어는 커밋이없는 토픽 브랜치 next(마스터로 병합하기 직전의 불안정한 브랜치 )를 리베이스 한 다음 pu로 재설정하고 next모든 토픽 브랜치를 병합 하여 브랜치 를 다시 빌드하는 것 입니다. (출처 : 문서 / 하우투 / 유지 - git.txt git.kernel.org/?p=git/git.git;a=blob;f=Documentation/howto/... )
Cascabel

25
+1 "Git에서 기록을 다시 작성하는 것은 실제 세계에서와 똑같이 작동합니다 : 음모가 필요합니다"
Sleeper Smith

"pu는 위에서 설명한 것처럼 일회용 지점이므로 공개 발표가 필요하지 않습니다." git-scm.com/docs/gitworkflows 우리는 직장에서 비슷한 일을합니다. "TEMP-something-latest"는 최신 변경 사항의 조합 인 폐기 브랜치이며 여러 기능 브랜치의 병합 일 수 있으며 삭제 될 수 있습니다. 어느 시점에서든 재생성되며 개발해서는 안됩니다.
pilkch

6

리베이스는 저장소의 기록을 변경합니다. 커밋을 다른 사람이 사용할 수 있도록 세상에 푸시 한 다음 커밋 기록에 대한보기를 변경하면 이전 기록을 가진 사람과 함께 작업하기가 어려워집니다.

유해한 것으로 간주되는 Rebase 는 좋은 개요라고 생각합니다.

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