Git 리베이스: 알아야 할 모든 것

게시 됨: 2022-12-15
Linux 명령 프롬프트를 보여주는 파란색 배경의 노트북.
fatmawati achmad zaenuri/Shutterstock.com
Git rebase 명령은 분기를 다른 분기의 헤드에 있는 새 위치로 이동합니다. Git 병합 명령과 달리 rebase에는 프로젝트 기록을 다시 작성하는 작업이 포함됩니다. 훌륭한 도구이지만 다른 개발자가 기반으로 작업한 커밋을 리베이스하지 마십시오.

Git rebase 명령은 두 개의 소스 코드 분기를 하나로 결합합니다. Git merge 명령도 마찬가지입니다. rebase 가 무엇을 하는지, 어떻게 사용하는지, merge 을 대신 사용하는 경우에 대해 설명합니다.

목차

힘내 폭발
힘내 병합이란 무엇입니까?
힘내 리베이스 란 무엇입니까?
다른 지점으로 리베이스하는 방법
Git 리베이스 대 병합: 어느 것을 사용해야 합니까?
리베이스하거나 리베이스하지 않습니까?

힘내 폭발

다른 버전 제어 시스템과 느린 업데이트 및 커밋에 좌절한 Linux 커널로 유명한 Linus Torvalds는 2005년에 자신의 시스템을 작성하기 위해 한 달을 비워두었습니다. 그는 그것을 Git이라고 명명했습니다.

GitHub, GitLab 및 BitBucket과 같은 사이트는 Git을 공생적으로 홍보하고 혜택을 받았습니다. 오늘날 Git은 전 세계적으로 사용되며 2022년 설문 조사에서 응답자 71,000명 중 98%가 Git를 버전 제어 시스템으로 사용했습니다.

Git의 주요 설계 결정 중 하나는 속도였습니다. 특히 지점과의 작업은 최대한 빨라야 했습니다. 분기는 버전 제어 시스템의 기본 부분입니다. 프로젝트 리포지토리에는 기본 또는 마스터 분기가 있습니다. 이것은 프로젝트의 코드 베이스가 있는 곳입니다. 새로운 기능과 같은 개발은 분리된 사이드 브랜치에서 이루어집니다. 이렇게 하면 분기에서 수행된 작업이 마스터 분기를 엉망으로 만드는 것을 중지하고 코드 기반의 다른 부분에서 동시 개발이 발생할 수 있습니다.

팀에 적합한 Git 워크플로 및 분기 모델을 선택하는 방법
관련 팀에 적합한 Git 워크플로 및 분기 모델을 선택하는 방법

사이드 브랜치의 개발이 완료되면 개발 브랜치를 마스터 브랜치로 병합하여 변경 사항을 마스터 브랜치로 이전합니다. 다른 버전 제어 시스템에서 브랜치로 작업하는 것은 어렵고 계산 비용이 많이 듭니다. Git에서 브랜치 작업은 매우 빠르고 매우 가볍습니다. 한때 지루하고 다른 시스템에서는 자주 피했던 작업이 Git에서는 사소해졌습니다.

Git rebase 명령은 한 분기에서 다른 분기로 변경 사항을 전송하는 또 다른 방법입니다. mergerebase 명령은 목적이 비슷하지만 서로 다른 방식으로 목적을 달성하고 결과가 약간 다릅니다.

힘내 병합이란 무엇입니까?

그렇다면 Git merge 명령은 무엇입니까? 새 기능을 작업하기 위해 dev-branch 라는 브랜치를 만들었다고 가정해 보겠습니다.

마스터 브랜치와 dev-branch라는 병합되지 않은 브랜치의 다이어그램
Dave McKay/How-To-Geek

몇 가지 커밋을 하고 새 기능을 테스트합니다. 모두 잘 작동합니다. 이제 새 기능을 master 브랜치로 보내려고 합니다. 다른 브랜치를 병합하려면 master 브랜치에 있어야 합니다.

병합하기 전에 명시적으로 확인하여 master 분기에 있는지 확인할 수 있습니다.

 자식 체크 아웃 마스터

이제 Git에게 dev-branchmaster 브랜치인 현재 브랜치로 병합하도록 지시할 수 있습니다.

 자식 병합 개발 지점 

dev-branch 브랜치를 마스터 브랜치로 병합

merge 이 완료되었습니다. master 브랜치를 체크 아웃하고 컴파일하면 새로 개발된 기능이 포함됩니다. Git이 실제로 수행한 것은 3방향 병합입니다. masterdev-branch 브랜치의 가장 최근 커밋과 dev-branch 가 생성되기 직전 master 브랜치의 커밋을 비교합니다. 그런 다음 master 브랜치에서 커밋을 수행합니다.

