🫥

【脱初心者】これだけは覚えておきたいgitコマンド集

2024/09/18に公開

はじめに

こんにちは、hiro です。
先日 X でこのような投稿がありエンジニア界隈で大きな反響がありました。

https://x.com/newevoluouo/status/1830563785117229564

私自身この投稿に対して賛も否もないですが、git に関しては触ることができるに越したことはないと思うので記事を書こうと思いました。

今回は「脱初心者」をテーマに、普段何気なく使っているコマンドの便利なオプションなどを紹介しようと思います。

add関連

  • -Aまたは--all
    すべての変更(新規ファイル、変更されたファイル、削除されたファイル)をステージングエリアに追加します。

    $ git add -A
    $ git add --all
    
  • .(カンマ)
    現在のディレクトリ内のすべての変更をステージングエリアに追加します(新規ファイル、変更されたファイル、削除されたファイル)。

    $ git add .
    
  • -u または --update
    変更されたファイルと削除されたファイルをステージングエリアに追加しますが、新規ファイルは追加しません

    $ git add -u
    $ git add --update
    
  • -p または --patch
    変更をインタラクティブに選択してステージングエリアに追加します。変更の一部だけを選択することができます。

    $ git add -p
    $ git add --patch
    

commit関連

  • コミットメッセージのみをコミットする
    ブランチを作成した直後にテストコミットを行ったりする場合に使用したりします。
    通常であればステージングエリアに追加されたものがなければコミットできませんが、--allow-emptyオプションを使用することでステージングエリアが空でもコミットが可能になります。

    $ git commit --allow-empty -m "コミットメッセージのみ"
    
  • 直前のコミットの修正
    --amendオプションを使用することで、直前のコミットの修正が可能です。
    新しいコミットを作成し、直前のコミットを修正します。
    コミットメッセージの修正や、直前のコミットをやり直したい時に使用します。

    # コミットメッセージを修正したいとき
    $ git commit -m "誤字を含むコミット"
    $ git commit --amend -m "正しいコミット"
    
    # add 忘れがあった時
    $ git add A.txt
    $ git commit -m "fix: A及びBファイルの修正" # Bの追加を失念
    
    $ git add B.txt
    $ git commit --amend -m "fix: A及びBファイルの修正"
    
    # 上記の様に同様のコミットメッセージを流用する場合は以下でも可
    $ git commit --amend --no-edit
    

push関連

push する際毎回以下の様に push するブランチを指定していませんか?

$ git push origin feat/login

確かに push 先を明示することで誤ったリモートブランチにプッシュすることは避けられますが、作業ブランチと異なるリモートブランチに push するような機会はほとんどないかと思います。

それを避けるために-uオプションを使用することで楽に push,pull ができるようになります。

$ git push -u origin feat/login
$ git push --set-upstream origin feat/login

# 次回からはブランチの指定が不要になる
$ git push  # origin feat/login にプッシュ
$ git pull  # origin feat/login からプル

-uオプションはリモートブランチとの追跡関係を設定するために使います。
このオプションのおかげで上記の様にpush,pullの際にブランチを指定する必要がなくなります。

https://git-scm.com/docs/git-push#Documentation/git-push.txt--u

ブランチ関連

ブランチの作成

branchコマンドで新規ブランチを作成する方法もありますが、今回はより効率的に、**「ブランチを作成しつつ、作成したブランチに移動する」**というシチュエーションを前提に紹介します。

今まではcheckoutコマンドに-bオプションを使用することでブランチの作成と移動を同時に行っていました。
しかしcheckoutにはブランチの切り替えと別に、作業ツリーファイルの復元という機能も持ち合わせています。

git2.23 からswitchというブランチの切替用のオプションが追加されたことにより、機能が分離され、より分かりやすくなりました。

# 今までの書き方
$ git checkout -b [作成するブランチ名]

# モダンな書き方
$ git switch -c [作成するブランチ名]
$ git switch -C [作成するブランチ名] # 同名のブランチが存在していたら強制的に上書き

リモートリポジトリに存在するブランチをローカルリポジトリに反映させる

リモートリポジトリにはあるけど、ローカルリポジトリには無いブランチを取得します。
例えば別のメンバーが作成したリモートブランチを自分のローカルリポジトリに反映させたいときに使用します。

