본문 바로가기

Note/생활코딩 GIT

[생활코딩_GIT] 06. cherry-pick , rebase

#cherry-pic의 기본 개념

 

topic branch t2 에서 작업한 내용이 master m2에도 반영이 되었으면 좋겠다.

--> cherry-pic 은 t2 , m2를 병합하여 새로운 버전을 만들어낸다.

--> t2이 버전이 생성될 때 생긴 변화만을 저장하겠다. (rebase revert도 마찬가지)

 

 

# 상황을 통한 사용법 

- 상황 : topic branch t2 에서 작업한 내용이 master m2에도 반영이 되었으면 좋겠다.

 

1. 병합되려는 브랜치로 가서 (가져오려는 브랜치가 아님)

git checkout master

 

2. t2버전을 cherry-pic 하겠어

git cherry-pick 848cee8

 

-------------------- git-test 라는 폴더에 들어감
82109@DESKTOP-OO924JS MINGW64 ~
$ cd git-test

-------------------- cherrypick 이라는 이름의 폴더생성
82109@DESKTOP-OO924JS MINGW64 ~/git-test
$ mkdir cherrypick

-------------------- cherrypick 이라는 이름의 폴더에 들어감.
82109@DESKTOP-OO924JS MINGW64 ~/git-test
$ cd cherrypick

-------------------- git 초기화
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick
$ git init .
Initialized empty Git repository in C:/Users/82109/git-test/cherrypick/.git/

-------------------- .git 이 잘 설치되었으면 잘 된거다.
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ ls -al
total 8
drwxr-xr-x 1 82109 197609 0 Dec 23 22:31 ./
drwxr-xr-x 1 82109 197609 0 Dec 23 22:31 ../
drwxr-xr-x 1 82109 197609 0 Dec 23 22:31 .git/

-------------------- init.txt라는 파일을 생성; init.txt 를 add; 'init'이라는 메세지와함께 커밋
-------------------- ;(세미콜론)을 이용하면 여러 명령을 한줄에 할 수 있다.
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ touch init.txt; git add init.txt; git commit -m 'init'
[master (root-commit) 8caec76] init
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 init.txt

-------------------- git log 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git log --all --oneline --graph
* 8caec76 (HEAD -> master) init

-------------------- topic 이라는 이름의 branch 생성
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git branch topic

-------------------- git log 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git log --all --oneline --graph
* 8caec76 (HEAD -> master, topic) init

-------------------- m1이라는 파일 생성; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ touch m1; git add m1; git commit -m 'm1'
[master 69efef9] m1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 m1

-------------------- m2라는 파일 생성; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ touch m2; git add m2; git commit -m 'm2'
[master 20cdede] m2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 m2

-------------------- git log 확인 (커밋이 잘 저장되었다.)
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git log --all --oneline --graph
* 20cdede (HEAD -> master) m2
* 69efef9 m1
* 8caec76 (topic) init

-------------------- master --> topic 브랜치 이동
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git checkout topic
Switched to branch 'topic'

-------------------- t1이라는 파일 생성; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (topic)
$ touch t1; git add t1; git commit -m 't1'
[topic eb848d8] t1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 t1

-------------------- t2라는 파일 생성; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (topic)
$ touch t2; git add t2; git commit -m 't2'
[topic 848cee8] t2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 t2

-------------------- t3이라는 파일 생성; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (topic)
$ touch t3; git add t3; git commit -m 't3'
[topic 4083cd9] t3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 t3

-------------------- git log 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (topic)
$ git log --oneline --all --graph
* 4083cd9 (HEAD -> topic) t3
* 848cee8 t2
* eb848d8 t1
| * 20cdede (master) m2
| * 69efef9 m1
|/
* 8caec76 init

-------------------- 현재 브랜치(topic)의 파일 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (topic)
$ ls
init.txt  t1  t2  t3

-------------------- topic --> master로 branch 이동
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (topic)
$ git checkout master
Switched to branch 'master'

-------------------- 현재 브랜치(master)의 파일 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ ls
init.txt  m1  m2

-------------------- git log 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git log --oneline --all --graph
* 4083cd9 (topic) t3
* 848cee8 t2
* eb848d8 t1
| * 20cdede (HEAD -> master) m2
| * 69efef9 m1
|/
* 8caec76 init

-------------------- 상황 )) topic branch t2 에서 작업한 내용이 master m2에도 반영이 되었으면 좋겠다
-------------------- 1. 변경이 적용되려는 branch로 이동해서
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git checkout master
Already on 'master'

-------------------- git cherry-pic 원하는버전의 커밋번호
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git cherry-pick 848cee8
[master b193113] t2
 Date: Thu Dec 23 22:36:23 2021 +0900
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 t2

-------------------- 파일 확인 :: t2가 추가되었다.
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ ls
init.txt  m1  m2  t2

-------------------- git log 확인, t2를 cherry-pic한 기록이 남았다.
82109@DESKTOP-OO924JS MINGW64 ~/git-test/cherrypick (master)
$ git log --oneline --all --graph
* b193113 (HEAD -> master) t2
* 20cdede m2
* 69efef9 m1
| * 4083cd9 (topic) t3
| * 848cee8 t2
| * eb848d8 t1
|/
* 8caec76 init

 

 

 

 

