「リモートリポジトリの巻き戻しが拒否される」の版間の差分

提供: tknotebook
移動: 案内検索
(対処法)
(リモートサーバーからコミットを直接削除する)
 
(1人の利用者による、間の16版が非表示)
4行: 4行:
 
==現象==
 
==現象==
  
リモートリポジトリに誤って登録したコミットを取り消したい場合は、
+
'''リモートリポジトリに誤って登録したコミットを取り消したい場合'''は、
revert で打消しのコミットを登録するのがまっとうな方法です。
+
'''revert''' で打消しのコミットを登録するのがまっとうな方法です。
 +
SCMは一度登録したものは取り消さないのが大原則で、登録したコミットを多くの人が
 +
既にpullしていた場合、コミットの削除は'''大災害'''に発展する恐れがあるからです。
  
でも少人数でリポジトリを管理していて、最近誰も pull していないことがわかっているなら
+
でも少人数でリポジトリを使っていて、最近誰も pull していないことがわかっているなら、
誤りのコミットはきれいさっぱりを削除したくなるものです。
+
間違いで登録してしまったコミットはきれいさっぱりを削除したくなるのが人情でしょう。ごみは残したくないものです。
  
そういう場合は
+
そういう場合は、ローカルリポジトリから
  
 
  git reset HEAD~ --hard
 
  git reset HEAD~ --hard
 
  git push -f
 
  git push -f
  
が定石ですが、
+
として、push で強制的にリモートのコミットを削除するのが定石ですが、
  
 
<pre>
 
<pre>
g push -f
 
 
Total 0 (delta 0), reused 0 (delta 0)
 
Total 0 (delta 0), reused 0 (delta 0)
 
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
 
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
35行: 36行:
 
というように '''--shared オプション付きで作った場合、none-fast-forward な push が断固拒否される設定になっている'''からです。
 
というように '''--shared オプション付きで作った場合、none-fast-forward な push が断固拒否される設定になっている'''からです。
  
--shared は複数の人間でリモートリポジトリを共用するために作るときに指定するオプションで、
+
--shared は複数の人間が供用するリモートリポジトリを作るオプションです。
一度 pull されたコミットが削除されると大惨事を引き起こす可能性のある git の特性を考えると妥当と言えます。
+
  
下記はリポジトリの config ファイルの中身で、denyNonFastforwards がその設定です。
+
一度 pull されたコミットがリモートリポジトリから削除されると大惨事を引き起こす可能性のあるという git の特性を考えると妥当な
 +
設定と言えるでしょう。
 +
 
 +
下記はリモートリポジトリの config ファイルの中身で、denyNonFastforwards がその設定です。
 
true なら none-fast-forward な push は断固拒否されます。
 
true なら none-fast-forward な push は断固拒否されます。
  
54行: 57行:
  
 
==対処法==
 
==対処法==
 +
 +
対処方法は2つあります。よく考えて決めてください。
  
 
===denyNonFastforwardsを false に設定する===
 
===denyNonFastforwardsを false に設定する===
59行: 64行:
 
リモートリポジトリの config ファイルの denyNonFastforwards の行を
 
リモートリポジトリの config ファイルの denyNonFastforwards の行を
 
  denyNonFastforwards = false
 
  denyNonFastforwards = false
とします。ただしこの設定では git push -f という危険な行為ができるようになってしまうのでご注意ください!!
+
とします。ただしこの設定では '''git push -f という危険な行為ができるようになってしまう'''のでご注意ください!!
 +
 
 +
直接リポジトリの configファイルを変更してもよいですが、リモートリポジトリに対して git コマンドで
 +
 
 +
git config receive.denyNonFastforwards false
 +
としても同じことができます。
  
 
===リモートサーバーからコミットを直接削除する===
 
===リモートサーバーからコミットを直接削除する===
  
 
リモートサーバにログインして、リモートリポジトリに対して git コマンドを実行できる権限があるなら
 
