私は学校のコンピューターで簡単なスクリプトを書いて、Gitへの変更をコミットしていました(自宅のコンピューターから複製した、ペンドライブにあるリポジトリで)。いくつかのコミットの後、私はrootユーザーとして何かをコミットしていることに気付きました。
これらのコミットの作者を私の名前に変更する方法はありますか?
私は学校のコンピューターで簡単なスクリプトを書いて、Gitへの変更をコミットしていました(自宅のコンピューターから複製した、ペンドライブにあるリポジトリで)。いくつかのコミットの後、私はrootユーザーとして何かをコミットしていることに気付きました。
これらのコミットの作者を私の名前に変更する方法はありますか?
回答:
この回答ではを使用
git-filter-branch
していますが、ドキュメントではこの警告が表示されます。git filter-branchには、意図された履歴の書き換えの明白ではないマングリングを生成する可能性のある多くの落とし穴があります(そして、非常に低いパフォーマンスを備えているため、このような問題を調査する時間はほとんどありません)。これらの安全性とパフォーマンスの問題は、下位互換性を保って修正することはできないため、その使用は推奨されません。git filter-repoなどの別の履歴フィルタリングツールを使用してください。それでもgit filter-branchを使用する必要がある場合は、安全性(およびパフォーマンス)を注意深く読み、filter-branchの地雷について学び、そこに記載されている危険を可能な限りできるだけ慎重に回避してください。
著者(またはコミッター)を変更するには、すべての履歴を書き直す必要があります。それで大丈夫で価値があると思うなら、git filter-branchをチェックしてください。manページには、始めるためのいくつかの例が含まれています。また、環境変数を使用して作成者、コミッター、日付などの名前を変更できることにも注意してください。gitmanページの「環境変数」セクションを参照してください。
具体的には、次のコマンドを使用して、すべてのブランチとタグの間違った作成者名とメールをすべて修正できます(ソース:GitHubヘルプ)。
#!/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
git push --force --tags origin HEAD:master
注:この回答はSHA1を変更するため、すでにプッシュされているブランチで使用する場合は注意してください。名前のスペルを修正するか、古いメールを更新するだけの場合、gitを使用すると、を使用して履歴を書き換えることなくこれを実行できます.mailmap
。私の他の答えを見てください。
あなたができる
git rebase -i -p <some HEAD before all of your bad commits>
次に、リベースファイルですべての不良コミットを「編集」としてマークします。最初のコミットも変更したい場合は、リベースファイルの最初の行として手動で追加する必要があります(他の行のフォーマットに従ってください)。次に、gitが各コミットを修正するように求めてきたら、次のようにします。
git commit --amend --author "New Author Name <email@address.com>"
開いているエディターを編集するか、単に閉じてから、
git rebase --continue
リベースを続行します。
--no-edit
コマンドを次のように追加することにより、ここでエディターを開くのをスキップできます。
git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue
一部のコメンターが指摘したように、最新のコミットを変更するだけの場合は、rebaseコマンドは不要です。するだけ
git commit --amend --author "New Author Name <email@address.com>"
これは、指定された名前に作者を変更しますが、コミッターは、あなたのように構成でユーザーに設定されますgit config user.name
とgit config user.email
。コミッターを指定したものに設定したい場合、これは作者とコミッターの両方を設定します:
git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author
私の元の応答にはわずかな欠陥がありました。現在の間のいずれかのマージコミットがある場合HEAD
、あなたは<some HEAD before all your bad commits>
、その後、git rebase
それらを平らにします(あなたはGitHubのプルリクエストを使用する場合の方法によって、あなたの歴史の中で、マージコミットのトンがあるように予定されています)。これは非常に頻繁に非常に異なる履歴につながる可能性があり(重複した変更が「リベースされる」可能性があるため)、最悪の場合、git rebase
難しいマージの競合(マージコミットですでに解決されている可能性が高い)の解決を要求する可能性があります。解決策は、-p
フラグをに使用することですgit rebase
。これにより、履歴のマージ構造が保持されます。のマンページではgit rebase
、使用する-p
と-i
問題が発生する可能性があることを警告していますが、BUGS
「コミットの編集とコミットメッセージの言い換えは問題なく機能するはずです。」
-p
上記のコマンドに追加しました。最新のコミットを変更するだけの場合、これは問題ではありません。
git commit --amend --reset-author
また、一度だけ機能しuser.name
、user.email
正しく構成されます。
<commit>
使用user.name
とuser.email
から~/.gitconfig
:実行しgit rebase -i <commit> --exec 'git commit --amend --reset-author --no-edit'
、保存し、終了します。編集する必要はありません!
あなたも行うことができます:
git filter-branch --commit-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
then
GIT_COMMITTER_NAME="<New Name>";
GIT_AUTHOR_NAME="<New Name>";
GIT_COMMITTER_EMAIL="<New Email>";
GIT_AUTHOR_EMAIL="<New Email>";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
Windowsコマンドプロンプトでこのコマンドを使用している場合は、次の"
代わりに使用する必要があります'
。
git filter-branch --commit-filter "
if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
then
GIT_COMMITTER_NAME="<New Name>";
GIT_AUTHOR_NAME="<New Name>";
GIT_COMMITTER_EMAIL="<New Email>";
GIT_AUTHOR_EMAIL="<New Email>";
git commit-tree "$@";
else
git commit-tree "$@";
fi" HEAD
"A previous backup already exists in refs/original/ Force overwriting the backup with -f"
申し訳ありませんが、-f
このスクリプトを2回実行すると、-flag がどこにあるのでしょうか。実際、それはブライアンの答えです。フィルターブランチが解決策になった直後の妨害については申し訳ありません。
ライナーは1つですが、マルチユーザーリポジトリがある場合は注意してください。これにより、すべてのコミットが同じ(新しい)作成者とコミッターを持つように変更されます。
git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD
文字列に改行がある場合(bashでは可能です):
git filter-branch -f --env-filter "
GIT_AUTHOR_NAME='Newname'
GIT_AUTHOR_EMAIL='new@email'
GIT_COMMITTER_NAME='Newname'
GIT_COMMITTER_EMAIL='new@email'
" HEAD
HEAD
コマンドの最後に指定した場合、なぜすべてのコミットを書き換えるのですか?
git push --force --tags origin 'refs/heads/*'
助言されたコマンドの後にaを行います
$git push --force --tags origin 'refs/heads/master'
$ HOME / .gitconfigを初期化していない場合に発生します。あなたはこれを次のように修正できます:
git config --global user.name "you name"
git config --global user.email you@domain.com
git commit --amend --reset-author
gitバージョン1.7.5.4でテスト済み
--local
ん
git commit --amend --reset-author --no-edit
コマンドは、間違った作者情報でコミットを作成し、その後、正しい作者を事後的に設定した場合に特に役立ちますgit config
。メールを更新する必要があったときに、今すぐa $$を保存しました。
単一のコミットの場合:
git commit --amend --author="Author Name <email@address.com>"
(asmeurerの回答から抽出)
git help commit
、git commit --amend
「現在のブランチの先端」(HEAD)でコミットを変更します。これは通常、最新のコミットですが、最初にまたはでコミットをチェックアウトすることにより、任意のコミットにすることができます。git checkout <branch-name>
git checkout <commit-SHA>
author
あり、committer
上位のいくつかのコミットだけに悪い作者がいる場合、次のようにgit rebase -i
、exec
コマンドと--amend
コミットを使用してこれをすべて行うことができます。
git rebase -i HEAD~6 # as required
コミットの編集可能なリストが表示されます:
pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2
次に、exec ... --author="..."
作者が悪いすべての行の後に行を追加します。
pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD
保存してエディターを終了します(実行します)。
この解決策は、他のいくつかの解決策よりも入力に時間がかかる場合がありますが、非常に制御可能です。どのようなコミットが発生したかを正確に把握しています。
インスピレーションを与えてくれた@asmeurerに感謝します。
exec git commit --amend --reset-author -C HEAD
か?そして各行は唯一ですか?
Someone else's commit
代わりになぜ始めるのmy bad commit 1
ですか?私HEAD^^
は最後の2つのコミットを修正しようとしたところ、完全にうまくいきました。
git rebase -i HEAD^^^^^^
次のように書くこともできますgit rebase -i HEAD~6
Githubには、次のシェルスクリプトである優れたソリューションがあります。
#!/bin/sh
git filter-branch --env-filter '
an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"
if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match" ]
then
cn="Your New Committer Name"
cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
then
an="Your New Author Name"
am="Your New Author Email"
fi
export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'
git reset --hard HEAD^
、以前のバージョンにそれらを得るために、他のローカルリポジトリに数回git pull
改訂版を-ed、そしてここで私は含む任意の行せずにいますunknown <stupid-windows-user@.StupidWindowsDomain.local>
(愛のgitのが不履行になりました)。
git push -f
。また、この後、ローカルリポジトリを再クローンする必要があります。
docgnomeが述べたように、履歴の書き換えは危険であり、他の人のリポジトリを破壊します。
しかし、本当にそれを実行したい場合で、bash環境にいる場合(Linuxでは問題ありません。Windowsでは、gitのインストールで提供されるgit bashを使用できます)、git filter-branchを使用します。
git filter-branch --env-filter '
if [ $GIT_AUTHOR_EMAIL = bad@email ];
then GIT_AUTHOR_EMAIL=correct@email;
fi;
export GIT_AUTHOR_EMAIL'
スピードアップするために、書き換えたいリビジョンの範囲を指定できます:
git filter-branch --env-filter '
if [ $GIT_AUTHOR_EMAIL = bad@email ];
then GIT_AUTHOR_EMAIL=correct@email;
fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD
--tag-name-filter cat
「機能させる」オプションです。
--tag-name-filter cat
。これは本当にデフォルトの動作でした。
別の作者からマージされていないコミットを引き継ぐ場合、これを処理する簡単な方法があります。
git commit --amend --reset-author
--no-edit
これをさらに簡単にするために追加できます。一般的に、ほとんどの人はコミットメッセージではなく電子メールアドレスのみを更新することを望んでいるためです
これをエイリアスとして使用できるので、次のことができます。
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
〜/ .gitconfigに追加:
[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 "
ソース:https : //github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
お役に立てれば幸いです。
[[ ]]
をsh互換のテスト[ ]
(単一のブラケット)に置き換える必要がありました。その上、それは非常にうまく機能します、ありがとう!
これは、@ Brianのバージョンのより精巧なバージョンです。
著者とコミッターを変更するには、次のようにします(bashで可能な文字列に改行を入れます)。
git filter-branch --env-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
then
GIT_COMMITTER_NAME="<New name>";
GIT_COMMITTER_EMAIL="<New email>";
GIT_AUTHOR_NAME="<New name>";
GIT_AUTHOR_EMAIL="<New email>";
fi' -- --all
次のいずれかのエラーが発生する可能性があります。
これらのエラーにもかかわらず強制的に実行したい場合は、--force
フラグを追加します。
git filter-branch --force --env-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
then
GIT_COMMITTER_NAME="<New name>";
GIT_COMMITTER_EMAIL="<New email>";
GIT_AUTHOR_NAME="<New name>";
GIT_AUTHOR_EMAIL="<New email>";
fi' -- --all
-- --all
オプションの説明が少し必要になる場合があります。これにより、すべての参照のすべてのリビジョンでフィルターブランチが機能します。(すべてのブランチを含む)の。これは、たとえば、タグも書き換えられ、書き換えられたブランチに表示されることを意味します。
一般的な「間違い」はHEAD
代わりに使用することです。つまり、現在のブランチのみのすべてのリビジョンをフィルタリングします。そして、書き換えられたブランチにはタグ(または他の参照)は存在しません。
最後の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
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
その後、一部の行を変更して、作成者を変更する場所を確認できます。これにより、自動化と制御の中間点が得られます。実行されるステップが表示され、保存するとすべてが一度に適用されます。
git rebase -i master -x ...
git rebase -i <sha1 or ref of starting point>
edit
(またはe
)すべてのコミットを処理するまで、次の2つのコマンドをループします。
git commit --amend --reuse-message=HEAD --author="New Author <new@author.email>"
;
git rebase --continue
これにより、他のすべてのコミット情報(日付を含む)が保持されます。この--reuse-message=HEAD
オプションは、メッセージエディターが起動しないようにします。
以下を使用して、タグとすべてのブランチを含むリポジトリ全体の作成者を書き換えます。
git filter-branch --tag-name-filter cat --env-filter "
export GIT_AUTHOR_NAME='New name';
export GIT_AUTHOR_EMAIL='New email'
" -- --all
次に、filter-branchのMANページで説明されているように、によってバックアップされたすべての元の参照を削除しますfilter-branch
(これは破壊的なため、最初にバックアップします)。
git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d
--tag-name-filter cat
です。そうしないと、タグはコミットの元のチェーンに残ります。他の答えはこれに言及することに失敗します。
シンプルなものを取り込むことで機能するこのソリューションを採用しましたauthor-conv-file
(形式はgit-cvsimportの場合と同じです)。author-conv-file
すべてのブランチで定義されているすべてのユーザーを変更することで機能します。
これをと組み合わせて使用してcvs2git
、リポジトリをcvsからgitに移行しました。
すなわちサンプル author-conv-file
john=John Doe <john.doe@hotmail.com>
jill=Jill Doe <jill.doe@hotmail.com>
スクリプト:
#!/bin/bash
export $authors_file=author-conv-file
git filter-branch -f --env-filter '
get_name () {
grep "^$1=" "$authors_file" |
sed "s/^.*=\(.*\) <.*>$/\1/"
}
get_email () {
grep "^$1=" "$authors_file" |
sed "s/^.*=.* <\(.*\)>$/\1/"
}
GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
' -- --all
唯一の問題が作者/メールアドレスがいつもと違うということであれば、これは問題ではないことを指摘しておきます。正しい修正は、次の.mailmap
ような行でディレクトリのベースに呼び出されるファイルを作成することです
Name you want <email you want> Name you don't want <email you don't want>
それ以降、などのコマンドは、git shortlog
これら2つの名前が同じであると見なします(特に指示しない限り)。http://schacon.github.com/git/git-shortlog.htmlを参照してくださいを。
これには、上流を使用している場合に問題が発生する可能性がある履歴を書き換える必要がないという点で、他のすべてのソリューションの利点があり、常に誤ってデータを損失する良い方法です。
もちろん、自分で何かをコミットし、それが本当に他の誰かである必要があり、この時点で履歴を書き換えても構わない場合、コミットの作成者を変更することは、おそらく帰属目的のために良い考えです(この場合、他の答えはこちら)。
特に、他の開発者からのパッチをコミットする場合、これは本質的に彼らのコードを盗むでしょう。
以下のバージョンはすべてのブランチで機能し、それを防ぐために作成者とコミッターを個別に変更します。
allオプションのleif81への称賛。
#!/bin/bash
git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
GIT_AUTHOR_NAME="<new author>";
GIT_AUTHOR_EMAIL="<youmail@somehost.ext>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
GIT_COMMITTER_NAME="<new commiter>";
GIT_COMMITTER_EMAIL="<youmail@somehost.ext>";
fi
' -- --all
コミットauthor name & email
をAmend
に変更し、次に置き換えold-commit with new-one
ます。
$ git checkout <commit-hash> # checkout to the commit need to modify
$ git commit --amend --author "name <author@email.com>" # change the author name and email
$ git replace <old-commit-hash> <new-commit-hash> # replace the old commit by new one
$ git filter-branch -- --all # rewrite all futures commits based on the replacement
$ git replace -d <old-commit-hash> # remove the replacement for cleanliness
$ git push -f origin HEAD # force push
別の方法Rebasing
:
$ git rebase -i <good-commit-hash> # back to last good commit
# Editor would open, replace 'pick' with 'edit' before the commit want to change author
$ git commit --amend --author="author name <author@email.com>" # change the author name & email
# Save changes and exit the editor
$ git rebase --continue # finish the rebase
これを行う最も速くて簡単な方法は、git rebaseの--exec引数を使用することです。
git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'
これにより、次のようなtodoリストが作成されます。
pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...
これはすべて自動的に機能し、何百ものコミットがあるときに機能します。
このリポジトリの唯一のユーザーである場合は、(svickが書いたように)または/ plusフィルタースクリプト(docgnome answerで参照されている記事で説明されているように)、またはインタラクティブなリベースを使用して、履歴を書き換えることができます。しかし、これらのどちらでも、最初に変更されたコミット以降のリビジョンが変更されます。これは、ブランチのリライトに基づいて変更を行った人にとっては問題になります。git filter-branch
git fast-export
git fast-import
回復
他の開発者が自分の作業を書き換え前のバージョンに基づいて行わなかった場合、最も簡単な解決策は再クローン(再度クローン)することです。
またはgit rebase --pull
、リポジトリに変更がない場合は早送りするか、書き直されたコミットに基づいてブランチをリベースすることもできます(書き換え前のコミットを永久に保持するため、マージは避けたい)。これらのすべては、彼らが仕事をコミットしていないことを前提としています。git stash
そうでなければ変更を隠しておくために使用します。
他の開発者が機能ブランチを使用したりgit pull --rebase
、アップストリームが設定されていないなどの理由で機能しない場合は、書き換え後のコミットに基づいて作業をリベースする必要があります。たとえば、新しい変更(git fetch
)をフェッチした直後にmaster
、/に基づくブランチの場合、origin/master
実行する必要があります
$ git rebase --onto origin/master origin/master@{1} master
これorigin/master@{1}
は、書き換え前の状態(フェッチ前)です。gitrevisionsを参照してください。
代わりの解決策は、バージョン1.6.5以降、Gitで利用可能なrefs / replace /メカニズムを使用することです。このソリューションでは、間違ったメールがあるコミットの代わりを提供します。その後、レフリー(のようなもの「置き換える」フェッチ誰fetch = +refs/replace/*:refs/replace/*
で適切な場所にrefspec 彼らは .git/config
)透過的に代替品になるだろう、とそれらのREFをフェッチしていない人たちは、古いコミットを見るでしょう。
手順は次のようになります。
間違ったメールですべてのコミットを見つけてください、例えば
$ git log --author=user@wrong.email --all
間違ったコミットごとに、代わりのコミットを作成し、オブジェクトデータベースに追加します
$ git cat-file -p <ID of wrong commit> |
sed -e 's/user@wrong\.email/user@example.com/g' > tmp.txt
$ git hash-object -t commit -w tmp.txt
<ID of corrected commit>
オブジェクトデータベースのコミットを修正したので、次のgit replace
コマンドを使用して、間違ったコミットを修正されたコミットに自動的かつ透過的に置き換えるようにgitに指示する必要があります。
$ git replace <ID of wrong commit> <ID of corrected commit>
最後に、すべての代替品をリストして、この手順が成功したかどうかを確認します
$ git replace -l
交換が行われるかどうかを確認します
$ git log --author=user@wrong.email --all
もちろん、この手順を自動化することもできます。まあ、git replace
(まだ)バッチモードがないものを使用する場合を除き、シェルループを使用するか、「手動」で置き換える必要があります。
未検証!YMMV。
refs/replace/
メカニズムを使用すると、いくつかの荒いコーナーに遭遇する可能性があることに注意してください。それは新しいものであり、まだ十分にテストされていません。
修正したいコミットが最新のものであり、それらだけのカップルの場合は、の組み合わせを使用することができますgit reset
し、git stash
右の名前とメールアドレスを設定した後、再びそれらをコミット戻って。
シーケンスは次のようになります(2つの誤ったコミット、保留中の変更がない場合)。
git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a
EGitでEclipseを使用している場合、非常に簡単な解決策があります。
前提:ローカルブランチ 'local_master_user_x'にコミットがありますが、ユーザーが無効なため、リモートブランチ 'master'にプッシュできません。
gitには2つの異なる電子メールアドレスが格納されていることに注意してください。1つはコミッター(変更をコミットした人)用で、もう1つは作成者用です。(変更を作成した人)用です。
コミッター情報はほとんどの場所で表示されませんが、それで確認できますgit log -1 --format=%cn,%ce
(または特定のコミットを指定するshow
代わりに使用log
します)。
最後のコミットの作成者を変更するのはと同じくらい簡単git commit --amend --author "Author Name <email@example.com>"
ですが、コミッター情報に対して同じことをするためのワンライナーまたは引数はありません。
解決策は、ユーザーの情報を(一時的に、または一時的に)変更し、次にコミットを修正することです。これにより、コミッターが現在の情報に更新されます。
git config user.email my_other_email@example.com
git commit --amend
path\to\repo\.git
。完全に抹消するために何をする必要があるのか、私にはまだわかりません。残念ながら修正(?)は消えないようです。
今日、著者名のUTF8文字がビルドサーバーで問題を引き起こしているという問題が発生したため、これを修正するために履歴を書き直す必要がありました。実行された手順は次のとおりです。
手順1:https : //help.github.com/articles/setting-your-username-in-git/の指示に従って、将来のすべてのコミットのためにgitでユーザー名を変更します 。
ステップ2:次のbashスクリプトを実行します。
#!/bin/sh
REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp
# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}
# Change to the cloned repository
cd ${REPO_DIR}
# Checkout all the remote branches as local tracking branches
git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout
# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="me@something.com"
CORRECT_NAME="New Me"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags
# Force push the rewritten branches + tags to the remote
git push -f
# Remove all knowledge that we did something
rm -rf ${REPO_DIR}
# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches
概要:リポジトリを一時ファイルにチェックアウトし、すべてのリモートブランチをチェックアウトし、履歴を書き換えるスクリプトを実行し、新しい状態を強制的にプッシュし、変更を取得するためにリベースプルを行うようにすべての同僚に伝えます。
OS Xでこれを実行すると、コミットメッセージの行末がどういうわけか混乱し、後でLinuxマシンで再実行する必要があったため、問題が発生しました。
あなたの問題は本当に一般的です。「を参照してください修正著者GitリポジトリのリストにMailmapの使い方」
簡単にするために、プロセスを簡単にするスクリプトを作成しました:git-changemail
そのスクリプトをパスに配置した後、次のようなコマンドを発行できます。
現在のブランチで著者の一致を変更する
$ git changemail -a old@email.com -n newname -m new@email.com
<branch>および<branch2>で作成者とコミッターの一致を変更します。-f
フィルターブランチに渡して、バックアップの書き換えを許可する
$ git changemail -b old@email.com -n newname -m new@email.com -- -f <branch> <branch2>
リポジトリに既存のユーザーを表示する
$ git changemail --show-both
ちなみに、変更を行った後は、git-backup-cleanを使用してフィルターブランチからバックアップをクリーンアップします。
これを試してみてください。上記と同じですが、インタラクティブに行われます。
bash <(curl -s https://raw.githubusercontent.com/majdarbash/git-author-change-script/master/run.sh)
リファレンス:https : //github.com/majdarbash/git-author-change-script
私の例も追加したいと思います。与えられたパラメーターでbash_functionを作成します。
これはmint-linux-17.3で動作します
# $1 => email to change, $2 => new_name, $3 => new E-Mail
function git_change_user_config_for_commit {
# defaults
WRONG_EMAIL=${1:-"you_wrong_mail@hello.world"}
NEW_NAME=${2:-"your name"}
NEW_EMAIL=${3:-"new_mail@hello.world"}
git filter-branch -f --env-filter "
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;
}
あなたがこのリポジトリの唯一のユーザーであるか、他のユーザーのリポジトリを壊す可能性を気にしていない場合は、はい。これらのコミットをプッシュし、それらが他のどこかにアクセスできる場所に存在する場合は、他の人のリポジトリを壊すことを気にしない限り、できません。問題は、これらのコミットを変更することで、新しいSHAを生成し、別のコミットとして扱われるようにすることです。他の誰かがこれらの変更されたコミットを取り込もうとするとき、歴史は異なり、カブームです。
このページhttp://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.htmlでは、その方法について説明しています。(私はこれを試していないので、YMMV)
refs/replace/
メカニズムを試してください。