# Rebase 개념

- re-base base를 바꾼겠다는 명령어이다. 아래 사진을 참조하여 좀 더설명해보자.

- rebase를 이해하기 전에는 일단 'base'의 개념을 먼저 알아야한다. 

두개의 갈래로 나뉘 브랜치의 공통인 조상을 말하는데, 위의 사진에서는, c 가 base다.

이 베이스를 다시 지정하는 것을 rebase라고 한다.

 

위 사진의 상황에서 topic barnch를 base로 지정하고 싶다면,

topic branch의 가장 마지막 t2 로 베이스를 다시 조정하면 된다.

이렇게 base를 다시 지정하겠다 하는 것이 rebase 이며, 

rebase하면 git log는 다음과 같은 선형 구조가 된다.

이때 새롭게 지정된 base는 t2가된다.

 

rebase 시, git log는 하단 사진과 같은 모양이 된다.

 

 

#실습

-------------------- git-test/rebase 폴더로 접속
82109@DESKTOP-OO924JS MINGW64 ~
$ cd git-test/rebase

-------------------- git 초기화
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase
$ git init
Initialized empty Git repository in C:/Users/82109/git-test/rebase/.git/

-------------------- .git 있나 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ ls -al
total 8
drwxr-xr-x 1 82109 197609 0 Dec 23 23:25 ./
drwxr-xr-x 1 82109 197609 0 Dec 23 23:25 ../
drwxr-xr-x 1 82109 197609 0 Dec 23 23:25 .git/

-------------------- init 파일 만들고; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ touch init; git add init; git commit -m 'init'
[master (root-commit) be091b2] init
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 init

-------------------- topic 이란 branch 생성
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ git branch topic

-------------------- 잘 생겼나 로그 확인 -> 잘생겼다.
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ git log --oneline --all --graph
* be091b2 (HEAD -> master, topic) init

-------------------- m1 파일 만들고; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ touch m1; git add m1; git commit -m 'm1'
[master 42f1a35] m1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 m1

-------------------- m2 파일 만들고; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ touch m2; git add m2; git commit -m 'm2'
[master e57a515] m2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 m2

-------------------- topic branch 로 이동
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ git checkout topic
Switched to branch 'topic'

-------------------- t1 파일 만들고; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (topic)
$ touch t1; git add t1; git commit -m 't1'
[topic 69e4205] t1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 t1

-------------------- t2 파일 만들고; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (topic)
$ touch t2; git add t2; git commit -m 't2'
[topic 18089e6] t2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 t2

-------------------- t3 파일 만들고; add; commit
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (topic)
$ touch t3; git add t3; git commit -m 't3'
[topic 6c3e97e] t3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 t3

-------------------- log 확인
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (topic)
$ git log --all --oneline --graph
* 6c3e97e (HEAD -> topic) t3
* 18089e6 t2
* 69e4205 t1
| * e57a515 (master) m2
| * 42f1a35 m1
|/
* be091b2 init

82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (topic)
$ ls
init  t1  t2  t3

82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (topic)
$ git checkout master
Switched to branch 'master'

82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ ls
init  m1  m2

-------------------- 1. 합쳐지려는 branch로 이동 (master를 topic에 합치고 싶음)
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ git checkout master
Already on 'master'

-------------------- git rebase branch이름
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ git rebase topic
Successfully rebased and updated refs/heads/master.

-------------------- 이전과 log를 비교해보면, 
-------------------- 이전의 topic의 기록은 그대로 남아있고, 
-------------------- 그 위에 master의 작업내용이 쌓였음을 알 수있다.
82109@DESKTOP-OO924JS MINGW64 ~/git-test/rebase (master)
$ git log --oneline --all --graph
* b783187 (HEAD -> master) m2
* bb388e3 m1
* 6c3e97e (topic) t3
* 18089e6 t2
* 69e4205 t1
* be091b2 init

 

 

 

 

 

rebase 전

 

rebase 후

 

# 상황을 통한 방법 소개

 

- 하려고 하는것 :  master branch 를 topic branch 로 옮기겠다.

 

1.  이동 시키려는 브랜치로 이동

git checkout master

 

2. git rebase + 베이스가 될 branch이름

git rebase topic

 

 

 

# merge  vs rebase

 

1. merge

: 위 사진의 m2 , t2 가 합쳐져서 새로운 버전이 만들어진다.

 

2. rebase

: t2의 작업 내용을 base로 그 뒤에 m1의 작업내역이 쌓이고, 그렇게 합쳐진 m1을 base로 m2가 쌓인다.

한마디로, 그냥 파일이 합쳐지는 것이 아니라, 이전 작업 내용이 달라지므로, 사용시 주의 해야한다.

 

--> 복잡한 프로젝트 아니면 잘 안쓰긴 함 / 원격저장소로 push 된 이후에는 rebase 하지 말자

--> merge의 결과와 rebase 의 결과는 같아야한다! 과정이 다를 뿐!

--> 선형으로 log를 짜고 싶을때만 해라.