여러모로 오탈자를 자주 내는 입장이라 commit message를 잘못 작성하는 경우도 많은 편인데
이를 조용히 수정하는 방법에 대해서 메모장처럼 기록해둔다.
(🚨 혼자 작업하는 경우에는 유용하지만 협업 때는 이용하지 말 것!!! 로그가 꼬여서 절대 권장하지 않는다)
커밋 메세지 수정하기
(1) 변경할 commit message 위치 확인을 위해 log 명령어를 사용한다.
$ git log --oneline # 한줄 옵션을 통해 제목만 빠르게 보자
예를 들어 내가 수정하고 싶은 커밋이 "[2][docs] 링크 연결" 이라고 가정한다.
해당 커밋의 번호는 7425e65, 커밋의 위치는 HEAD~4 이다.
(HEAD는 현재 위치와 같으며, HEAD->main 표시가 되어 있는 위치가 HEAD~1이다.
7425e65의 위치는 HEAD로 부터 3 떨어져 있으므로 HEAD~4라는 계산이 나온다.)
(2) rebase 명령어를 통해 뒤(과거)로 돌아감과 동시에 정보를 가져온다.
rebase는 브랜치의 변경 사항을 다른 베이스 커밋 위로 이동시키는 데 주로 사용되는 명령어다.
$ git rebase 돌아갈위치 -i
해당 명령어 입력 시, VScode 터미널을 이용하고 있는 경우는 아래와 같이 git-rebase-todo 파일이 자동으로 열람된다.
git-rebase-todo 파일을 통해 커밋을 조작할 수 있다.
파일을 살펴보면 상단에는 pick 이란 글자와 함께 HEAD~4, 3, 2, 1에 해당되는 커밋이 나열되어 있다.
(3) 메세지를 변경할 커밋의 앞 글자 pick을 reword로 변경한다.
pick은 기본값으로 커밋을 있는 그대로 적용하고,
reword는 해당 커밋의 메세지를 수정. 커밋의 내용은 변경되지 않고 오로지 메세지 자체만 변경한다.
커밋 메세지를 단순 변경하는 의도라면 pick을 reword로 변경 후 git-rebase-todo 파일을 저장. 창을 종료한다.
그러면 다음과 같이 바로 COMMIT_EDITMSG 파일이 자동 열람된다.
해당 파일의 1번째 줄에는 기존 커밋 메세지가 보여질텐데 이를 원하는대로 변경한 뒤 저장하고 창을 종료하면 된다.
이후 git history를 열람해보면 아래와 같이 HEAD~4의 커밋 메세지는 변화했음을 볼 수 있다.
그리고 동시에 HEAD~4, 3, 2, 1 의 커밋 번호가 이전과 전부 변화했음을 알 수 있는데 이를 기억해두자.
(4) 변경 사항을 원격에 강제로 적용한다.
$ git push -f origin 브랜치명 # 이전 커밋을 덮어쓰기 위해서는 강제로 전송해야 한다
해당 명령어를 입력한 후 원격 저장소를 확인해보자.
HEAD~4의 커밋 메세지가 잘 변경된 것을 확인했다.
여기까지 커밋 메세지 변경하기라는 목표는 무사히 달성한 것이 된다.
그런데 아쉬운 점이 하나 있다.
보면 HEAD~4, 3, 2, 1이 rebase를 완료한 시점으로 전부 최신화됐다.
rebase 명령어의 의미를 다시 짚어보자면 "브랜치의 변경 사항을 다른 베이스 커밋 위로 이동시켜준다"
즉, 중간 커밋을 변경했으니 이것이 최신화 된 것이고, 그 앞 시점에 해당되는 커밋들은 그대로 두면 꼬일테니 함께 최신화된 것이다.
이 내용을 예상할 수 있었던 부분이 앞서 커밋의 번호가 전부 새롭게 변경됐다는 사실이다.
다만 이건 아무리 생각해도 조금 아쉽다.
전지적 잔디심는🌱 입장에서 말하자면 5/31에 예쁘게 한 커밋이 사라진 것이기 때문. 로그가 의도치 않게 변경된 것이 아쉽다.
그렇게 나는 커밋 시간을 변경하는 방법을 이어서 알아보게 됐다.
커밋 시간 변경하기
(1) rebase 명령어를 통해 뒤(과거)로 돌아감과 동시에 정보를 가져온다.
기본적으로 앞서 한 동작과 동일하다. HEAD~4 로 돌아가본다.
$ git rebase 돌아갈위치 -i
(2) 시간을 변경할 커밋의 앞 글자 pick을 edit으로 변경한다.
앞서 pick, reword의 역할을 설명했는데 edit을 추가로 소개한다.
edit는 해당 커밋에서 일시 중지하고 사용자가 커밋을 수정하거나 새로운 커밋을 추가하는 등의 커밋 내용 자체를 변경한다.
단순하게 커밋 메세지만 수정하는 reword보다는 역할이 조금 더 확대 된 명령어라고 볼 수 있다.
시간을 변경할 커밋의 앞 글자를 모두 edit 또는 e로 변경한다.
이후 전과 같이 git-rebase-todo 파일을 저장하고 창을 종료하면 아래와 같은 터미널 내용이 출력된다.
이제부터 edit하는 커밋들 중에서 가장 오래된 시점부터 방문한다고 이해하면 된다.
현재 멈춰져있는 시점은 HEAD~4인 f0d9f60 이다.
해당 커밋을 수정하길 원하는 경우 git commit --amend 명령을,
커밋에 더 이상 수정할 내용이 없다면 git rebase --continue 명령을 실행해 다음 시점으로 이동하면 된다.
(3) amend를 통해 변경할 시간을 설정한다.
$ GIT_COMMITTER_DATE=변경할시간 git commit --amend --date 변경할시간
# 날짜 입력 예시
$ GIT_COMMITTER_DATE="May 31 11:15:53 2024 +0900" git commit --amend --date "May 31 11:15:53 2024 +0900"
git commit --amend 를 실행하면 앞서 reword를 할 때 뜬 것처럼 커밋을 수정할 수 있는 창이 열람되는데, 지금은 해당 과정을 거치지 않고 위 명령어를 통해 수정까지 한 번에 수행한다.
이건 나름의 이유가 있는데 git에서는 커밋의 시간 정보를 두 가지로 저장한다.
author date: 커밋의 작성 시간 (변경 사항이 작성된 시간). --date 옵션으로 변경함
committer date: 커밋이 실제로 저장된 시간. GIT_COMMITTER_DATE 환경 변수를 통해 변경함
git commit --amend 를 통해 COMMIT_EDITMSG 창을 띄워서 아래 date를 변경하면 이는 author date를 변경하는 것이다.
committer date는 변경되지 않는다.
그리고 이렇게 author date만 변경해서 push하면 github에서는 변경된 날짜가 온전히 적용되지 않는다는 문제가 있다.
이 때문에 author date와 committer date를 모두 바꿔줘야 해 위 명령어를 수행한다.
참고로 위 명령어 수행 후 자동으로 열람되는 COMMIT_EDITMSG 파일은 더 수정하지 않고 바로 종료해도 된다.
(3) 수정이 끝나면 --continue한다. 모든 edit commit에 대해 수정 사항 변경을 진행한다.
$ git rebase --continue # 다음 수정이 필요한 커밋으로 시점을 이동한다
모든 커밋을 continue하고 나면 Successfully rebased를 알리는 문구가 출력된다.
참고로 예시를 위해 나는 HEAD~3, 2, 1에 해당되는 커밋도 아래와 같이 6/4에서 6/1로 변경해주었다.
(4) 변경 사항을 원격에 강제로 적용한다.
$ git push -f origin 브랜치명 # 이전 커밋을 덮어쓰기 위해서는 강제로 전송해야 한다
이번에도 해당 명령어를 입력한 후 원격 저장소를 확인해보자
HEAD~4, 3, 2, 1 모두의 날짜가 잘 변경됐다.
명령어 요약
단순 커밋 메세지 변경
$ git rebase -i HEAD~3 # 변경할 커밋으로 이동
# pick -> reword
# 커밋 메세지 수정
$ git push -f # 원격 저장소 반영
커밋 시간 변경
$ git rebase -i HEAD~3 # 변경 할 커밋으로 이동
# pick -> edit
# 각 커밋의 시간 변경
$ GIT_COMMITTER_DATE="Jan 31 01:28:06 2024 +0900" git commit --amend --date "Jan 31 01:28:06 2024 +0900"
$ git rebase --continue # 다음 커밋으로 이동
$ git push -f # 원격 저장소 반영
'DEV' 카테고리의 다른 글
[GitHub][terminal] 비밀번호 인증 에러를 토큰으로 해결하고 로그인 하기 (1) | 2023.09.08 |
---|---|
VScode를 이용해서 백준 JavaScript(node.js) 풀이 연습하기 (0) | 2023.06.11 |
[terminal][vscode] MAC에서 code 명령어 사용하기 (0) | 2023.05.16 |
[GIT] git reflog를 이용하여 git reset한 내용 원복하기 (0) | 2023.05.06 |
[Tool] diff2html | 코드 변경 내용 파일로 전달하기 (0) | 2023.04.22 |