git rebase로 commit 합치기

Reading time ~5 minutes

Git을 사용하다보면 commit을 한 후에 누락된 작업이 생각이 나거나 이미 커밋한 내용 중에 수정이 필요한 경우가 종종 생기는데, 추가로 작업한 후에 다시 commit을 하면 동일한 이름의 commit 혹은 의미없는 새로운 commit이 생기게 된다. 이때, git rebase 명령을 이용하면 변경사항은 적용하면서 이전과 현재의 커밋을 합칠 수 있다. git rebase 명령 중에서도 squash(s)를 자주 이용했었는데 단순히 현재 commit의 log message를 지우고 과거의 commit으로 합치는 것이라면 fixup(f)을 이용하는 것이 더 편리하다.


git rebase

git rebase -i HEAD~N 명령을 이용하면 현재 commit으로부터 N개의 commit에 대해 commit 합침, 제거, 메세지 수정 등이 가능하다. 명령을 실행하면 다음 단계에서 N개의 commit에 대해 각각의 간략한 해시 값과 메세지를 보여주며 맨 앞에 pick, squash 등의 명령을 이용할 수 있다. pick 명령이 기본 값으로 설정되어 보여지며, Commands: 를 살펴보면 각각의 명령들에 대한 설명이 간단하게 나와있다. 이용하는 방법은 pick 자리에 원하는 명령을 입력하면 된다. (p, s, f, d 등의 약어를 사용하면 편리하다.) 아래의 예시를 통해 자세히 살펴보자.


Example

아래와 같은 commit log가 있다. second commit 이 의미없는 커밋이기 때문에 first commit으로 합치고 싶은 상황이다.

$ git log --oneline
ae53bdf second commit
004644d first commit
[...]


Squash를 이용한 rebase

최근 2개의 commit을 작업하기 위해 아래와 같은 명령을 입력한다.

$ git rebase -i HEAD~2
pick 004644d first commit
pick ae53bdf second commit

# Rebase f42adb4..ae53bdf onto f42adb4 (2 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

seconde commitfirst commit에 합치기 위해 squash 명령을 이용하여 적용한다.

pick 004644d first commit
s ae53bdf second commit

:wq으로 저장 후 종료하면,

# This is a combination of 2 commits.
# This is the 1st commit message:

first commit

# This is the commit message #2:

second commit

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Tue Mar 14 21:50:01 2017 +0900
#
# interactive rebase in progress; onto f42adb4
# Last commands done (2 commands done):
#    pick 004644d first commit
#    s ae53bdf second commit
# No commands remaining.
# You are currently editing a commit while rebasing branch 'master' on 'f42adb4'.
#
# Changes to be committed:
#   modified:   test.txt
#

vi를 통해 commit message 를 변경할 수 있다. 지우고 싶은 commit message를 #으로 주석처리 할 수 있고, 수정할 수도 있다.

$ git log --oneline
98a0a97 first commit
[...]

2개만 합칠 수 있는 것이 아니라 여러개의 commit을 squash로 지정할 수 있다. 또한 반드시 현재의 commit을 이전의 commit으로 합쳐야 하는 것이 아니라 합쳐지고 싶은 commit에 대해 squash(s) 를 지정하면 된다.


fixup을 이용한 rebase

하지만 단순히 현재 commit(second commit)을 이전 commit(first commit)으로 합치고 싶은 것이라면 fixup(f)을 이용하는 것이 편리하다.

$ git rebase -i HEAD~2

명령을 실행 한 후에

pick 004644d first commit
f ae53bdf second commit

와 같이 입력하면 이후에 특별한 작업 없이 바로 commit이 합쳐진다. 변경 사항들은 적용되면서 second commit은 사라지고 first commit 만 남는다.


이외의 기능

이 외에도 git rebase를 이용하면

  • reword(r) : 특정 commit의 message 변경
  • drop(d) : 특정 commit 제거

등의 기능도 이용할 수 있다.

Django 예제를 이용한 python import 이해하기

이전 포스트에서 질문 받았던 Django의 python import에 대해 해답을 주기 위해 공부한 내용을 정리했다.Example아래와 같은 구조의 django 프로젝트가 있고 tutorial/tutorial/urls.py 에서 tutoria...… Continue reading