github에는 커밋을 하게 되면 아래와 같이 잔디가 심어지는데,
며칠 전 내 github에 들어가보니 이 때까지 커밋했던게 제대로 반영이 되어 있지 않았다.
무슨 일인가 확인해보니 내 계정이 아니고 다른 계정을 만들어놨던게 Author로 등록이 되어서 하나도 반영이 되지 않았던 것이다. 그래서 구글링을 해서 복구하긴 했지만 나랑 완벽하게 똑같은 사례가 없어서 이것 저것 찾아보느라 힘들었기 때문에 기록 겸 다음에 같은 실수가 일어났을 때 찾아보려고 포스팅을 한다.
아래의 Error(잘못된 커밋)의 예와 같이 의도치 않은 작성자가 입력되어 변경하고 싶다.
이미 Git 원격저장소로 push까지 한 상태이기 때문에 reset
이나rebase
를 통하여 변경할 수 있다.
만약 push를 하지 않고 로컬 저장소에만 있는 상태라면 git commit --amend
명령어를 사용하면 직전 커밋을 수정할 수도 있다.
또한, push를 했더라도 직전 커밋만 수정하면 된다면 git reset HEAD^1
으로 HEAD를 돌린 이후에 git push origin + branch
이름으로 강제 push를 해주면 된다.
나같은 경우 예시에서는 마지막 한 개의 커밋만 저렇게 되었지만 실제로는 이 때까지 한 전체 commit의 Author를 변경해야 했기 때문에 rebase
를 사용해야 했다.
rebase 명령어를 사용해야 되는 경우는,
먼저 커밋을 변경하려면 변경할 커밋의 hash값 또는 변경할 커밋의 hash값을 알아야한다.
hash 값은 github에 들어가서 커밋 히스토리에서 hash 값을 찾아봐도 되고,
더 편한 방법은 터미널에서 git log 명령어를 사용하면 된다.
또는 짧게 hash 값만 확인하고 싶다면, git log --oneline 명령어를 사용하면 된다.
이젠 hash 값을 알아냈으니 본격적으로 rebase 명령어를 사용해보자.
현재 변경하고 싶은 commit 의 hash 값이 e81c643이다.
git rebase -i {변경할 커밋의 해시값}^
git rebase -i {변경할 커밋의 이전 커밋의 해시값}
git rebase -i e81c643
여기서 -i 는 (--interactive), 대화형 모드로 rebase를 실행하는 것이다.
또 나처럼 처음부터 모든 commit을 변경해야 된다면 git rebase -i --root
명령어를 사용하면 된다.
위의 rebase 명령어를 실행하면 따로 설정을 하지 않았다면 vi 에디터가 열린다.
초기 상태는 pick {hash 값} {커밋 메시지} 로 적혀있을텐데 변경할 커밋을 찾은 뒤, pick 을 edit 또는 e 로 변경해준다.
edit e81c643 Error (잘못된 커밋), Author 변경하기 예시
# Rebase b5f5663..e81c643 onto b5f5663 (1 command)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# . create a merge commit using the original merge commit's
# . message (or the oneline, if no original merge commit was
# . specified). Use -c <commit> to reword the commit message.
#
# 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
수정 한 뒤에 esc를 누르고, :wq 명령어를 통해서 저장하고 나가면 된다.
$ git rebase -i e81c643^
Stopped at e81c643... Error (잘못된 커밋), Author 변경하기 예시
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
저장하고 나오면 위와 같이 rebase 진행모드를 시작한다.
$ git commit --amend --author="작성자명 <email주소>"
# 또는 git commit --amend까지 입력하면 vi 에디터에서 직접 수정할 수 있다.
$ git commit --amend
Error (잘못된 커밋), Author 변경하기 예시
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Author: Choi HyungWook <qpflapffhs76@naver.com>
# Date: Thu Aug 12 13:51:19 2021 +0900
#
# interactive rebase in progress; onto b5f5663
# Last command done (1 command done):
# edit e81c643 Error (잘못된 커밋), Author 변경하기 예시
# No commands remaining.
# You are currently editing a commit while rebasing branch 'main' on 'b5f5663'.
#
# Changes to be committed:
# new file: src/error.js
또한, 여기서 commit message도 수정하고 쉽다면 --amend 뒤에 -m "수정할 message" 를 입력해주면 된다.
최종적으로 명령어를 입력하면 수정사항이 반영된다.
$ git commit --amend --author="CTD <qpflapffhs76@gmail.com>"
[detached HEAD 1cd1106] error (잘못된 커밋), Author 변경하기 예시
1 file changed, 1 insertion(+)
이제 수정을 마쳤으니 rebase 작업을 종료하면 된다.
$ git rebase --continue
여기서, edit으로 변경했던 커밋이 1개가 아니라면 다음 커밋으로 넘어가게 되고 3번의 과정을 다시 반복해주면 된다.
$ git rebase --continue
Successfully rebased and updated refs/heads/master.
이제 로컬 저장소에는 커밋이 반영되었고 원격 저장소로 push만 하면 된다.
다만, rebase 작업 이후에는 --force 옵션을 사용하여 강제로 진행해야 한다.
$ git push -f origin +브랜치이름
정상적으로 변경되었음을 알 수 있다.
https://docs.github.com/en/get-started/using-git/using-git-rebase-on-the-command-line
github 공식 문서에도 잘 정리되어 있으니 참고해도 좋을듯 하다.
근데 여기서, commit이 1분 전이라고 되어있는데 COMMITTER_DATE값이 수정시간으로 변경되었기 때문이다.
이를 해결해주려면 git filter-branch를 사용하여 AUTHOR_DATE로 덮어 씌워야 한다.
git filter-branch --env-filter \
'if [ "$GIT_AUTHOR_DATE" != "$GIT_COMMITTER_DATE" ]
then
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
fi'
만약 하나의 커밋만 수정하고 싶다면, 아래 명령어를 입력하면 된다.
git filter-branch --env-filter \
'if [ $GIT_COMMIT = 커밋해시값 ]
then
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
fi'
또는 커밋의 날짜를 직접 변경하고 싶다면, 아래 명령어를 입력한다.
git filter-branch --env-filter \
'if [ $GIT_COMMIT = 커밋해시값 ]
then
export GIT_AUTHOR_DATE=2020-12-01T18:30:00+0900
export GIT_COMMITTER_DATE=2020-12-01T18:30:00+0900
fi'
이후 원격저장소에 push 해주면 된다.
여기서 git filter-branch로 날짜를 변경할 수 있다면 author도 변경할 수 있는게 아닌가? 해서 찾아봤는데 이 방법도 있다.
다만, 꽤나 위험한 방법이고 기존 커밋의 hash가 모두 바뀌므로 개인 프로젝트가 아닌 협업하는 프로젝트에서는 협의 없이 절대로 해서는 안 되는 방법이라고 한다.
#!/bin/sh
git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
해당 블로그를 참고했다.
https://docs.github.com/en/get-started/using-git
github 공식문서에서도 filter-branch 예제가 잘 나와있다.
Enroll in people right dreamlike entire world that will emanates leeway wherever every single subsequent number until eventually your time and efforts can be way up throughout Goa Escorts. Be ready to try out different things brimming with enjoyment along with lust!