Skip to content

Instantly share code, notes, and snippets.

@fomuon
Last active October 25, 2021 08:46
Show Gist options
  • Save fomuon/511129b5ab9f0a7fa4fca083c0685f13 to your computer and use it in GitHub Desktop.
Save fomuon/511129b5ab9f0a7fa4fca083c0685f13 to your computer and use it in GitHub Desktop.

git rebase 활용 방법

git rebase --help git-rebase - Reapply commits on top of another base tip

1. commit log 의 중요성

commit log 를 잘 작성하는 것은 협업 또는 본인 스스로 가독성 높은 코드를 작성하기 위한 많은 방법들 중 하나.

2. 원자적 커밋 (Atomic Commits with Git)

하나의 커밋에는 더이상 분리 할 수 없는 최소한의 코드 변경만 포함한다.

atomic commit 예

메세지를 통해 무엇 을 수정했는지 파악이 가능

* Create HTML for form
* Style form
* Add HTML5 validation
* Fix unrelated JS bug
* Add ajax submit to form with mock server results from PHP
* Add JS validation to form
* Send form results via email
* Log form results to database
* Style form validation and success/error messages
  • 원자적 커밋이 좋은 이유

    • 코드리뷰가 쉬워진다.
    • 롤백이 쉬워진다.
    • 명확한 히스토리가 된다. (시간이 많이 지난 후에도 작업 내용 파악 용이)
    • cherry pick 의 활용 여지가 커진다.
  • 자주 쓰는 메세지

    • Polish or Polishing
      • 컴파일된 코드에 변경이 없는 수정인 경우 (인덴트 수정, 주석 수정, 포멧팅 등)
    • Upgrade to XXX
      • dependency 의 버전업을 한 경우
    • Fix typo
      • 변수명등 오탈자 수정한 경우

3. rebase 로 내 브랜치에 master 최신 코드 가져오기

※ (rebase 를 알기 전에 알아야 할 amend commit)

HEAD commit 에 변경 사항을 합친다.
$git commit --amend

1) 아래 상태에서 topic 브랜치에 master 의 F, G 를 반영 하는 방법

      A---B---C topic
     /
D---E---F---G master

2) 기존방법 : (topic 브랜치에서) git merge master

      A---B---C---G' topic
     /           /
D---E---F-------G master
  • git graph가 복잡해짐.
  • 충돌이 발생한 경우 merge commit 에는 충돌 해결 commit 이 들어가게 되고 이 log 는 히스토리를 복잡하게 만듦.

3) rebase 방법 : git rebase master idea : rebase.. => (interactive 체크해제 및 onto 에 base branch 지정)

              A'--B'--C' topic
             /
D---E---F---G master
  • git graph 매우 심플
  • commit log 상에 불필요한 충돌 해결 commit 이 없음
  • fast-forward merge (git merge --ff feature1) 를 통해 불필요한 merge commit 을 없앨 수 있음.

(참고)topic 을 master 에 fast-forward 로 merge 한 모습 (또한 github 에서 PR 을 rebase merge 할 경우 이와 같이 됨)

D---E---F---G---A'--B'--C' topic, master

4. 내 브랜치 history 중간에 commit 추가, 수정, 삭제, 순서바꾸기, 합치기 (git rebase interactive)

  • 작업이 완료된 후에라도 원자적 커밋 원칙을 준수하기 위해 각 커밋을 다시 고칠 수 있다.
  • 하나의 작업 브랜치에서 같은 코드 블럭이 두개의 commit 에 포함되지 않도록 고칠 수 있다.
    • 작업 히스토리 파악 용이
    • rebase merge 할때 충돌을 최소화 할 수 있다.
      A---B---C topic
     /
D---E master

1) topic branch 전체 commit 고치기

command : git rebase -i master

idea : rebase.. => (interactive 체크 및 onto 에 base branch 지정)

2) topic branch 최근 2개 commit 고치기

command : git rebase -i HEAD~2

idea : Show VCS Log => (로그중 원하는 commit 에서 context menu ) => Interactively Rebase from hear
      A---B---C topic, origin/topic
     /
D---E master

rebase interacive 이후 아래와 같이 변함

      A---B---C origin/topic
     /
D---E master
    \
     A'---B'---C' topic

force push 를 통해 origin 을 날리고 local branch 로 갱신한다

git push -f origin topic

(force push 주의점)

  • 내 작업 브랜치에서만 수행한다.
  • 공동 작업 브랜치인 경우 각 멤버의 local 에 추가 수정이 없는지 확인해야 함.

공동작업 브랜치에서 rebase & force push 를 수행한 이후 다른 멤버들은 local branch 를 reset 하여 remote 로 갱신해야 한다

git reset --hard origin/topic

3) 자주 사용하는 interactive mode 의 commit apply 명령

  • pick : 이 커밋을 적용한다.
  • reward : 이 커밋을 메세지를 수정하고 적용한다.
  • edit : 이 커밋에서 멈추어 원하는 수정을 한 뒤에 적용한다.
  • squash : 이 커밋을 이전 커밋과 합친뒤 적용한다.
  • drop or skip : 이 커밋을 버린다.
  • (기타는 문서 확인)

5. cherry pick 활용하기

cherry pick 은 다른 브랜치의 특정 commit 만 내 브랜치로 가져오는 기능.

(상황1)

  • 내가 개발 작업을 하던 중 버그를 발견 하였고, 이 버그는 핫픽스로 바로 배포 되어야 한다면 어떻게 처리하는게 가장 좋을까?
      A---B---C(bug fix)---D topic
     /
D---E master

bug fix 인 C 커밋만 master 에서 cherry pick 한 후 배포 한다.

      A---B---C(bug fix)---D topic
     /
D---E---C'(bug_fix) master

topic rebase onto master 시 C 커밋은 skip 한다.

          A---B---D topic
         /
D---E---C'(bug_fix) master

(상황2)

  • 다른 사람이 이미 구현했지만 배포일정 관계로 아직 머지 하지 않은 기능을 머지하기 전까지 내 브랜치에 추가해서 사용하고 싶다면 어떻게 하는게 가장 좋을까?
      A---B---D topic1
     /
D---E---F master
         \
          G---H---B'(cherry pick)---I topic2
  1. topic1의 B 커밋에 구현된 기능을 topic2 에서 사용하고 싶은 경우 B 커밋을 cherry pick 한다.
  2. topic1 이 머지된 이후 rebase 를 통해 B' 커밋은 skip 한다.
      A---B---D topic1
     /         \
D---E-----------D' master
                 \
                  G---H---I topic2

6. commit log 관점에서 리펙토링시 주의 사항

레거시 메서드를 다른 클래스로 이동하거나 파일을 이동하거나 이름을 변경하는 것은 히스토리 파악을 어렵게 만들기 때문에 주의해야한다.

리펙토링에서 기존코드 를 개선하는 것이 어려운 경우 기존코드에 deprecated 마크와 함께 새 기능을 추가 하는 방향으로 하는 것이 좋다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment