[입 개발]GIT: 여러 개의 commit 하나로 합치기

솔직하게 말하자면, 저는 Git을 잘 사용하지 못합니다. 그냥 아주 간단한 수준에서
1] branch 생성
2] branch merge
3] git pull
4] git push

여기다가 github을 이용해서 pull request 보내는 정도가 저의 전부입니다.

그런데, 가끔식 보면, git을 이용해서 pull request를 보내면 여기에 수정해야할 때가 생깁니다.
이럴 경우 해당 branch에 그냥 계속 commit 하면 자동으로 pull request에 commit이 쌓이게 됩니다.

커미터가, 이런것에 신경을 안쓰고 그냥 커밋할 경우에는 전혀 문제가 없지만(부끄러운 기록이 다 남게 됩니다)
자신이 이 일련의 패치들을 하나로 묶어서 보내고 싶을 때, 또는 커미터가 이거 하나로 묶어주세요 라고 요구할때가
생깁니다. 전 그럴때는 -_- 지금까지 새로운 브랜치를 만들어서 해당 패치들을 옮겨서 하나로 만들어서 제출했습니다.
(아 부끄러워요.)

git 의 기능중에 rebase 라는게 있습니다. 저도 자세히는 잘 모릅니다. 저는 제가 딱 필요한 만큼만 공부를 해둬서 쿨럭…
이 git rebase 를 이용하면 여러 개의 커밋을 하나로 합칠 수 가 있습니다.

아래와 같은 명령으로 4개의 commit 정보를 볼 수 있습니다.

git rebase -i HEAD~4

$ git rebase -i HEAD~4

pick 01d1124 Adding license
pick 6340aaa Moving license into its own file
pick ebfd367 Jekyll has become self-aware.
pick 30e0ccb Changed the tagline in the binary, too.

# Rebase 60709da..30e0ccb onto 60709da
#
# Commands:
#  p, pick = use commit
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

여기서 pick 이라고 되어 있는 부분을 다음과 같이 squash 바꿔주면 하나의 커밋으로 변경할 수 있습니다.

pick 01d1124 Adding license
squash 6340aaa Moving license into its own file
squash ebfd367 Jekyll has become self-aware.
squash 30e0ccb Changed the tagline in the binary, too.

그럼 이제 하나의 커밋이 되었는데 이것을 자신의 브랜치로 push 하면 다음과 같은 오류가 발생합니다.

charsyam@ubuntu:~/projects/redis-resync/src$ git push origin unexpected_resync
Username for 'https://github.com': charsyam
Password for 'https://charsyam@github.com': 
To https://github.com/charsyam/redis.git
 ! [rejected]        unexpected_resync -> unexpected_resync (non-fast-forward)
error: failed to push some refs to 'https://github.com/charsyam/redis.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

현재 git의 history 정보를 잃어버리게 되기 때문에 reject 를 한다는 것인데, 제가 원하는 것은
이걸 강제로 push 시키는 겁니다. 이 때 브랜치명에 ‘+’를 포함해주면 강제로 push가 되게 됩니다.

[souce language=’c’]
charsyam@ubuntu:~/projects/redis-resync/src$ git push origin +unexpected_resync
Username for ‘https://github.com’: charsyam
Password for ‘https://charsyam@github.com’:
To https://github.com/charsyam/redis.git
+ 2d3ecb5…19d8783 unexpected_resync -> unexpected_resync (forced update)
[/source]

이렇게 하면 pull request에도 이것이 하나로 합쳐져서 보여지게 됩니다.