770

ソースコードを少し操作した後、通常のことをコミットしてから、リモートリポジトリにプッシュしました。しかし、その後、ソースコードでインポートを整理するのを忘れていることに気づきました。だから私は前のコミットを置き換えるためにamendコマンドを実行します:

> 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/'

私は何をすべきか?(リモートリポジトリにアクセスできます。)

4

17 に答える 17

305

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 つの省略形を使用します。:masternull local_ref を持っています。これは、null ブランチをリモート側にプッシュすることを意味しますmaster。つまり、リモート ブランチを削除します。意味のないブランチ名は:、指定された名前のローカル ブランチを同じ名前のリモート ブランチにプッシュします。masterこの場合は の略ですmaster:master

于 2008-10-31T21:58:00.533 に答える
234

簡単な暴言: 誰もここに簡単な答えを投稿していないという事実は、Git CLI によって示される必死のユーザー敵意を示しています。

とにかく、これを行う「明白な」方法は、プッシュを強制しようとしていないと仮定すると、最初にプルすることです。これにより、修正した (そしてもはや持っていない) 変更がプルされ、再び使用できるようになります。

競合を解決したら、再度プッシュできます。

そう:

git pull

プルでエラーが発生した場合は、ローカル リポジトリの構成に問題がある可能性があります (.git/config ブランチ セクションの参照が間違っていました)。

以降

git push

おそらく、「些細なマージ」について説明する件名で追加のコミットを取得するでしょう。

于 2009-09-22T10:46:04.907 に答える
121

簡単な答え: 修正されたコミットをパブリック リポジトリにプッシュしないでください。

長い答え: や のようないくつかの Git コマンドはgit commit --amendgit rebase実際に履歴グラフを書き換えます。変更を公開していない限り、これは問題ありませんが、一度公開したら、履歴をいじる必要はありません。誰かが変更を既に取得している場合、再度プルしようとすると失敗する可能性があるためです。 . コミットを修正する代わりに、変更を加えて新しいコミットを作成する必要があります。

ただし、本当に、本当に修正されたコミットをプッシュしたい場合は、次のようにすることができます。

$ git push origin +master:master

+「早送り」コミットに至らなくても、先頭の符号によって強制的にプッシュが行われます。(早送りコミットは、プッシュしている変更がパブリック リポジトリに既にある変更の直接の子孫である場合に発生します。)

于 2008-10-31T14:35:12.097 に答える
33

ローカルで修正されたコミットを破棄し、新しい変更を上に追加することで、これを解決しました。

# 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
于 2012-09-24T15:46:14.803 に答える
11

I had the same problem.

  • Accidentally amended the last commit that was already pushed
  • Done a lot of changes locally, committed some five times
  • Tried to push, got an error, panicked, merged remote, got a lot of not-my-files, pushed, failed, etc.

As a Git-newbie, I thought it was complete FUBAR.

Solution: Somewhat like @bara suggested + created a local backup branch

# 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

Maybe it's not a fast and clean solution, and I lost my history (1 commit instead of 5), but it saved a day's work.

于 2014-02-20T10:24:49.413 に答える
9

コードをリモート ブランチ (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?

重要な注意:強制プッシュを直接使用すると、他の開発者が同じブランチで作業しているというコードの問題が発生する可能性があります。したがって、これらの競合を回避するには、強制プッシュを行う前にブランチからコードをプルする必要があります。

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

これは、コミット メッセージが既にプッシュされている場合に変更する場合のベスト プラクティスです。

于 2015-01-13T07:20:05.867 に答える
6

Git リモートには既にこれらのコミット ファイルがあるため、このエラーが発生しています。これを機能させるには、ブランチを強制的にプッシュする必要があります。

git push -f origin branch_name

また、チームの他の誰かが同じブランチにプッシュした可能性があるため、必ずリモートからコードをプルしてください。

git pull origin branch_name

これは、コミットをリモートに強制的にプッシュする必要があるケースの 1 つです。

于 2016-01-21T06:35:29.630 に答える
5

修正されていないコミットを誰もプルしていないことがわかっている場合は、 の--force-with-leaseオプションを使用してくださいgit push

TortoiseGit では、「プッシュ...」オプションの「強制: 破棄可能」と「既知の変更」のチェックで同じことができます。

強制 (既知の変更を破棄する可能性があります)を使用すると、リモート リポジトリはより安全な非早送りプッシュを受け入れることができます。これにより、リモート リポジトリがコミットを失う可能性があります。注意して使用してください。これにより、リモートで他の人から不明な変更が失われるのを防ぐことができます。サーバー ブランチがリモート トラッキング ブランチと同じコミットを指しているかどうかを確認します (既知の変更)。はいの場合、強制プッシュが実行されます。それ以外の場合は拒否されます。git にはリモート追跡タグがないため、このオプションを使用してタグを上書きすることはできません。

于 2016-06-07T00:03:57.953 に答える
2

git add "your files"and を作成した後に変更をプッシュする非常にシンプルでクリーンな方法を次に示しますgit commit --amend

git push origin master -f

また:

git push origin master --force
于 2016-01-18T08:29:59.733 に答える
1

リモートリポジトリからのプルでこの問題を修正し、発生したマージの競合に対処し、コミットしてからプッシュする必要がありました。しかし、もっと良い方法があるように感じます。

于 2008-10-31T11:39:28.587 に答える
1

私は Git に言われたことをやり続けました。そう:

  • コミットが修正されたため、プッシュできません。
  • 提案どおりにプルします。
  • マージが失敗します。なので手動で修正。
  • 新しいコミット ("merge" というラベルが付いています) を作成し、それをプッシュします。
  • 効きそうです!

注: 修正されたコミットは最新のものです。

于 2016-12-02T16:29:18.070 に答える