깃의 로그를 관리할때 사용된다.
로그의 순서가 아래와 같다고 할때
생성된 로그를 삭제, 수정, 압축등의 작업을 하고 싶을때 rebase
를 이용한다
로그정리
- git rebase -i HEAD~"헤더에서부터 vi 에디터로 가져갈 로그의 수"
git rebase -i HEAD~3
를 입력하면 vi editor
가 실행된다.
현재 HEAD
는 로그인 완료이므로 로그인 완료부터 이전 로그 3개를 vi editor
로 가지고 간다
vi editor
에는 다양한 명령어가 있다
로그의 앞부분을 주석의 명령어로 바꾸면 다양한 기능을 수행할 수 있다.
내용을 변경하려면 vi editor
에서 i
를 눌러 insert
모드로 변경후 입력하면 된다
로그를 삭제하고 싶다면 해당 로그의 명령어를 d
로 바꾼다
esc
를 누른 다음 :wq
를 입력하고 엔터를 치면 로그가 삭제된다
다시 로그를 조회하면 삭제가 된걸 볼 수 있다.
하지만 중간 커밋의 데이터도 날아가니 주의해야 한다.
복구를 하고 싶다면 reflog
를 이용한다.
깃 복구하기
- git reflog
git reflog
를 입력하면 지금까지의 작업을 수행한 로그들을 모두 조회할 수 있다.
rebase
를 하기 전 로그로 돌아가고 싶다면 reset
을 이용한다
git reset --hard 193c
( 로그인 완료 )리셋후 다시 조회를 하면 로그가 복구된걸 확인할 수 있다.
다시 rebase로 vi editor를 열고 이번에는 로그명을 변경해보자
git rebase -i head~3
입력변경하고 싶은 로그의 명령어를 r
로 변경후 esc
+ :wq
를 누르면 로그명을 수정할 수 있는 창으로 이동된다.
i
를 눌러 insert 모드에서 로그명을 변경하고 esc
+ :wq
를 누르면 완료가 된다.
다시 로그를 조회하면 로그명이 변경 될걸 확인 할 수 있다.
( 로그인 만들다가 퇴근 -> 로그인 집에서 만들자 )
여러개의 로그가 있을때 지금 HEAD
에서 원하는 로그를 Pick
해서 Squash
하는 개념이다.
git rebase -i head~3
입력 후 vi editor로 가서 i
누르고 원하는 로그의 명령어는 pick
으로 유지하고 압축할 로그는 s
로 변경한다
esc
+ :wq
로 나가면 로그이름을 변경할 수 있는 창이 뜬다.
로그인 완료만 남기고 다른로그는 삭제후 남은 로그는 변경하고 싶으면 변경후 esc
+ :wq
나가서 조회를 하면
squash
가 되어서 압축된 로그를 확인할 수 있다.
( 로그인~~~ 3개의 로그 -> 로그인 )
작업중에 원격브랜치에서 다른 동료가 작업을 커밋할 경우 개발자는 본인의 커밋을 푸쉬할 수 없다.
이때는 형상을 맞추기 위해서 rebase를 이용할 수 있다.
먼저 원격 저장소의 형상을 다운받는다.
git fetch origin
다운받고 나서 rebase로 로컬 저장소에 합친다.
git rebase origin/[로컬 브랜치명]
이때 충돌이 발생하면 잘 정리한 후에 rebase가 완료된다.
이후 원격 저장소에 푸쉬하면 충돌이 발생하지 않는다.
rebase를 이용한 스쿼시는 약간 복잡한데, squash merge
를 이용하면 쉽게 병합을 할 수 있다.
master 브랜치 에서 작업을 하다가 topic 브랜치를 만들었다고 하자.
topic 브랜치에서 추가 작업을 진행 후 커밋을 했는데 커밋로그가 난잡하게 됐을 경우 그대로 master에 올리면 난잡한 커밋이 올라가게 되므로 rebase를 이용해서 squash를 할텐데 이 경우 조금 번거로울수가 있다.
이럴때 squash merge
를 이용하면 간단하게 master로 병합을 할 수 있다.
- master 브랜치로 이동 -> 스쿼지 머지 -> 커밋
git checkout master
git merge --squash "가져올 브랜치"
git commit -m "스쿼시할 커밋 이름"
git checkout master
git merge --squash topic 까지 입력하면 커밋이 안된상태로 머지가 되는데 이때 커밋을 다시 하면 된다.
$ git fetch origin 또는 upstream
$ git rebase origin/[가져올 브랜치]
$ git add .
$ git rebase --continue
$ git fetch upstream dev
$ git rebase upstream/dev
CONFLICT (content): Merge conflict in build.gradle
error: could not apply 1b3fb2e... login 완료
$ git add .
$ git rebase --continue
$ git rebase --abort
마지막에 vi 에디터 들어가짐
수정 내용 없으면 esc
+ :wq
입력해서 나감
로그가 적용되었는지 확인
rebase 된 브랜치 push
--force-with-lease
-> 안전하게 강제 푸쉬
$ git push origin feature-branch --force-with-lease
위 작업은 아래 커맨드와 같습니다.
체크아웃을 하지 않아도 master브랜치에 topic브랜치를 rebase하라는 의미입니다.
$ git rebase master topic
위 과정을 한번에 수행합니다.
현재 브랜치에서 작업 중 원격 브랜치에 동료가 새로운 작업 내용을 커밋한 경우
원격 브랜치의 커밋 내용을 현재 브랜치로 받아온 뒤 현재 브랜치 작업을 가장 위로 올려 커밋을 합니다.
즉, fetch와 rebase를 한번에 수행합니다.
이 커맨드는 지정된 커밋 범위를 새로운 기점으로 옮깁니다.
A---B---C feature-branch
\
D---E master
$ git checkout feature-branch
$ git rebase --onto master B
B 커밋 이후의 커밋들을 master 브랜치로 옮겨라 라는 의미입니다.
$ git reset --soft HEAD^
입력후 다시 --amend
로 커밋을 하면 된다.
깃 커밋 로그에서 특정 포인트 혹은 다른 브랜치의 특정 포인트의 커밋을 현재 작업 브랜치로 가져오고 싶다면
git cherry-pick
커맨드를 이용한다.
먼저 가지고 오고 싶은 브랜치의 커밋 ID를 확인
git log --oneline
그리고 적용시킬 브랜치로 이동한 후 아래 커맨드를 입력
git cherry-pick [가져올 ID]