Git

【Git】ローカルリポジトリ チートシート(その2)

環境・事前準備

・macOS Ventura
GitHubの登録
・Gitのインストール
Homebrew:brew install git

本ページでは、ローカルリポジトリの応用的な処理についてまとめていきます。

Rebase

あるブランチのコミットを別のブランチの一連のコミット履歴として繋げることで、マージコミットを作成せずにブランチを統合できるようにする作業を「rebase」という。通常、作業用のブランチにmainブランチをrebaseした後にmergeする流れとなる。

rebaseにより既存のコミットは削除されてしまうため、push済みのコミットは、他の人がそのコミットで作業している可能性があるのでrebaseしないよう注意する(自身のコミットとリモートリポジトリのコミットが別物となってしまう)。

  • % git rebase <branch-name>:指定したブランチをアクティブブランチにrebaseする。
  • % git rebase --continue:rebase時にコンフリクトが発生した際、対処(直接ファイルを修正してコンフリクトを解消)後にrebaseを継続させる。
  • % git pull --rebase <remote_ref> <remote_branch>:pull時にmergeではなくrebaseをする。

Stash

Working directory及びStaging areaの作業内容を一時的に退避する処理を「stash」という。

また、一度stashした内容を元に戻すことを「apply」といい、この場合、全ての作業内容が(stash前はStaging areaにあったとしても)Working directoryに戻される(別のブランチに戻すことも可能)。

なお、stashは後に入れた内容を先に取り出す構造(「スタック」)を採用している。

  • % git stash:Working directory(track済みのファイルのみ)及びStaging areaの作業内容をstashする。untrackのファイルもstashする場合は「-u」オプションを使用する。gitignoreされているファイルもstashする場合は「-a」オプションを使用する。
  • % git stash save "<message>":stashする際にメッセージを添える。
  • % git stash list:stashした内容の一覧を表示する。
  • % git stash apply:stashした内容をapplyする。なお、stashの内容はそのまま残る。Staging areaにあった内容をStaging areaに戻す場合は「--index」オプションを使用する。apply時にWorking directoryに同内容の変更がある場合はエラーとなり、Staging areaに同内容の変更がある場合はコンフリクトとなる。コンフリクトが発生した際は、直接ファイルを修正してコンフリクトを解消する必要がある。「% git stash list」で表示されたレファレンス名(stash@{<number>})を指定することで特定のstashのみapplyすることも可能。
  • % git stash drop:stashから内容を削除する。レファレンス名(stash@{<number>})を指定することで特定のstashのみdropすることも可能。
  • % git stash pop:applyとdropを同時に行う。一番最新のstashがpopされる。レファレンス名(stash@{<number>})を指定することで特定のstashのみdropすることも可能。
  • % git stash show <reference_name>:特定のstashの内容を確認する。<reference_name>には、レファレンス名(stash@{<number>})を指定する。

tag

tagの付与と削除

  • % git tag <tag_name>:最新のコミットにラベルを付ける。通常、特定のコミットを特定のバージョンとして管理する場合に使用する。「% git show <commit_ID>」や「% git diff <base-commit_ID> <compare-commit_ID>」をする場合等、<commit_ID>の代わりにtagを指定することが可能。
  • % git tag -a <tag_name>:追加情報(アノテーション)を加えた上で、最新のコミットにラベルを付ける。デフォルトのエディタが起動するため、そこにRelease Note等の情報を記載する。「-m "<message>"」を追加することで、エディタを開かずに直接メッセージを追加することも可能。
  • % git tag -a <tag_name> <commit_ID>:追加情報(アノテーション)を加えた上で、特定のコミットにラベルを付ける。
  • % git tag --list:tagの一覧を表示する。
  • % git tag --delete <tag_name>:指定したtagを削除する。

tag情報をリモートリポジトリへpush

  • % git push <remote_reference> <tag_name>:指定のtag情報をリモートリポジトリにpushする(「% git push origin main」等ではtag情報はpushできないので注意)。全てのtag情報をpushする場合は<tag_name>の代わりに「--tags」オプションを使用する。
  • % git push <remote_reference> :<tag_name>:指定のtag情報をリモートリポジトリから削除する。

特定のtagにcheckout

  • % git checkout tags/<tag_name>:特定のタグに切り替える。
  • % git fetch --tags --all:タグ情報をローカルに取得する。

Submodule

submoduleの追加

Gitでは、プロジェクト(リポジトリ)の一部として別のプロジェクト(リポジトリ)を「submodule」として使用することが可能。プロジェクト間で共通して利用するようなプロジェクトをsubmoduleとして実装することが多い。

  • % git submodule add <submodule_url>:プロジェクトにsubmoduleを追加する。メインとなるプロジェクトからリモートリポジトリ(<submodule_url>)をsubmoduleとして追加することができる。追加後はsubmoduleフォルダと「.gitmodules」ファイルがStaging areaにできるのでコミットする。※この後、メインのプロジェクトをpullすると、リモートリポジトリ上でもメインのプロジェクトからsubmoduleへのリンクが追加される。

submoduleの初期化と更新

submoduleを含むプロジェクトをcloneした場合、submodule以下のフォルダやファイルはcloneされない。そのため、submoduleフォルダで、submoduleの初期化と更新をする必要がある。

  • % git submodule init:submoduleを初期化する。
  • % git submodule update:submoduleを更新する。
  • % git clone --recurse-submodules <remote_repository_url> :clone時に全てのsubmoduleの初期化と更新をする。

submoduleが更新された際の対処

メインプロジェクトのsubmoduleは、特定のコミットへのポインタであることから、最新のコミットを指しているわけではない。submoduleのポインタを最新のコミッタに更新する場合は、submoduleでpullする必要がある。

ただし、全てのsubmoduleに移動してpullしていくことは非効率なため、メインプロジェクトで以下のコマンドを使用することが多い。

なお、submoduleのpull(更新)がメインプロジェクトのWorking directoryに追加されるため、別途コミットする必要がある。

  • % git submodule foreach '<command>':全てのsubmoduleに対して<command>を実行する。「% git submodule foreach 'git pull origin main'」のように使用する。

RevertとReset

  • % git revert <commit_ID>:指定したコミットを打ち消す新規のコミット(「revert commit」)を作成することで、一つ前のコミットの状態に戻す。(Working directoryやStaging areaに作業内容がある場合は、破棄するかコミットしてからrevertすること。)
  • % git reset <commit_ID>:指定したコミットにHEADが移動し、以降のコミットは削除される。デフォルトでは、Working directoryの内容はそのままキープされ、Staging areaの内容は削除されるが、、オプションにより変更が可能(以下の表を参照。オプションはresetと<commit_ID>の間に挿入する)。
オプション Working directoryの内容 Stagint areaの内容
--soft keep keep
--mixed(デフォルト) keep reset
--hard reset reset