힘내, 이전 커밋 사용자 이름과 이메일을 다시 작성


170

Github의 프로젝트에 많은 커밋을 커밋했지만 커밋을 위해 현재 사용중인 컴퓨터에서 올바른 전자 메일과 커미터 전체 이름을 설정하지 않았으므로 사용자 아바타 및 전자 메일 주소를 알았습니다. 거기 없다.

과거 커밋 이메일과 사용자 이름을 어떻게 다시 쓸 수 있습니까?



내 GitHub 계정에서 이메일 주소를 변경 한 후이 문제가 발생했습니다. GitHub 데스크톱이 아닌 git 명령 줄 인터페이스를 사용하여 로컬 git repo에서 코드 변경 사항을 푸시하는 것 외에도 GitHub 웹 인터페이스를 사용하여 원격 git repo에서 직접 텍스트 및 관리 파일을 편집했습니다. 새 이메일 주소는 전자가 아닌 후자의 조치로 인해 커밋에만 전파됩니다.
Robert John

답변:


243

이 별명을 추가 할 수 있습니다.

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "

작성자 이름을 변경하려면

git change-commits GIT_AUTHOR_NAME "old name" "new name"

또는 최근 10 개의 커밋에 대한 이메일 :

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

별명:

change-commits="!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" \$@; }; f "

출처 : https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig


13
또한 git change-commits GIT_COMMITTER_EMAIL "old@example.com" "new@example.com"커미터 이메일을 변경합니다.
laurent

19
우분투에서 "eval : [[: not found" "고정 및 확인change-commits = "!f() { VAR1=$1; VAR='$'$1; OLD=$2; NEW=$3; echo \"Are you sure for replace $VAR $OLD => $NEW ?(Y/N)\";read OK;if [ \"$OK\" = 'Y' ] ; then shift 3; git filter-branch --env-filter \"if [ \\\"${VAR}\\\" = '$OLD' ]; then export $VAR1='$NEW';echo 'to $NEW'; fi\" $@; fi;}; f "
qxo

9
git : 'change-commits'는 git 명령이 아닙니다. 'git --help'를 참조하십시오. git 설정에 별칭을 추가하지 않았 음을 의미합니다. 예 : git config -e
Wayne

2
이것은 방금 변경하려는 이메일로 모든 커밋을 복제했습니다. 기록을 다시 쓰지 않는 것 같습니다. @Olivier Verdier의 솔루션이 저에게 효과적이었습니다.
제이크 윌슨

6
다른 입력으로 연속해서 두 번 수행하면 다음과 같은 결과가 발생합니다.Cannot create a new backup. A previous backup already exists in refs/original/
theonlygusti

97

해결책은 이미 있습니다 : Git에서 여러 커밋의 작성자와 커미터 이름 및 전자 메일 변경

즉,

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

4
이것은 지점의 모든 커밋 (전체 히스토리)에 대한 작성자 이름을 변경하지 않습니까?
하센

2
예, 그러면 모든 커밋이 새로운 저자 정보로 변경됩니다.
ewall

9
답변을 붙여 넣는 대신 질문을 중복으로 표시하십시오.
givanse

2
이전 이름이나 이전 이메일을 지정하지 않으면 어떻게됩니까? git는 "빈
아이덴티티

이 명령을 실행했는데 이제 리포지토리가 git 서버로 밀거나 당기지 않습니다.
예수 H

46

커밋 중 일부를 이미 공용 저장소에 푸시 한 경우,이를 수행 하지 않으려는 경우 또는 다른 사용자가 사용한 마스터 히스토리의 대체 버전을 작성합니다. "하천을 건너지 마십시오 ... 나쁠 것입니다 ..."

즉, 로컬 리포지토리에 커밋 한 경우에만 서버에 푸시하기 전에이 문제를 해결하십시오. 옵션 git filter-branch과 함께 명령을 사용할 수 있으므로 다음 --commit-filter과 같이 잘못된 정보와 일치하는 커밋 만 편집합니다.

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD

5
녹색으로 표시된 답변은 그렇지 않은 반면 완벽하게 작동합니다.
jmary

그런 다음으로 백업을 지우고 싶을 수도 있습니다 ( git update-ref -d refs/original/refs/heads/master< stackoverflow.com/a/7654880/333403 > 참조) .
cknoll

참고 : 잘못된 이름 / 이메일이 여러 개인 경우 여러 번 실행해야 할 수도 있습니다. 이 경우 다음과 같은 오류 메시지가 표시됩니다. A previous backup already exists in refs/original/이 경우 새 이메일로 다시 실행 -f하고 --commit-filter 앞에 a 를 추가하십시오 . 자신의 재량에 따라 사용하십시오. 일반적 -f으로 수행중인 작업에 대한 지식 없이는 위험한 일입니다.

19

Olivier Verdier의 답변을 적용한 후 :

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

... 원래 저장소에서 변경된 기록을 푸시하려면 다음을 사용하십시오.

git push origin +yourbranch

위의 명령 (더하기 참고)은 원래 리포지토리에 기록을 다시 쓰도록 강제합니다. 주의해서 사용하십시오!


나를 위해 일하고 또한 기원에 관한 역사를 올바르게 다시 작성했습니다.
Xeverous

10
누가 커밋했는지에 관계없이 모든 커밋을 다시 작성합니다. 주의해서 사용하십시오.
Bhavin Doshi

14

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="oldEmail@xxx-MacBook-Pro.local"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

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

이것은 완전히 나를 위해 일했습니다. git push 후 git 웹 포털에서 업데이트를 확인하십시오. 커밋이 여전히 내 계정에 연결되어 있지 않은 경우 커밋 옆에 기본 축소판 이미지가 표시되고 내 기여 일정표에 반영되지 않은 경우 커밋 URL로 이동하여 URL 끝에 .patch를 추가하고 이름을 확인하십시오. 이메일이 정확합니다.


이 이론적으로 질문에 대답 할 수 있습니다 동안, 바람직 할 것이다 여기에 대한 대답의 본질적인 부분을 포함하고 참조 할 수 있도록 링크를 제공합니다.
jhpratt

1
이것은 모든 브랜치를 다시 쓰는 유일한 사람입니다.
브루노 젤

6

쉬운 복사 붙여 넣기 버전을 원하는 경우 (이메일 및 이름 업데이트 제외) :

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f

5
-bash :! f : 이벤트를 찾을 수 없음
Saiyine

터미널이 자동으로 탈출하는 문제 일 가능성이 높습니다.
Andrei Savin

3

의 사용을 고려 git-filter-branch한다 바람직하지 에 같은 일을 할 수있는, 자식 필터 - REPO (당신이 먼저 설치해야 할 수 있습니다를 pip install git-filter-repo)

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'

저장소가 원본이 아닌 원격 인 경우 추가해야합니다. --force 강제로 다시 쓰 . (이 작업을 수행하기 전에 리포지토리의 백업을 생성 할 수 있습니다.)

심판을 유지하지 않으려면 (Git GUI의 분기 기록에 표시됩니다) 추가해야합니다 --replace-refs delete-no-add .

고급 기능에 대해서는 "이름 및 이메일 필터링"을 참조하십시오 .

PS 도난 및 https : //.com/a/59591928/714907에서 개선되었습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.