$ git fetch --all

ブランチの削除

ローカルブランチの削除

-dオプションは削除対象のブランチがリモートブランチにプッシュおよびマージ済みの場合のみ削除を実行します。プッシュ、マージされていないブランチを強制的に削除したい場合は、代わりに -D を使用します。

# syntax
$ git branch -d <ブランチ名>
$ git branch --delete <ブランチ名>

# example
$ git branch -d feat/login  # feat/login ブランチの削除
$ git branch -D feat/login  # 強制的に削除

リモートブランチの削除

# syntax
$ git push <remote> --delete <branch>
$ git push <remote> :<branch>  # shorthand

# example
$ git push origin --delete feat/login  # feat/login ブランチの削除
$ git push origin :feat/login

ゾンビ化したリモートブランチの削除

リモートリポジトリ上で直接ブランチを削除すると、存在していないはずのリモートブランチがローカルで存在していることになってしまいます。

$ git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
  remotes/origin/deleted_branch

そういう時はremote pruneで解決できます。

$ git remote prune origin

$ git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main

修正関連

reset

resetコマンドは、間違えてadd,commitしてしまった時に使用する緊急対応用のコマンドです。
commit --amendに似ていますが、commit --amend直前のコミットを上書きするのに対して、reset

  • 特定のコミットに戻る
  • ステージングエリアの変更を取り消す
  • 作業ディレクトリ(ワーキングツリー)の変更を元に戻す

などを実現でき、使用するオプションによって挙動が異なります。

よく使うオプションを紹介します。

・コミットのみを取り消す--soft

# HEAD^ で直前のコミットのみを取消
$ git reset --soft HEAD^

--softは HEAD(最新のコミット)の位置のみを移動します。
つまりcommitだけが取り消され、ワーキングツリーやaddの状態はそのままです。

・ステージングエリアへの追加の取消&コミットを取り消す--mixed

# オプションを指定しない場合 --mixedと同様の挙動になる
$ git reset HEAD^
$ git reset --mixed HEAD^

--mixedは HEAD の位置の移動及びステージングエリアへの追加を取り消します。
つまりcommit及びaddした内容が取り消されます。
ワーキングツリーの変更は取り消されないので、作業した内容は消えません。

・全てを無かったことにする--hard

$ git reset --hard HEAD^

--hardcommit,add,作業内容の全てを取り消します。
--hardで取り消した内容は基本的には復元できないので注意して使用する必要があります。

resetを取り消す

間違えてgit resetしてしまった場合にも対処法があります。

  • 直前のresetを取り消す

    $ git reset --hard ORIG_HEAD
    
  • 特定のresetを取り消す

    # HEADが辿ってきた履歴を確認
    $ git reflog  # ハッシュ値を確認する
    
    $ git reset [オプション] [ハッシュ値]
    

stash

stashはワーキングツリーの内容を一時退避させるためのコマンドです。
実際に私が経験したユースケースとしては、

  • 作業してはいけないブランチで作業してしまった
  • 作業中だけど新しくブランチを切って作業したい、けど中途半端だからコミットはしたくない

というパターンです。
見出しの「修正関連」とは直接関係なさそうですが、前者の様に誤ったブランチで作業してしまった場合の救済措置として使用できるので、「修正関連」として紹介させていただきます。

変更を退避する

$ git stash save # saveは省略可

# 新規作成ファイル(追跡対象に含まれていないファイル)も退避
$ git stash -u

# メッセージ付きで退避させる
$ git stash save '○○の機能実装中'

退避した内容を確認する

$ git stash list
  stash@{0}: On feat/login: ○○の機能実装中
  stash@{1}: On commit-sample: xxxx

退避した内容を復元する

# stash名を指定して復元
$ git stash apply stash@{0}

stash@{0} の stash 名は省略することもできます。省略した場合は、直近に stash した情報が復元されます。

最後に

最後までご覧いただきありがとうございます。
今回は冒頭でも申し上げた通り、【脱初心者】に向けて役に立ちそうなコマンドを紹介しました。

特に初心者のうちは git は敬遠しがちですが、慣れてしまえば仕事で使う上では困らないレベルまですぐに到達できると思います。

git を怖がらずに沢山触って「やばい」って言われないように日々頑張りましょう。

Discussion