git bareリポジトリの最後のコミットをコミット解除するにはどうすればよいですか?


91

ベアリポジトリでは意味をなさないgitコマンドがいくつかあることを考慮すると(ベアリポジトリはインデックスを使用せず、作業ディレクトリがないため)、

git reset --hard HEAD^ 

このようなリポジトリの最後の変更をコミット解除するソリューションではありません。

インターネットで検索すると、トピックに関連して私が見つけることができるのはthisだけで、これを行う3つの方法が提示されます

2.「git push -fベアリポジトリ以外から」;
3. " git branch -f this $that"。

どのソリューションがより適切であると思いますか、またはこれを行うには他にどのような方法がありますか?残念ながら、git bareリポジトリについて見つけたドキュメントはかなり貧弱です。


8
@ Lavinia-Garbriela Dobrovol以下の複雑なものは使用しないでください。あなたはHEADを別のコミットに移動しようとしていますが、それは裸のリポジトリであってもgitリセットが意図されているものです。以下の私の答えに従って、以下を使用します。git reset --soft <commit> --softを使用すると、存在しない作業ツリーとインデックスを変更しようとしないので、gitを使用すると問題なくリセットできます。
ハゾク

回答:


130

git update-refコマンドを使用できます。最後のコミットを削除するには、次を使用します。

$ git update-ref HEAD HEAD^

または、最後のコミットを削除できないブランチにいない場合:

$ git update-ref refs/heads/branch-name branch-name^

必要に応じて、sha1を渡すこともできます。

$ git update-ref refs/heads/branch-name a12d48e2

git-update-refコマンドのドキュメントを参照してください。


@ Lavinia-Gabriela Dobrovolschi:そうです、私は正確な構文に精通していませんでした。
VonC、2011年

@VonC git update-ref <ref> <newvalue>たとえば、HEADの代わりに "refs / heads / master"のように、<ref>を正しいブランチに指定できます。私はあなたの質問を誤解していないことを望みます。
Lavinia-Gabriela Dobrovolschi、2011年

@シルヴァン:+1良い編集。@ Lavinia-Gabriela Dobrovolschiは精度に感謝します。これははるかに実用的です(リモートサーバーに直接アクセスできる場合、私はそう思います)。
VonC、2011年

3
例はbranch-name議論に関して誤解を招くものです。update-ref「ブランチ」で使用する場合は、ブランチの完全な参照名を必ず指定する必要があります(つまりrefs/heads/、通常の短いブランチ名の前に追加します)。短い名前だけを使用すると、最終的にの$GIT_DIR/branch-name代わりに作成/更新されます$GIT_DIR/refs/heads/branch-name。両方の存在branch-namerefs/heads/branch-name原因となります警告「もしrefnameは...あいまいです」。
Chris Johnsen、

この答えは、ザックが提案したものよりもはるかに複雑です。そして彼の解決策はうまくいきます。
クリスティアン

32

ベアリポジトリで以下を使用する場合:

git reset --soft <commit>

そうすれば、ベアリポジトリにないもの(つまり、作業ツリーとインデックス)を変更しようとしないので、ベアリポジトリで使用している問題--hard--mixedオプションにぶつかることはありません。あなたの場合、具体的には(裸のリポジトリから)使用したいでしょう:

git reset --soft HEAD^

リモートリポジトリのブランチ切り替えるには、次のようにします。

git symbolic-ref HEAD refs/heads/<branch_name>

現在選択されているブランチを表示するには:

git symbolic-ref HEAD

https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html


3
移動したいブランチをどのように選択しますか?あなたの例はマスターでgit checkout other_branchはうまくいきますが、ベアでは動きません。
Gauthier、2011

1
うーん...これに誰が投票したのかしら。質問は、リモートリポジトリでブランチを切り替える方法を尋ねたのではなく、ベアリポジトリでリセットする方法を尋ねました。リモートリポジトリのデフォルトブランチを変更するには、git symbolic-ref HEAD refs / heads / <branch_name>を使用します。
ハゾク2013年

7

git push -f罰金を動作するはずです:
あなたはその裸のレポのクローンを作成する場合は、最後のコミット削除(git reset --hard HEAD^(あなたが言及として、しかし、地元の非裸のレポで)とプッシュバック-f):

  • 削除するコミットの前にある他のコミットのSHA1は変更​​しません。
  • ベアリポジトリの正確なコンテンツから余分なコミットを差し引いたものを確実にプッシュバックします(最初にそれを複製しただけなので)。

@ VonCこんにちはVon、あなたはGitでたくさん答えるのを見たので、あなたに尋ねたかったのですが...興味津々でしたgit reset --soft <sha1>
ハゾク、

私が尋ねるもう1つの理由は、ベアリポジトリにソフトリセットを使用することはすぐに利用できる情報ではなく、多くのフォーラムでは、タイピングが最小限で、チャンスが少ないため、ソフトリセットがベストプラクティスであると思われる場合、不必要に複雑な回避策があるように思われるためです。エラーのため。
ハゾク

2
@Zach:reset --softベアリポジトリで直接実行すると機能するはずです。ベアリポジトリは通常アップストリームリポジトリ(つまり、データをプッシュするリポジトリ)であり、ほとんどの場合、直接ローカルアクセスできないため、これはめったに行われないと思います。しかし、そうした場合、これは確かに " reset --soft"の使用法のもう1つの良い例です(例:stackoverflow.com/questions/5203535/…)。そのため、答えを+1してください。
VonC、

2

git refspec表記を使用して、次のようなこともできます。

git push -f origin +<commit you want to revert to>:<destination_head | branch_name>

これにより、(refで示される)宛先ブランチが、+<object ref>パーツで示されるソースコミットに強制的に更新されます。


2
ブランチにACLがある場合を除いて-これは通常、「ベアリポジトリ自体でそれを行う必要がある」場合です...
David Schmitt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.