KEIS BLOGは株式会社ケイズ・ソフトウェアが運営しています。

KEIS BLOG

Git Reset コマンドの役割とオプションの違い


Git Reset コマンドの役割とオプションの違い

Gitは、ソフトウェア開発において最も広く使用されているバージョン管理システムの一つです。今回は、Gitでよく使用されるgit resetコマンドに焦点を当て、その基本的な使い方とオプションについて解説します。

git reset コマンドって何をするコマンド?

git resetはGitの非常に多用されるコマンドの一つであり、その動作はオプションや指定されたコミットによって異なります。基本的には、このコマンドは現在のブランチのHEAD(最新のコミット)を指定されたコミットに移動する役割があります。このコマンドを使って、特定のコミットまで履歴を「巻き戻したり」、ステージングエリア(インデックス)やワーキングディレクトリの変更を取り消すことができます。

主なオプション

  • –soft: 指定したコミットまでHEADを移動しますが、ステージングエリア(インデックス)とワーキングディレクトリはそのまま保持します。
  • –mixed (デフォルト): 指定したコミットまでHEADを移動し、ステージングエリア(インデックス)もそのコミットの状態に更新しますが、ワーキングディレクトリは変更しません。
  • –hard: 指定したコミットまでHEADを移動し、ステージングエリア(インデックス)とワーキングディレクトリもそのコミットの状態に完全に戻します。

soft と mixed の違いは?

git reset コマンドの --soft--mixed オプションの違いは、ステージングエリア(インデックス)にどのような影響を与えるかにあります。

–mixed

このオプションを使うと、元々のHEADから指定したコミットまでの変更差分はステージングエリアから削除されますが、ワーキングディレクトリにはその差分がそのまま残ります。git reset したい場合って、普通ワーキングエリアに差分を戻したいと思いますし、git add すればステージングエリアに入れることが出来る事も考えると、大体の場合、オプション無しで使う(–mixed を指定したのと同じ)と覚えておけば良さそうです。

git add して、git commit したものが全部ワーキングエリアに戻りますので、
わりとわかりやすいし、思い切り前のコミットを指定して reset したりしない限りはそんなに危険の無い操作です。

直前のコミットの取り消しは、


git reset HEAD^

でOKという事ですね。修正したものが失われる事は無く、git add する前の状態に戻ってくれます。

–soft

このオプションを使うと、ステージングエリアには元々のHEADから指定したコミットまでの変更差分がそのまま残ります。この状態で git commit を実行すると、その差分を持つ新しいコミットが作成されます。

このオプションを使う状況って、あんまり無いような気がします。
オプション無しで reset 使うと、–mixed ですが、基本的に –mixed でいいから
デフォルトがこれになってるんだと思います。あえて使い分けるとすると、部分的にステージして、コミットしたものをステージに戻したいだけ、ワーキングエリアにはステージされてないのがたくさんあるので混ざってほしくない・・・という状況だと思いますが、わかって使い分ける分にはいいと思いますが、ややこしい気がします。

–mixed(オプション無し)で使うほうが大体の用途には合ってる気がします。

説明の仕方をちょっと変えると、
・git commit を取り消したい時は reset –soft
・git commit & git add を取り消したい時は reset (–mixed)
という言い方でもOKです。いずれも変更内容が失われることはなく、
ステージングかワーキングエリアに戻ります。

hard の使いどころは?

一方で hard の方は、「積み上げたコミットをばっさり消して過去の状態に戻りたい」という時以外では、「あるブランチの向き先を既存のコミットにしたい」という用途が考えられます。「ん?」という感じですかね。

「あるブランチの向き先を既存のコミットにしたい」という場合、「あるブランチ」がまだ存在しないなら、素直にやるなら、

  
    git checkout 8d496132fb8a69372a43a2277fc06b4d325c70e6
    git checkout -b [あるブランチ]
  

ですね。「あるブランチ」が存在する場合、素直にやるなら、

  
    git checkout 8d496132fb8a69372a43a2277fc06b4d325c70e6
    git branch -D [あるブランチ]
    git checkout -b [あるブランチ]
  

じゃないかと思います。消して作り直す、という事ですね。
で、結局これと同じことを reset –hard で実現出来ます。

  
    git checkout [あるブランチ]
    git reset --hard 8d496132fb8a69372a43a2277fc06b4d325c70e6
  

これは破壊的な操作です。そのため、このコマンドを使用する前に、他の誰もそのブランチを使用していないか確認することが重要です。

この操作はローカルのリポジトリで行われるので、同じ変更をリモートリポジトリに反映させる場合は、git push -f(強制プッシュ)が必要です。ただし、これも破壊的な操作なので、他の開発者に影響を与えないか注意が必要です。

これも「いつ使うの?」とおもわれそうなオプションですが、これについては、要するに「ブランチを指定のコミットIDに向ける」というオプションです。そういう状況ってたまにありますので、他の方法で代替も可能ですが、これが一番直接的に実現できる場合があります。

以上、それぞれのコマンドの使い道をまとめてみました。ご参考になれば幸いです。