Gitの非早送りが拒否されました


88

この質問は何度も尋ねられたように感じますが、解決策は通常「ディレクトリを削除して、新しいチェックアウトで作業をやり直した」です。コミットとプッシュを行いましたが、コミットメッセージで間違ったチケット番号を参照していることに気付きました。だから私はSOで簡単な解決策を探し、最終的に次のようにターミナルに入力しました:

$ git reset --soft HEAD^
$ git commit -m "... correct message ..."

唯一の問題は、次のエラーメッセージが表示されることです。

To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again.  See the 'Note about
fast-forwards' section of 'git push --help' for details.

私はgit-flowモデルを使用していて、開発ブランチに取り組んでいます。gitを再び幸せにするために、どうすれば元に戻すことができますか?


回答:


52

git push

git push origin +develop

24
これは解決策ですが、ブライアンキャンベルのコメントを読んで、これを使用する前に何をしているかを理解してください。
thelem

5
git push origin + master
Aniket Thakur 2013

ブライアンキャンベルの回答に記載さreceive.denyNonFastForwardsれているメモも参照してください。または Gitリポジトリをどのように構成したかによって、十分に強力ではない場合があります。+--force
トレック

174

あなたがプッシュした場合、サーバーにコミットした後、それは(とローカルにコミット書き換えgit resetgit rebasegit filter-branch書き換えられたことを押した後、または任意の他の歴史操作)、およびバックアップサーバーへのコミット、あなたが引っ張っていた他の誰を台無しにします。ここに例があります。Aをコミットし、サーバーにプッシュしたとしましょう。

-*-*-A <-マスター

-*-*-A <-発信元/マスター

ここで、前述の方法でAを書き換え、リセットして再コミットすることにします。これにより、ダングリングコミットAが残り、到達できないため、最終的にはガベージコレクションされます。

-*-*-A
    \
     A '<-マスター

-*-*-A <-発信元/マスター

他の誰かが、たとえばフレッドが、masterあなたがこれをしている間にサーバーからプルダウンした場合、彼らはAへの参照を持ちます。

-*-*-A '<-マスター

-*-*-A <-発信元/マスター

-*-*-AB <-フレッド/マスター

ここで、A 'をorigin / masterにプッシュできた場合、早送りではなくなり、履歴にAが含まれなくなります。したがって、フレッドがもう一度プルしようとした場合、彼は突然マージする必要があり、Aコミットを再導入します。

-*-*-A '<-マスター

-*-*-A <-発信元/マスター

-*-*-AB- \ 
    \ * <-フレッド/マスター
     A '-/

フレッドがたまたまこれに気づいた場合、彼はリベースを行うことができ、コミットAが再び現れるのを防ぎます。しかし、彼はこれに気づく必要があり、これを忘れないでください。また、Aを引き下げた人が複数いる場合は、ツリーで余分なAコミットが取得されないように、全員がリベースする必要があります。

そのため、他の人がそこからプルしたリポジトリの履歴を変更することは、一般的には良い考えではありません。ただし、そのリポジトリから他の人がプルしていないことがわかった場合(たとえば、それが自分のプライベートリポジトリであるか、プロジェクトを簡単に調整できる他の開発者が1人しかいない場合)、強制的に実行して更新:

git push -f

または

git push origin +master

これらは両方とも、非早送りプッシュのチェックを無視し、サーバーの内容を新しいA 'リビジョンに更新し、Aリビジョンを破棄して、最終的にはガベージコレクションされます。

receive.denyNonFastForwardsconfigオプションで強制プッシュが完全に無効にされている可能性があります。このオプションは、共有リポジトリではデフォルトで有効になっています。その場合、本当にプッシュを強制したい場合は、ブランチを削除して再作成するのが最善のオプションですgit push origin :master; git push origin master:master。ただし、このdenyNonFastForwardsオプションは上記の理由で有効になっています。共有リポジトリでは、それを使用するすべての人が新しい履歴に基づいてリベースする必要があることを意味します。

共有レポジトリでは、一般的に、問題を修正する新しいコミットを上にプッシュする方が適切です。git revert以前のコミットの変更を取り消すコミットを生成するために使用できます。


素晴らしい教育、そしてあなたは最終的に正しいコマンドを手に入れましたが、私のブランチは開発(git-flowに基づく)と呼ばれ、他の人+developが彼のコマンドを入れました-チェックは彼に行きます。とにかく天文学的なポイント数があります:P
rynmrtn

7
または、あまり暗号化されていないものを使用するgit push --force
Bennett McElwee

3
@Paniqueあなたは、互いにブロックしたり(一度に1人だけが作業できるようにしたり)したり、変更によって互いに上書きしたりせずに、大規模で複雑なコードベースで複数の人が同時に作業できるようにしようとしています。各人が独立して変更を加え、それらの変更をマージできる必要があります。マージ(手動または自動)は、予期しない問題を引き起こす可能性があります。そのため、問題が発生した場合に何が起こったかを把握できるように、できるだけ多くの情報を保持する必要があります。これは本質的に複雑です。汚れていません。ただ難しい問題です。
ブライアンキャンベル

リモートリポジトリの履歴を書き換えるために-fと+オプションの両方を試しました。どちらのオプションでも、早送り以外の問題が発生しました。[5:05 PM] $ git push -f origin local_A:remote_Aオブジェクトのカウント:35、完了。最大2スレッドを使用するデルタ圧縮。オブジェクトの圧縮:100%(18/18)、完了。オブジェクトの書き込み:100%(21/21)、7.41 KiB、完了。合計21(デルタ9)、再利用0(デルタ0)リモート:履歴が失われないようにするため、非早送りの更新は拒否されました。再度プッシュする前に、リモートの変更( 'git pull'など)をマージします。詳細については、「git push --help」の「早送りに関する注意」セクションを参照してください。
Srikanth、2013年

4
@Srikanth receive.denyNonFastForwardsconfigオプションで強制プッシュを完全に無効にすることが可能です。このオプションは、共有リポジトリではデフォルトで有効になっています。その場合、本当にプッシュを強制したい場合は、ブランチを削除して再作成するのが最善のオプションですgit push origin :remote_A; git push origin local_A:remote_A。しかし、共有リポジトリでこの種のワークフローを実行するのがなぜ悪いのかについて、上で書いたことを読んでください。削除または書き換えようとしているコミットで重大な問題が発生する場合にのみ、これを実行する必要があります。
ブライアンキャンベル

14

を実行する必要があるかもしれませgit pullん。その後、再度コミットできます。競合がある場合は、解決するように求められます。

gitconfigを指定して更新していない場合は、プルするブランチを指定する必要があることに注意してください...

例えば:

git pull origin develop:develop

非早送りについてはまだ怒っています。それを強制的にマージする方法についての考えはありますか?! [rejected] develop -> develop (non-fast-forward)
rynmrtn

スイッチは-fだと思いますが、間違っている可能性があります。kernel.org/pub/software/scm/git/docs/git-pull.html
Tony

これは部分的に機能します。私はgithubに更新を見ていません(以前のコミットが最新であることを示していますgit push origin develop
rynmrtn

7

私はEGitを使用していて、この問題にも直面しました。rebase現在のブランチを試してみましたが、うまくいきました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.