私が自分のソースコードで少し働いたとき、私は私の通常の事コミットをしました、そして次に私はリモートリポジトリにプッシュしました。しかし、私は自分のインポートをソースコードにまとめるのを忘れていることに気づきました。だから私は前のコミットを置き換えるために修正コマンドを行います:
> git commit --amend
残念ながらコミットはリポジトリにプッシュバックできません。それはこのように拒絶されます:
> git Push Origin
To //my.remote.repo.com/stuff.git/
! [rejected] master -> master (non-fast forward)
error: failed to Push some refs to '//my.remote.repo.com/stuff.git/'
私は何をすべきか? (リモートリポジトリにアクセスできます。)
私は実際にかつて--force
と.git
リポジトリにプッシュし、Linus BIG TIME に叱られました。一般に、これは他の人々にとって多くの問題を引き起こすでしょう。簡単な答えは「やらないで」です。
とにかく他の人がレシピを出してくれたのを見たので、ここでは繰り返さない。しかし、ここであなたが修正したコミットを--force(または+ master)でプッシュしたafter状況から回復するためのヒントがあります。
git reflog
を使用してください(それをold
と呼び、私達はあなたが作成した新しいコミットをnew
を修正することによって呼びます)。git checkout new && git merge -s ours old
のように、old
のツリーを記録して、new
とnew
の間のマージを作成します。git merge master
でそれをあなたのマスターにマージしてくださいgit Push . HEAD:master
の結果でマスターを更新してくださいそれで、あなたがプッシュを修正して強制することによって抹消したコミットに彼らの仕事を基づかせるのに十分に不幸だった人々は結果として生じるマージがあなたがnew
よりold
を支持するのを見るでしょう。彼らの後の合併はあなたの修正から生じたold
とnew
の間の衝突を見ることはないでしょうから、それらは苦しむ必要はありません。
あなたはGitの安全機能を見ています。あなたのブランチのヘッドコミットはあなたがプッシュしているブランチの現在のヘッドコミットの直接の子孫ではないので、Gitはあなたのブランチでリモートブランチを更新することを拒否します。
そうでない場合、2人の人間が同じリポジトリに同時にプッシュすると同時に新しいコミットが発生したことを知らず、最後にプッシュした人がどちらもしなくても前のプッシャーの作業を失うことになります。彼らはこれを理解しています。
自分だけがプッシュしていることを知っていて、修正したコミットをプッシュするか、ブランチを巻き戻すコミットをプッシュしたい場合は、-f
スイッチを使用してGitにリモートブランチを強制的に更新させることができます。
git Push -f Origin master
Gitはリモートリポジトリが遠端で設定変数receive.denynonfastforwards
を使うことによって早送りでないプッシュを拒否することを許すのでこれさえ動作しないかもしれません。この場合、拒否の理由は次のようになります(「リモート拒否」の部分に注意してください)。
! [remote rejected] master -> master (non-fast forward)
これを回避するには、リモートリポジトリの設定を変更する必要があるか、あるいは汚いハックとしてブランチを削除して再作成することができます。
git Push Origin :master
git Push Origin master
一般的にgit Push
の最後のパラメータは<local_ref>:<remote_ref>
というフォーマットを使います。ここでlocal_ref
はローカルリポジトリのブランチの名前、remote_ref
はリモートリポジトリのブランチの名前です。このコマンドペアは2つの短縮形を使用します。 :master
はnull local_refを持ちます。これはnullブランチをリモート側にプッシュすることを意味しますmaster
、つまりリモートブランチを削除します。 :
が付いていないブランチ名は、指定された名前のローカルブランチを同じ名前のリモートブランチにプッシュすることを意味します。この場合のmaster
はmaster:master
の短縮形です。
素直な答え:誰もここに簡単な答えを投稿していないという事実は、Git CLIが示している絶望的なユーザー敵意を示しています。
とにかく、これを行うための「明らかな」方法は、あなたがプッシュを強制しようとしていないと仮定すると、最初に引っ張ることです。これはあなたが修正した変更を引っ張ります(そしてもう変更しません)。
衝突を解決したら、もう一度プッシュできます。
そう:
git pull
プルエラーが発生した場合は、ローカルリポジトリの設定に何らかの問題がある可能性があります(.git/configブランチの節で誤った参照をしました)。
以降
git Push
たぶん、あなたは "Trivial merge"について話している主題との追加のコミットを得るでしょう。
簡単な答え:修正したコミットを公開リポジトリにプッシュしないでください。
長い答え:git commit --amend
やgit rebase
のようないくつかのGitコマンドは、実際には履歴グラフを書き換えます。変更を公開していない限りこれで問題ありませんが、一度公開してしまえば、履歴をざっと見て回ってはいけません。 。コミットを修正するのではなく、変更を加えて新しいコミットをするだけです。
しかし、本当に、もしあなたが本当に修正されたコミットをプッシュしたいのであれば、次のようにすることができます。
$ git Push Origin +master:master
たとえ「早送り」コミットにならなくても、先頭の+
サインはプッシュを強制的に発生させます。 (あなたがプッシュしている変更が 直接の子孫 すでにパブリックリポジトリにある変更の場合には早送りコミットが発生します。)
これはcommit --amend
を作成した後に変更をプッシュするための非常にシンプルでクリーンな方法です。
git reset --soft HEAD^
git stash
git Push -f Origin master
git stash pop
git commit -a
git Push Origin master
これは次のことを行います。
これを別のブランチやリモートに適用する場合は、必ず "Origin"と "master"を変更してください。
私は自分の地域で修正されたコミットを破棄し、新しい変更を追加することでそれを解決しました:
# Rewind to commit before conflicting
git reset --soft HEAD~1
# Pull the remote version
git pull
# Add the new commit on top
git add ...
git commit
git Push
私は同じ問題を抱えていました。
Git初心者として、私はそれが完全だったと思いました _ fubar _ 。
解決策:@baraが+ローカルバックアップブランチを作成するよう提案したようなものです
# Rewind to commit just before the pushed-and-amended one.
# Replace <hash> with the needed hash.
# --soft means: leave all the changes there, so nothing is lost.
git reset --soft <hash>
# Create new branch, just for a backup, still having all changes in it.
# The branch was feature/1234, new one - feature/1234-gone-bad
git checkout -b feature/1234-gone-bad
# Commit all the changes (all the mess) not to lose it & not to carry around
git commit -a -m "feature/1234 backup"
# Switch back to the original branch
git checkout feature/1234
# Pull the from remote (named 'Origin'), thus 'repairing' our main problem
git pull Origin/feature/1234
# Now you have a clean-and-non-diverged branch and a backup of the local changes.
# Check the needed files from the backup branch
git checkout feature/1234-gone-bad -- the/path/to/file.php
たぶんそれは速くてきれいな解決策ではない、そして私は私の歴史(5の代わりに1コミット)を失ったが、それは1日の仕事を救った。
リモートブランチ(GitHub/Bitbucket)にコードをプッシュしていない場合は、以下のようにコマンドラインでコミットメッセージを変更できます。
git commit --amend -m "Your new message"
もしあなたが特定のブランチに取り組んでいるのなら、こうしてください:
git commit --amend -m "BRANCH-NAME: new message"
すでに間違ったメッセージでコードをプッシュしている場合は、メッセージを変更するときに注意する必要があります。つまり、コミットメッセージを変更してもう一度押すと、問題が発生します。滑らかにするには、次の手順に従います。
それをする前に答え全体を読んでください
git commit --amend -m "BRANCH-NAME : your new message"
git Push -f Origin BRANCH-NAME # Not a best practice. Read below why?
重要な注意: あなたが直接Pushを使うと、他の開発者が同じブランチに取り組んでいるコードの問題に終わるかもしれません。そのため、これらの衝突を避けるためには、 force Push を実行する前にブランチからコードを取得する必要があります。
git commit --amend -m "BRANCH-NAME : your new message"
git pull Origin BRANCH-NAME
git Push -f Origin BRANCH-NAME
コミットメッセージを変更するとき、これがすでにプッシュされている場合はこれがベストプラクティスです。
誰もあなたの未修正のコミットを引っ張っていないことを知っているなら、--force-with-lease
のgit Push
オプションを使ってください。
TortoiseGitでは、「プッシュ...」オプションの「強制:破棄する」と「既知の変更」をチェックすることで同じことができます。
Force(既知の変更を破棄する可能性があります) リモートリポジトリはより安全な非早送りプッシュを受け入れることができます。これにより、リモートリポジトリがコミットを失う可能性があります。慎重に使用してください。これにより、リモートの他の人からの未知の変更を失うことを防ぐことができます。サーバーブランチがリモートトラッキングブランチと同じコミットを指しているかどうかをチェックします(既知の変更)。もしそうであれば、強制プッシュが実行される。それ以外の場合は拒否されます。 gitにはリモートトラッキングタグがないので、このオプションを使ってタグを上書きすることはできません。
Gitリモートにはすでにこれらのコミットファイルがあるため、このエラーが発生しています。これを機能させるには、ブランチを強制的にプッシュする必要があります。
git Push -f Origin branch_name
また、チームの他の誰かが同じブランチにプッシュした可能性があるので、必ずリモートからコードを引き出すようにしてください。
git pull Origin branch_name
これは、強制的にコミットをリモートにプッシュする必要があるケースの1つです。
これは、既にgit add "your files"
とgit commit --amend
を作成した後に変更をプッシュするための非常に単純でクリーンな方法です。
git Push Origin master -f
または
git Push Origin master --force
私はこの問題を解決するために、リモートレポジトリから引っ張り出し、マージ、そしてプッシュという衝突が発生した場合に対処する必要がありました。しかし、もっと良い方法があるように私は感じます。
私はGitが私にするように言われたことをやり続けました。そう:
注:修正されたコミットは最新のものです。
ここで、前回のコミットで編集を修正した方法は次のとおりです。
git stash
これであなたの作業コピーはあなたの最後のコミットの状態できれいになりました。git commit --all --amend
あなたの編集者はログメッセージ(デフォルトでは古いログメッセージ)を要求するようになるでしょう。満足したらエディタを保存して終了します。
新しい変更は古いコミットに追加されます。 git log
とgit diff HEAD^
で自分の目で確かめてください
行われた場合、隠した変更を再適用します。git stash apply