병합은 아무 것도 삭제하지 않고 Git 기록을 변경하지 않기 때문에 비파괴적인 것으로 간주됩니다. dev-branch 는 여전히 존재하며 이전 커밋은 변경되지 않습니다. 3방향 병합 결과를 캡처하는 새 커밋이 생성됩니다.

병합 후 Git 리포지토리는 대체 줄이 분기된 후 기본 타임라인으로 돌아가는 타임라인처럼 보입니다.

마스터 브랜치와 병합된 dev-branch 브랜치
Dave McKay/How-To Geek

dev-branch 분기가 master 분기에 통합되었습니다.

한 프로젝트에 많은 분기가 있는 경우 프로젝트 히스토리가 혼란스러울 수 있습니다. 이는 프로젝트에 기여자가 많은 경우에 자주 발생합니다. 개발 노력이 다양한 경로로 분할되기 때문에 개발 이력은 비선형적입니다. 브랜치에 자체 브랜치가 있으면 커밋 히스토리를 푸는 것이 훨씬 더 어려워집니다.

Git 브랜치는 어떻게 작동합니까?
관련 Git 브랜치는 어떻게 작동합니까?

master 브랜치에 커밋되지 않은 변경 사항이 있는 경우 병합하기 전에 이러한 변경 사항에 대해 작업을 수행해야 합니다. 새 분기를 만들고 거기에서 변경 사항을 커밋한 다음 병합을 수행할 수 있습니다. 그런 다음 임시 분기를 다시 마스터 분기로 병합해야 합니다.

그것은 작동하지만 Git에는 새 분기를 만들지 않고도 동일한 작업을 수행하는 명령이 있습니다. stash 명령은 커밋되지 않은 변경 사항을 저장하고 stash pop 으로 다시 호출할 수 있도록 합니다.

다음과 같이 사용합니다.

 숨기는 장소

자식 병합 개발 지점

숨김 팝

최종 결과는 저장되지 않은 변경 사항이 복원된 병합된 분기입니다.

힘내 리베이스 란 무엇입니까?

Git rebase 명령은 완전히 다른 방식으로 목표를 달성합니다. 리베이스하려는 브랜치에서 모든 커밋을 가져와서 리베이스하려는 브랜치의 끝에서 재생합니다.

이전 예를 들어 어떤 작업을 수행하기 전에 Git 리포지토리는 다음과 같습니다. dev-branch 라는 브랜치가 있고 이러한 변경 사항을 master 브랜치로 옮기고 싶습니다.

마스터 브랜치와 dev-branch라는 병합되지 않은 브랜치의 다이어그램
Dave McKay/How-To-Geek

rebase 후에는 하나의 완전히 선형적인 변경 타임라인처럼 보입니다.

dev-branch가 리베이스된 마스터 브랜치
Dave McKay/How-To Geek

dev-branch 가 제거되었고 dev-branch -branch의 커밋이 master 브랜치에 추가되었습니다. 최종 결과는 처음에 dev-branch 의 커밋이 실제로 master 브랜치에 직접 커밋된 것과 동일합니다. 커밋은 master 브랜치에 고정되는 것이 아니라 "재생"되고 새로 추가됩니다.

이것이 rebase 명령이 파괴적인 것으로 간주되는 이유입니다. 리베이스된 브랜치는 더 이상 별도의 브랜치로 존재하지 않으며 프로젝트의 Git 기록이 다시 작성되었습니다. 어떤 커밋이 원래 dev-branch 에 만들어졌는지 나중에 확인할 수 없습니다.

그러나 단순하고 선형적인 역사를 남깁니다. 수십 또는 수백 개의 분기 및 병합이 있는 리포지토리와 비교하여 Git 로그를 읽거나 그래픽 git GUI를 사용하여 리포지토리의 그래프를 보는 것과 비교하면 리베이스된 리포지토리는 이해하기 쉽습니다.

다른 지점으로 리베이스하는 방법

git rebase 예제를 사용해 봅시다. new-feature 라는 분기가 있는 프로젝트가 있습니다. 이와 같이 해당 분기를 master 분기로 rebase 합니다.

먼저 master 브랜치에 눈에 띄는 변경 사항이 없는지 확인합니다.

 자식 상태

new-feature 분기를 확인합니다.

 git checkout 새로운 기능

우리는 Git에게 현재 브랜치를 마스터 브랜치로 rebase 하도록 지시합니다.

 자식 리베이스 마스터

