git의 기록을 편집하여 잘못된 이메일 주소 / 이름을 수정하려면 어떻게해야합니까?


76

내가 자식을 사용하기 시작하면 난 그냥했다 git init및 부르기 시작 add하고 commit. 이제 관심을 가지기 시작했으며 커밋이 cowens@localmachine내가 원하는 주소가 아닌 로 표시되고 있음을 알 수 있습니다 . 설정 것처럼 나타납니다 GIT_AUTHOR_EMAILGIT_COMMITTER_EMAIL내가 원하는 것을 할 것입니다,하지만 난 여전히 잘못된 이메일 주소 / 이름을 가진 그 오래된 커밋이있다. 이전 커밋을 어떻게 수정할 수 있습니까?


4
향후 독자 git를 위해 : 이와 유사한 목적으로 사용하는 것에 대한 질문은 Stack Overflow 에서 더 잘 부탁드립니다 .
Michael Hampton

다음은 stackoverflow.com 에서 가장 가까운 질문 입니다.
naught101

답변:


82

git filter-branch에 대한 단일 호출로 돌아가서 모든 커밋을 수정할 수 있습니다. 이것은 rebase와 같은 효과가 있지만 각 커밋을 개별적으로 수정하는 대신 모든 기록을 수정하려면 하나의 명령 만 수행하면됩니다.

이 명령으로 모든 잘못된 이메일을 수정할 수 있습니다.

git filter-branch --env-filter '
    oldname="(old name)"
    oldemail="(old email)"
    newname="(new name)"
    newemail="(new email)"
    [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
    [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
    [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
    [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
    ' HEAD

더 많은 정보는 git docs 에서 얻을 수 있습니다.


11
git filter-branch --env-filter 'export GIT_AUTHOR_EMAIL = "foo@example.com"; GIT_AUTHOR_NAME = "Foo"'덕분에 훨씬 간단합니다. 변경 할 수 있으면 이것이 허용되는 답변 일 것입니다 (서버 결함에 버그가있는 것 같습니다).
Chas. Owens

7
내보내기 라인은 등호 양쪽에 공백이 없어야합니다. 즉, 다음과 같아야합니다. export GIT_AUTHOR_EMAIL = "(올바른 이메일)";
Andy Balaam

1
이제 Windows에서 어떻게해야합니까?
Carsten Schmitz

2
@Deckard : fixcommits.sh와 같은 텍스트 파일에 스크립트를 저장 한 다음 Git Bash를 실행하고 스크립트를 실행하십시오. 스크립트 파일을 레포 루트에 넣고 Git Bash의 해당 폴더로 이동 한 다음 ./fixcommits.sh를 사용하여 스크립트를 실행했습니다.
Avalanchis

2
부록 1 이 명령 형식은 저에게는 효과가 없었지만 다음과 같은 경우 :if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi
Josh M.

28

Git의 filter-branch 명령은 강력하지만 수정해야 할 작성자가 두 명 이상인 경우와 같이 사소한 것이 아닌 경우에는 사용하기가 끔찍합니다.

다음은 git-shortlog 맨 페이지에 설명 된 .mailmap 기능을 사용하는 유용한 대안입니다. 이것은 git log의 형식화 기능과 함께 사용할 수있는 작성자 매핑 메커니즘을 제공합니다. 이름 지정된 커밋 시퀀스를 선택하고 수정하는 명령을 생성하는 데 사용할 수 있습니다.

예를 들어, $ START 커밋에서 시작하여 브랜치 $ BRANCH의 저작권을 수정한다고 가정합니다.

기존 작성자 이름을 올바른 저자 이름으로 맵핑하는 저장소의 최상위 디렉토리에 .mailmap 파일을 작성해야합니다. 다음을 사용하여 기존 작성자 이름 목록을 얻을 수 있습니다.

git shortlog -se

다음과 같은 .mailmap 파일로 끝나야합니다 (예 :).

You <you@somewhere.org>   cowens@localmachine
You <you@somewhere.org>   root@localmachine

이제 git log의 형식화 기능을 사용하여 $ BRANCH를 $ BRANCH2로 다시 쓰는 명령을 생성 할 수 있습니다.

git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh - 

첫 번째 명령은 커밋 $ START에서 새 빈 분기 싹을 만듭니다. $ START와 $ BRANCH 사이의 각 커밋에 대해 두 번째 명령 cherry는 현재 분기 $ BRANCH2의 끝에서 원래 커밋을 선택하고 작성자를 올바르게 설정하도록 수정합니다.

이것은 또한 일반적으로 적용 가능합니다-~ / .gitconfig에 넣으십시오.

[alias]
    # git reauthor $START..$END
    reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H &&  git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '

따라서 작성자를 수정해야하는 경우 이제 .mapfile을 생성하고 다음을 수행해야합니다.

git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH

원래 브랜치 참조를 새 브랜치로 재 할당하고 새 브랜치 참조를 삭제할 수 있습니다.

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2

대단해. 더 많은 담당자가 있다면 현상금을 줄 것입니다. 감사합니다 :)
pistache

9

에서 답을 결합 내가 먼저 자식에 커밋에 대한 메타 정보를 수정하려면 어떻게합니까?

### Fix the first commit ###    
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue    
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root

올바른 길로 안내했지만 --author 사용법 대신 stackoverflow.com/a/28536828/307의 명령이 필요했습니다
Brett Veenstra

5

jedberg의 답변을 따르려면 : rebase -i해당 커밋을 사용 하고 편집하도록 선택할 수 있습니다 . 당신이 사용하는 경우 git commit --amend --author <AUTHOR DETAILS>다음 git rebase continue당신은 통과하고 역사를 해결할 수 있습니다.

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