リモートサーバにログインして、リモートリポジトリに対して git コマンドを実行できる権限があるなら
 +
リモートリポジトリに対して、コマンドラインで
  
 
  git reset HEAD~ --soft
 
  git reset HEAD~ --soft
  
 
を実行すれば、コミットを削れます。--soft を指定しないと リモートリポジトリでは git reset は実行できないことに
 
を実行すれば、コミットを削れます。--soft を指定しないと リモートリポジトリでは git reset は実行できないことに
注意してください。
+
注意してください。また、リモートリポジトリに対して reset を行うことは、大変危険であることを自覚して行ってください!
  
この方法では 禁断の git push -f を許さないので、より安全な方法と言えるでしょう。
+
この方法は だれでも禁断の git push -f を許すことにならないので、より安全な方法と言えるでしょう。
 
+
直接リポジトリのファイルを変更してもよいですが、リモートリポジトリに対して git コマンドで
+
 
+
git config receive.denyNonFastforwards false
+
としても同じことができます。
+

2016年12月10日 (土) 01:15時点における最新版

メインページ>コンピュータの部屋#ソフトウェア>Git tips

現象

リモートリポジトリに誤って登録したコミットを取り消したい場合は、 revert で打消しのコミットを登録するのがまっとうな方法です。 SCMは一度登録したものは取り消さないのが大原則で、登録したコミットを多くの人が 既にpullしていた場合、コミットの削除は大災害に発展する恐れがあるからです。

でも少人数でリポジトリを使っていて、最近誰も pull していないことがわかっているなら、 間違いで登録してしまったコミットはきれいさっぱりを削除したくなるのが人情でしょう。ごみは残したくないものです。

そういう場合は、ローカルリポジトリから

git reset HEAD~ --hard
git push -f

として、push で強制的にリモートのコミットを削除するのが定石ですが、

Total 0 (delta 0), reused 0 (delta 0)
remote: error: denying non-fast-forward refs/heads/master (you should pull first)
To C:/git-repos/remote
 ! [remote rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'C:/git-repos/remote'


となってしまって -f(--force) を付けても push が拒否される場合があります。

原因

これは リモートリポジトリ を

git init --bare --shared

というように --shared オプション付きで作った場合、none-fast-forward な push が断固拒否される設定になっているからです。

--shared は複数の人間が供用するリモートリポジトリを作るオプションです。

一度 pull されたコミットがリモートリポジトリから削除されると大惨事を引き起こす可能性のあるという git の特性を考えると妥当な 設定と言えるでしょう。

下記はリモートリポジトリの config ファイルの中身で、denyNonFastforwards がその設定です。 true なら none-fast-forward な push は断固拒否されます。

[core]
        repositoryformatversion = 0
        filemode = false
        bare = true
        symlinks = false
        ignorecase = true
        sharedrepository = 1
[receive]
        denyNonFastforwards = true

対処法

対処方法は2つあります。よく考えて決めてください。

denyNonFastforwardsを false に設定する

リモートリポジトリの config ファイルの denyNonFastforwards の行を

denyNonFastforwards = false

とします。ただしこの設定では git push -f という危険な行為ができるようになってしまうのでご注意ください!!

直接リポジトリの configファイルを変更してもよいですが、リモートリポジトリに対して git コマンドで

git config receive.denyNonFastforwards false

としても同じことができます。

リモートサーバーからコミットを直接削除する

リモートサーバにログインして、リモートリポジトリに対して git コマンドを実行できる権限があるなら リモートリポジトリに対して、コマンドラインで

git reset HEAD~ --soft

を実行すれば、コミットを削れます。--soft を指定しないと リモートリポジトリでは git reset は実行できないことに 注意してください。また、リモートリポジトリに対して reset を行うことは、大変危険であることを自覚して行ってください!

この方法は だれでも禁断の git push -f を許すことにならないので、より安全な方法と言えるでしょう。