git push 된 커밋 사용자 name, email 변경

# 현재 저장소 ./git/config 에 user(name, email) 을 설정하지 않은 상태에서
# 전역 ~/.gitconfig 에 설정된 회사 user(name, email) 로
# 오랫 동안 commit , push 하고 있었다.
# github 에선 등록되지 않은 email 로 contribution 카운트가 누락된다.
# 이미 push 된 커밋들의 author(user name, email)를 변경할 수 있다.
# 참고 https://www.git-tower.com/learn/git/faq/change-author-name-email

#####

# [첫번째 방법]
# 잘못된 author 로 커밋이 일어나기 전의 커밋으로 rebase 한다.
# 잘못된 커밋 해시 이후 부터 head 까지의 커밋들을 수정할 수 있다.
# -i, --interactive 사용자가 rebase 하기전에 수정할 수 있도록 한다.
# --preserve-merge 를 옵션을 사용하지 않으면 하나의 브랜치 커밋들로 변경된다.
git rebase -i --preserve-merge 잘못된_커밋_이전_커밋_해시

# 최초 커밋부터 잘못되었다면
git rebase -i --root

# 이제 rebase 커밋 이후의 모든 커밋들이 vim 에디터로 보인다.
# 위쪽 부터가 오랜된 커밋이다.
# github 커밋 기록을 보면서 잘못된 커밋은 pick -> edit 또는 e 로 변경해 저정한다.
# 참고로 s 로 하나의 커밋을 합칠 경우 맨처음(맨위) 커밋은 pick, 그 뒤 합칠 커밋들은 s 로 변경해 저장하면 커밋 메시지들이 하나로 모인다. 여기서 메시지를 편집해서 저장한다.


# 이제 터미널에서 커밋마다 author 만 수정한다.
# 참고로 --abort 로 rebase 취소할 수 있다.
git commit --amend --author="ysoftman <ysoftman@gmail.com>" --no-edit

# rebase 계속 진행(다음 커밋으로 이동)
git rebase --continue

# 위 두과정을 커밋이 없을때까지 반복한다.
# 더이상 진행할 커밋이 없으면 다음과 같은 메시지 나온다.
Successfully rebased and updated refs/heads/master.

# master, develop, feature 등 로컬의 브랜치 마다 강제 push 한다
git push -f

# 혹시 로컬에 rebase 전 상태로 clone 받은 곳이 있고, 여기서 git pull 하면
# 이곳에선 rebase 수정전 커밋들이 그대로 남아있고 수정한 커밋들이 추가되는 형상이 된다.
# 여기서 push 하면 다시 수정한 커밋들이 푸시되니 이런 clone 은 삭제하자.

#####

# [두번째 방법]
# 우선 git pull 받아 최신 상태로 업데이트한다.
https://git-scm.com/docs/git-filter-branch
# 다음 스크립트를 이용해 한번에 변경할 수 도 있다.(완전 편함~ㅋ)
git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="ysoftman"
NEW_EMAIL="ysoftman@gmail.com"
if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$NEW_NAME"
    export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$NEW_NAME"
    export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

# pull 표시가 나더라도 pull 없이 강제 push 한다.
# master, develop, feature, tag 등 로컬의 브랜치들을 강제 push 한다.
git push origin master -f
git push origin develop -f
git push --tags -f

# git filter-branch 를 실행해서 다음과 백업이 있어 실행하지 못한다면
# git filter-branch 뒤에 -f 로 강제(백업 덮어쓰기)할 수 있다.
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f

# 로컬에 refs/original/refs/... 참조가 보이면 삭제한다.
# 업데이트할 참조가 많다면 새로 clone 받는것이 편할 수 있다.
git update-ref -d refs/original/refs/heads/master
git update-ref -d refs/original/refs/heads/develop

#####

# 실제 커밋(contribute) 수 보다 적게 표시되는 상황


# author 수정 후 정상 카운트 되는 contributions


#####

# rebase 이전의 커밋들이 보일 수 있다.
# 이를 표시하지 않으려면 해당 release 혹윽 태그를 삭제해야 한다.
git tag -d ysoftman-release-1
git tag -d ysoftman-hotfix-1

#####

# 참고로 여러 커밋을 합치는 경우 위 vim 커밋 수정화면에서
# 방법1
# 합칠 커밋들을 s 또는 squash 로 변경해 저장한다.
# s 로 표시한 커밋과 s 바로 이전 커밋이 vim 편집 화면이 열리고 커밋 메시지를 수정하고 저장하면 s -> s 이전 커밋으로 합쳐진다.
# 방법2
# 합칠 커밋들을 f 또는 fixup 로 변경해 저장한다.
# f 로 표시한 커밋 메시지는 vim 편집 화면 없이 삭제되며 f -> f 이전 커밋으로 합쳐진다.

comments:

댓글 쓰기