저자를 변경하기 위해 Git에서 여러 커밋을 수정하는 방법


180

Git에서 일련의 커밋을 수행했으며 이제는 사용자 이름과 사용자 이메일 속성을 올바르게 설정하는 것을 잊었 음을 알게되었습니다 (새 컴퓨터). 아직 커밋을 저장소에 푸시하지 않았으므로 커밋하기 전에 어떻게 커밋을 수정할 수 있습니까 (마스터 브랜치에서 3 개의 최신 커밋 만 해당)?

나는 git resetand을 보고 git commit -C <id> --reset-author있었지만, 내가 올바른 길을 가고 있다고 생각하지 않습니다.


1
전자 메일 속성을 변경하려는 또 다른 이유는 다음 github 오류입니다. remote: error: GH007: Your push would publish a private email address....`! [원격 거부] 마스터-> 마스터 (이메일 프라이버시 제한으로 인해 푸시 거부)`.
craq

stackoverflow.com/q/750172/1340631 도 참조하십시오 .
scai

답변:


232

손끝에 필터 브랜치의 힘이있을 때 Rebase / Amend은 비효율적 인 것처럼 보입니다.

git filter-branch --env-filter 'if [ "$GIT_AUTHOR_EMAIL" = "incorrect@email" ]; then
     GIT_AUTHOR_EMAIL=correct@email;
     GIT_AUTHOR_NAME="Correct Name";
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL;
     GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; fi' -- --all

(명확성을 위해 여러 줄로 나누지 만 필수는 아님)

작업이 끝나면 결과를 검사하여 의도하지 않은 것을 변경하지 않았는지 확인하십시오!


이것을 조금 더 설명해 주시겠습니까? 필터 브랜치가 확실하지 않은 경우
max pleaner

1
@maxpleaner git filter-branch --help는 매우 간단합니다 :)
alediaferia

3
help.github.com/articles/changing-author-info 도 참조하십시오 . 태그를 새 기록으로 마이그레이션하기 위해 추가 --tag-name-filter cat합니다 filter-branch. 또한 사용하는 --branches --tags대신 --all단지 브랜치와 태그의 역사와 잎을 다시 작성하는을, 다른 refs(즉, 아마 당신이 사용하고있는 예를 들어하지 않는 많은 차이가되지 않습니다하지만 혼자 git-notes)
토비아스 Kienzler

12
에서이 작업을 수행하기 위해 단지 마지막 두 커밋, 나는 대체 -- --all와 함께HEAD~1..HEAD
nmz787

1
@ nmz787 얼마나 많은 로그가 표시 git log HEAD~2..HEAD됩니까?
Jona

148

대화식 rebase 접근 방식은 exec와 함께 사용하면 매우 좋습니다. rebase의 특정 커밋 또는 모든 커밋에 대해 쉘 명령을 실행할 수 있습니다.

먼저 git author 설정을 설정하십시오.

git config --global user.name "John Doe"
git config --global user.email johndoe@example.com

그런 다음 지정된 SHA 이후의 모든 커밋에 대한 작성자를 재설정

git rebase -i YOUR_SHA -x "git commit --amend --reset-author -CHEAD"

변경 사항을 확인하는 편집기가 나타납니다. 여기에서해야 할 일은 저장하고 종료하는 것입니다. 각 커밋을 거쳐 -x 플래그에 지정된 명령을 실행합니다.

아래 @Dave의 의견에 따라 원본 타임 스탬프를 유지하면서 작성자를 변경할 수도 있습니다.

git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"

3
-x 옵션을 소개해 주셔서 감사합니다. 꽤 굉장합니다! -i 옵션의 경우 HEAD ~ 4를 사용하여 마지막 4 개의 커밋에서 전자 메일 주소를 수정했습니다. 매력처럼 일했다.
Brad Hein

2
filter-branch마지막 커밋을 수정하려는 경우 보다 훨씬 간단 합니다. :). 그러나 이로 인해 커밋의 타임 스탬프가 변경됩니다.
luator

24
작성자를 변경하지만 원래 타임 스탬프를 유지하려면 다음을 사용하십시오.git rebase -i YOUR_SHA -x "git commit --amend --author 'New Name <new_address@example.com>' -CHEAD"
Dave

2
@Connor git log는 저 에게도 오래된 저작권을 보여 주었지만 git status는 새로운 커밋을 올바르게 식별했으며 강제로 푸시하면 의도했던대로였습니다.
Dan M.

6
루트 사용을 포함하여 모든 커밋을 리베이스하려면 : git rebase -i --root …SHA를 전달하는 대신.
gfullam

80

마지막 커밋에 대해서만 작성자를 변경하려면

git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit

마지막 N 커밋의 작성자 만 변경한다고 가정합니다.

git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"

노트

  • --no-edit플래그 차종은 확인이 git commit --amend추가로 확인을 요구하지 않습니다
  • 을 사용할 때 git rebase -i작성자를 변경할 커밋을 수동으로 선택할 수 있습니다.

편집 한 파일은 다음과 같습니다.

pick 897fe9e simplify code a little
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix

1
루트에서 모든 커밋에 대해. git rebase -i --root UPTO_COMMIT_SHA -x "git commit --amend --author 'NEW_CHANGE'
Ashish Negi

1
병합이 포함 된 분기의 토폴로지를 그대로 유지하려면 --rebase-merges(짧은 -r) 옵션 을 추가하는 것이 좋습니다 .
donquixote

4

방법은이 목적을 위해 github에 의해 문서화되었습니다. 단계는 다음과 같습니다.

  1. 터미널을 열고 레포 의 베어 클론을 만드 십시오
git clone --bare https://github.com/user/repo.git
cd repo
  1. 편집 다음 스크립트 (교체 OLD_EMAIL, CORRECT_EMAILCORRECT_NAME)
#!/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
  1. 스크립트를 터미널에 복사 / 붙여 넣기하고 Enter 키를 눌러 실행하십시오.
  2. 변경 사항을 적용 git push --force --tags origin 'refs/heads/*'하면 완료됩니다!

GitHub에서 언급 한 것과 동일한 지침을 따랐으며 지금 GitHub가 보입니다. 그러나 나는 Git newb이며 그 후에 로컬 리포지토리를 다시 동기화하는 방법을 모르겠습니다. 내가 당기면 다른 답변에 언급 된 것과 같은 "관련되지 않은 기록을 병합하는 것을 거부"오류가 발생합니다. 새로운 커밋 기록에 대해 리베이스해야한다고 생각하지만 더 구체적인 단계를 높이 평가합니다.
enigment

@enigment github에있는 repo에 만족한다면 로컬에있는 폴더를 삭제 (또는 다른 위치로 이동)하고 github에서 간단히 복제 할 수 있습니다.
stevec

고마워, 나는 알고 있지만 그것은 관용적 인 GitHub / Git 방식처럼 보이지 않습니다.
enigment


0

몸을 굽히고 수정하는 것이 안전하지 않다면 이런 식으로 할 수 있습니다. 동시에 어쨌든 할 글로벌 설정을 설정하게 될 것입니다.

git reset HEAD~ (마지막 커밋 취소)

git config --global user.name "Your Name"

git config --global user.email you@example.com

git commit -m "message"

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