【Git】コマンドスニペット(随時更新)

git pull

git pullコマンドは、リモートリポジトリから最新の変更を取得し、現在のローカルブランチに統合するための重要な操作です。--rebaseオプションを付けるかどうかで統合方法が異なります。

概要

git pull origin master

git pullは、次の2つのステップで構成されます。

  1. フェッチ (fetch):リモートリポジトリから最新のコミットをローカルに取得します。
  2. 統合 (merge/rebase):フェッチしたコミットを現在のローカルブランチに統合します。

git pullを引数なしで実行すると、現在のブランチに設定されている追跡リモートブランチからフェッチし、マージします。

git pull

マージ (merge) とリベース (rebase)

git pullの統合方法は、マージ (merge) とリベース (rebase) の2種類があります。

マージ (デフォルト)

リモートの変更をフェッチし、ローカルブランチにマージします。また、新たにマージコミットが生成されます。

git pull --no-rebase
# --no-rebase オプションは省略可能
  • 履歴にマージコミットが残る:マージによって新しいマージコミットが作成されるため、履歴に「マージした」という記録が残ります。
  • 履歴の複雑化:マージコミットが多くなると、履歴が複雑に見えることがあります。特に、複数人での共同開発ではこの傾向が強まります。
  • コンフリクト解決:マージ中にコンフリクトが発生した場合、手動で解決する必要があります。

リベース

リモートの変更をフェッチし、ローカルの変更をリモートの最新の変更の上にリベースします。また、履歴が直線的になります。

git pull --rebase
  • 直線的な履歴:リベースによってコミット履歴が直線的になり、読みやすくなります。
  • 履歴の書き換え:リベースは履歴を書き換えるため、公開済みのブランチでの使用は注意が必要です。
  • コンフリクト解決:リベース中にコンフリクトが発生した場合も手動で解決する必要があります。コンフリクトは各コミットごとに発生します。

どちらを使うべきか

マージを選ぶ理由

  • 履歴をそのまま残したい:誰がどの時点で変更をマージしたかを記録しておきたい場合に有効です。
  • チームでの共同開発:マージによって履歴がそのまま残るため、複数人が同時に開発しているプロジェクトでは、変更履歴が明確になります。

リベースを選ぶ理由

  • 直線的な履歴を好む場合:履歴が直線的で、シンプルな方が望ましい場合に有効です。特に個人の作業ブランチで役立ちます。
  • 公開されていないブランチでの使用:履歴が書き換わるため、個人の作業ブランチや一時的なブランチでの使用に向いています。

git merge

git merge

git mergeコマンドは、2つのブランチを統合します。基本的には、現在のブランチに指定したブランチの変更を統合します。

特徴

  • マージが完了すると、新しい「マージコミット」が作成され、統合された内容が記録されます。
  • Gitが自動的に競合を解決できる場合もあります。

ユースケース

  • 開発が完了したfeatureブランチをmainブランチやmasterブランチに統合する場合。
  • 複数の開発ブランチを統合する際に使用。

コマンド

git checkout main
git merge feature-branch

git merge --no-ff

--no-ffオプションを使用すると、Fast-Forwardマージを無効にし、必ずマージコミットを作成します。

特徴

  • Fast-Forwardマージを防ぎ、必ずマージコミットが作成されます。
  • マージの履歴を明示的に記録できます。

ユースケース

  • 開発履歴を分かりやすく保つために、マージコミットを残したい場合。
  • 大規模な変更や機能追加を行った場合に、マージの際にその変更を明確にするため。

コマンド

git checkout main
git merge --no-ff feature-branch

git merge --squash

--squashオプションを使用すると、マージ対象のブランチの変更を1つのコミットとして現在のブランチに統合します。

特徴

  • マージ対象のブランチのすべてのコミットを1つのコミットにまとめることができます。
  • スクワッシュコミットによって、履歴がシンプルに保たれます。

ユースケース

  • featureブランチで多くの小さなコミットを行ったが、mainブランチには1つのまとまったコミットとして統合したい場合。
  • レビューやデプロイの際に、履歴をシンプルに保ちたい場合。

コマンド

git checkout main
git merge --squash feature-branch
git commit -m "Merged feature-branch"

git merge --strategy

--strategyオプションを使用すると、マージ時の戦略を指定できます。recursive,ours,theirsなどの戦略が用意されています。