우리는 여전히 두 개의 분기가 있음을 알 수 있습니다.

 자식 분기

master 브랜치로 다시 교체합니다.

 자식 체크 아웃 마스터

새 기능 분기를 현재 분기로 병합합니다. 이 경우에는 master 분기입니다.

 자식 병합 새로운 기능 
새 기능이 리베이스된 마스터 브랜치
Dave McKay/How-To Geek

흥미롭게도 최종 병합 후에도 여전히 두 개의 분기가 있습니다.

Git 분기 명령을 사용하여 git 리포지토리의 분기 나열
Dave McKay/How-To Geek

차이점은 이제 new-feature 브랜치의 헤드와 master 브랜치의 헤드가 동일한 커밋을 가리키도록 설정되었으며 Git 기록에는 별도의 new-feature 브랜치가 있었다는 것이 표시되지 않습니다. 지점 레이블.

dev-branch가 리베이스된 마스터 브랜치
Dave McKay/How-To Geek

Git 리베이스 대 병합: 어느 것을 사용해야 합니까?

rebasemerge 의 경우가 아닙니다. 둘 다 강력한 명령이며 아마 둘 다 사용할 것입니다. 즉, rebase 가 제대로 작동하지 않는 사용 사례가 있습니다. merge 을 사용하여 실수로 인한 Unpicking 실수는 불쾌하지만 rebase 로 인한 unpicking 오류는 지옥입니다.

당신이 리포지토리를 사용하는 유일한 개발자라면 rebase 로 재앙적인 일을 할 가능성이 적습니다. 예를 들어 여전히 rebase 방향으로 리베이스하고 마스터 브랜치를 new-feature 브랜치로 rebase 할 수 있습니다. master 브랜치를 다시 가져오려면 이번에는 new-feature 브랜치에서 master 브랜치로 다시 rebase 해야 합니다. 이상하게 보이는 기록이 있지만 master 분기가 복원됩니다.

다른 사람이 작동할 가능성이 있는 공유 분기에서 rebase 를 사용하지 마십시오. 리베이스된 코드를 원격 저장소로 푸시할 때 저장소 변경으로 인해 많은 사람들에게 문제가 발생할 것입니다.

프로젝트에 기여자가 여러 명 있는 경우 안전한 방법은 공용 분기가 아닌 로컬 리포지토리에서만 rebase 를 사용하는 것입니다. 마찬가지로 풀 요청이 코드 검토의 일부를 구성하는 경우 rebase 를 사용하지 마십시오. 또는 적어도 풀 리퀘스트를 생성한 후 rebase 를 사용하지 마십시오. 다른 개발자가 커밋을 보고 있을 가능성이 높습니다. 즉, 변경 사항이 master 브랜치에 없더라도 퍼블릭 브랜치에 있음을 의미합니다.

위험은 이미 원격 리포지토리로 푸시된 커밋을 rebase 하고 다른 개발자가 해당 커밋에 대한 작업을 이미 수행했을 수 있다는 것입니다. 로컬 rebase 는 기존 커밋을 사라지게 합니다. 이러한 변경 사항을 저장소에 푸시하면 인기를 얻지 못할 것입니다.

Git 커밋을 수정, 편집 또는 실행 취소하는 방법(Git 기록 변경)
관련 Git 커밋을 수정, 편집 또는 실행 취소하는 방법(Git 기록 변경)

다른 기여자들은 자신의 작업을 리포지토리로 다시 푸시하기 위해 지저분한 merge 을 거쳐야 합니다. 그런 다음 변경 사항을 로컬 리포지토리로 다시 가져오면 중복된 변경 사항을 선택 해제해야 합니다.

리베이스하거나 리베이스하지 않습니까?

Rebase 는 프로젝트에서 불법일 수 있습니다. 지역적, 문화적 반대가 있을 수 있습니다. 일부 프로젝트 또는 조직에서는 rebase 를 이단의 한 형태로 간주하고 모독 행위로 간주합니다. 어떤 사람들은 Git 기록이 발생한 일에 대한 불가침의 영구적인 기록이어야 한다고 생각합니다. 따라서 rebase 는 테이블에서 벗어날 수 있습니다.

그러나 개인 브랜치에서 로컬로 사용되는 rebase 는 유용한 도구입니다.

리베이스 한 후 푸시하고 유일한 개발자인 브랜치로 제한하십시오. 또는 적어도 모든 개발이 중단되고 다른 누구도 브랜치의 커밋에서 벗어나 다른 작업을 기반으로 하지 않는 경우입니다.

그렇게 하면 문제를 피할 수 있습니다.

관련: Git 버전 확인 및 업데이트 방법