特徴

  • 競合解決の方法をカスタマイズできます。
  • 特定の状況に応じて、どのようにマージを行うかを指定できます。

ユースケース

  • 特定の戦略を使って競合を解決したい場合。
  • 特定のマージ戦略が必要な状況で使用します。

コマンド

git checkout main
git merge --strategy=ours feature-branch

git merge --no-commit

--no-commitオプションを使用すると、マージを行っても自動的にコミットはされません。手動でコミットする必要があります。

特徴

  • マージの内容を確認し、手動でコミットできます。
  • マージ後の変更を確認し、調整が可能です。

ユースケース

  • マージ後に変更内容を確認し、手動でコミットしたい場合。
  • マージの結果に対してさらに変更を加えたい場合。

コマンド

git checkout main
git merge --no-commit feature-branch

# 変更を確認し、調整
git commit -m "Manually merged feature-branch"

まとめ

  • git merge: 標準のマージ方法、履歴を保つ。
  • --no-ff: マージコミットを必ず作成、履歴を明示化。
  • --squash: 変更を1つのコミットにまとめる、履歴をシンプルに。
  • --strategy: マージ戦略を指定、競合解決のカスタマイズ。
  • --no-commit: マージ後に自動コミットを行わない、手動で確認。

ブランチの切り替え

別のブランチに切り替える際に使うコマンドは、git switchgit checkoutの2つがあります。

git switch

このコマンドは、ブランチを切り替えるためのシンプルで直感的な方法です。

既存のブランチに切り替え

git switch <ブランチ名>

新しいブランチを作成してそのブランチに切り替え

git switch -c <新しいブランチ名>

git checkout

git checkoutもブランチを切り替えるために使えますが、それに加えてファイルのチェックアウト(ファイルを特定のコミットの状態に戻す)も行えます。

既存のブランチに切り替え

git checkout <ブランチ名>

新しいブランチを作成してそのブランチに切り替え

git checkout -b <新しいブランチ名>

補足: git switch と git checkout の違い

機能の範囲

  • git checkoutは、ブランチの切り替えだけでなく、ファイルを特定の状態に戻す操作にも使われます。多機能ですが、混乱を招く可能性があります。
  • git switchはブランチの切り替え専用で、ブランチ操作に特化しています。

新しいGitでの推奨

git switchはGitの新しいバージョンで追加されたコマンドで、ブランチの切り替えをよりシンプルに行うために推奨されています。

ブランチ名の変更

ブランチ名を変更するには、以下の手順を行います。

現在のローカルブランチ名を変更

git branch -m <新しいブランチ名>

例えば、mainブランチの名前をdevelopに変更する場合は以下のコマンドを実行します。

git branch -m develop

別のローカルブランチ名を変更

git branch -m <古いブランチ名> <新しいブランチ名>

リモートブランチ名を変更

リモートにある古いブランチ名を削除し、新しいブランチ名をプッシュします。

新しいブランチ名をリモートにプッシュ

git push origin <新しいブランチ名>

古いブランチ名をリモートから削除

git push origin --delete <古いブランチ名>

トラッキングの設定(もしリモートブランチと連携している場合)

git push --set-upstream origin <新しいブランチ名>

子ブランチに親ブランチの変更を取り込む

状況

featureブランチで開発を行っている途中に親ブランチであるmasterブランチに変更が発生したので、featureブランチにmasterブランチの変更を取り込みたい状況です。

○ = Commit
◎ = HEAD

○ -- ○ -- ○ ------ ○        (master)
            \
              ○ -- ○ -- ◎   (feature)

手順

# 親ブランチに切り替える
git switch master

# 親ブランチを最新状態にする
git pull origin master

# 子ブランチに切り替える
git switch feature

# 子ブランチに親ブランチをマージ
git merge master

コミットの取り消し

通常のコミットの取り消し

git revert

git revertコマンドを使うと、特定のコミットを取り消す新しいコミットを作成します。履歴を保持しつつ、変更を打ち消すことができます。

git revert <コミットハッシュ>

git reset

git resetコマンドを使うと、特定のコミットまでの状態にリセットできます。以下のオプションがあります。

--soft

コミットを取り消しても、作業ツリーとステージングエリアはそのままにします。

git reset --soft <コミットハッシュ>

--mixed (デフォルト)

コミットを取り消し、ステージングエリアを更新しますが、作業ツリーはそのままにします。

git reset --mixed <コミットハッシュ>

--hard

コミットを取り消し、作業ツリーとステージングエリアもその状態にリセットします。データが失われる可能性があるため、注意が必要です。

git reset --hard <コミットハッシュ>

git checkout

git checkoutコマンドを使って、特定のファイルや状態をコミットの状態に戻すこともできます。

git checkout <コミットハッシュ> -- <ファイル名>

マージコミットの取り消し

マージコミットの取り消しには、次の方法があります。

git revert

マージコミットを取り消す場合、-mオプションを使ってどの親を基準にするかを指定します。通常、-m 1を指定して、最初の親を基準にします。

git revert -m 1 <マージコミットハッシュ>

例えば、以下のようなブランチ構造の場合を考えます。

○ = Commit
◎ = HEAD

○ -- ○ -- ○                    (master)
            \
              ○ -- ◯           (develop)
                    \
                      ◯ -- ◎   (feature)

featureブランチに最初の親ブランチであるdevelopブランチをマージしたコミットを取り消すには-m 1を指定し、さらに親ブランチであるmasterブランチをマージしたコミットを取り消すには-m 2を指定します。

git reset

マージコミットを含むコミットをリセットする場合もあります。リセットオプションに注意して使う必要があります。

--soft

コミットを取り消し、変更をステージングエリアに残します。

git reset --soft <マージコミットの前のコミットハッシュ>

--mixed

コミットを取り消し、ステージングエリアを更新します。

git reset --mixed <マージコミットの前のコミットハッシュ>

--hard

コミットを取り消し、作業ツリーとステージングエリアもその状態にリセットします。

git reset --hard <マージコミットの前のコミットハッシュ>

git reflog

リセット後に元の状態に戻したい場合、git reflogで以前の操作履歴を確認し、必要な状態に戻すことができます。

git reflog

補足:revertとresetの違い

git revert

git revertは、特定のコミットの変更を打ち消す新しいコミットを作成します。履歴はそのまま保たれ、新しいコミットが追加されます。

git revert <コミットハッシュ>

すでにリモートに公開されたコミットを取り消す場合に使用します。履歴を変更せず、新しいコミットを追加するため、安全に取り消すことができます。

例えば、ローカルで行ったコミットをリモートに公開した後に、そのコミットが不要だとわかり取り消したい場合、git revertを使用します。

git reset

git resetは、特定のコミットまで履歴を戻します。--soft/--mixed/--hardの3つのオプションがあります。

--soft

コミットを取り消し、ステージングエリアと作業ツリーはそのままにします。

git reset --soft <コミットハッシュ>

--mixed (デフォルト)

コミットを取り消し、ステージングエリアをリセットしますが、作業ツリーはそのままにします。

git reset --mixed <コミットハッシュ>

--hard

コミットを取り消し、作業ツリーとステージングエリアもその状態にリセットします。

git reset --hard <コミットハッシュ>

ローカルでの作業中に誤ったコミットを取り消し、履歴を変更する場合に使用します。公開リポジトリに影響を与えないため、主にローカルで使います。また、複数のコミットをまとめて修正したい場合や、履歴から不要なコミットを削除したい場合に使用します。

例えば、誤って複数のコミットを行ってしまった場合、--softを使って最近のコミットを取り消し、変更を再調整します。大きな変更を取り消し、履歴を完全にリセットしたい場合に --hardを使用します。

使い分けのポイント

  • すでに他の人が作業しているリモートリポジトリに対しては、git revertを使用して、新しい変更を追加することで安全に取り消します。履歴はそのままで、新しいコミットを追加するため、チーム全体に影響を与えません。
  • ローカルで作業している場合、履歴の編集や複数のコミットの修正を行うためにgit resetを使用します。特に、--hardオプションは作業ツリーとステージングエリアを完全にリセットするため、作業中の変更が失われる可能性があります。注意して使用してください。

関連記事

【Git】マージにおけるfast-forwardとnon-fast-forwardの違い
# はじめに Gitにおけるマージには、fast-forwardとnon-fast-forwardの2種類があります。これらの違いを理解することは、Gitの使い方を習得する上で重要です。本記事では、fast-forwardとnon-fast-fo [...]
2023年2月17日 13:42