kent備忘ログ

お仕事と趣味生活と

Gitの仕組みと基本コマンドについて

ファイルのバージョン管理や、チーム開発環境の場において必須となっているGit その概要と各種コマンドについて学習したので記事にしました。

Gitのデータ構造:Gitはファイルを圧縮して、その時点のファイル情報をスナップショットとして保持する。

構造
リポジトリ 圧縮ファイル, ツリーファイル, コミットファイル
ステージ インデックス
ワークツリー 作成した各種ファイル・ディレクト
ファイルの種類 (Gitオブジェクト)
圧縮ファイル 圧縮されたワークツリーで作成したファイル
インデックス 圧縮ファイルの一覧をマッピング
リーファイル インデックスに記載されているマッピング情報を表示
コミットファイル リーファイル情報, 親コミット名, 作成者, 日付, コミットメッセージを記載
  • 圧縮ファイル (blobオブジェクト) :オブジェクト名はハッシュIDで記録される
  • リーファイル (treeオブジェクト) :中身は一つのファイルに一つの圧縮(blob)オブジェクトが対応、一つのディレクトリに一つのツリー(tree)ファイルが対応しており、圧縮ファイルの情報と、圧縮ファイルの構造情報を保持している。
  • コミットファイル (commitオブジェクト) :ファイル構成のスナップショット、それが時系列順に連なる
  • git add <ファイル名>で圧縮ファイルとインデックスを作成
    (ファイルの変更を記録する動作であるコミットの準備、ステージングエリアという)
    ステージにあるインデックスファイルは変更のあったファイル情報が 上書き で保存される
    (git addするたびに都度都度 複数のインデックスが作成されるわけではない )
  • git commit [オプション]でツリーファイルとコミットファイルを作成
  • git push <リポジトリ名> <ブランチ名> コミット内容をリモートリポジトリに送信

ファイルへの変更を取り消す

  • ワークツリーの変更を取消し
  • git checkout --<ファイルorディレクトリ名> (全変更を取り消すには.を指定)
    ステージ上のインデックスを参照して、ワークツリーに反映させる
    ステージした変更を取り消し
  • git reset HEAD <ファイルorディレクトリ名> (全変更を取り消すには.を指定)
    リポジトリの最新のコミットを参照して、ステージに反映させる
    (ワークツリー上のファイルには何ら変更を加えないので注意)
  • 直前のコミットした変更を取り消し
  • git commit --amend ステージ上のインデックスを参照してコミットに反映し直す
    (リモートリポジトリにpushする前のコミット限定)

管理しないファイルをGitの管理から外す

  • .gitignoreファイルに記載

リモートリポジトリ

  • git remote [オプション] リモートリポジトリを表示
    • -v 対応するURLを表示
  • git remote show <リモート名> リモートの詳細情報を表示
  • git remote rename <旧リモート名> <新リモート名> リモートリポジトリ名を変更
  • git remote rm <リモート名> リモートリポジトリの削除
  • git remote add <リモート名> <リモートURL> リモートリポジトリを追加
  • git fetch <リモート名> リモートリポジトリからローカルリポジトリに情報を取得
  • git pull <リポジトリ名> <ブランチ名> リモートから情報を取得してワークツリーに反映
    リモートブランチの情報が、今いるローカルブランチに強制統合される

ブランチとマージ

  • ブランチはコミットIDを指したポインタ(基本は最新のコミットファイル)
  • コミットしたらブランチガスコミットファイルが変わる
  • HEADは現在のブランチを指したポインタ
  • リモートブランチはリモートリポジトリのブランチの状態へのポインタ
  • git switch -c <ブランチ名> ブランチの新規追加( 旧 git branch)
  • git branch [オプション:-a 全てのブランチ] ブランチの一覧表示
  • git checkout <既存ブランチ名> ブランチの切り替え(HEADが移動)
  • git merge <ブランチ名> 他のブランチの変更をマージ
    • Fast Forward 早送りになるマージ:ブランチの内容が枝分かれせず、ポインタを前に進めただけ
    • Auto Merge 基本的なマージ:二種類のブランチファイルを一つに統合するマージコミットを作成(親コミットが二つ)
  • git swith <ブランチ名> ブランチを変更(旧 git branch -m)
  • git branch -d <ブランチ名> ブランチを削除

プルリクエス

  1. mainブランチとは別のブランチでファイルの変更、その後Githubにプッシュ
  2. Github上でプルリクエストを送る
  3. コードレビューを受けた後、Github上でmainブランチにマージを行う

GitHub flow

GitHub推奨の開発フローの基本となる考え方
  1. ファイル変更の際はmainブランチから作業ブランチを切る
  2. 変更完了したらGitHubへプッシュしてプルリクエストを送る
  3. コードレビュー完了後、mainブランチへマージ、本番環境へデプロイ
  4. mainブランチは常にデプロイできる状態にする
  5. 新開発はmainブランチから新しいブランチを作成して作業

リベース

リベースで履歴を整えた形で変更を統合
1. 履歴を明確に残したい場合はマージを使用(マージは履歴が複雑化する)
2. 履歴を綺麗にしたい場合はリベースを使用(リベースはコンフリクトの解消が面倒)

プッシュしていないローカルの変更にはリベースを使用
プッシュした後、コンフリクトしそうならマージを使用

  • git rebase <ブランチ名> ブランチの起点となるコミットを別のコミットに移動
    他のブランチの変更分を自身に取り込みながら、枝分かれしていたコミットの履歴を綺麗に一本戦にする事ができる
  • マージコマンドは変更分を取り込むだけ、リベースコマンドは変更分とコミット履歴を取り込む
  • コマンドはリベース元のブランチに移動してから使用、リベース後、リベース先のブランチでマージを行うと先にリベースで出来た子コミットに、リベース先のブランチがファストフォワードする
  • GitHub上にプッシュしたコミットをリベースするのはNG(履歴が改変されてしまい、プッシュできなくなる)
  • git push -f (強制プッシュ)をするとリモートリポジトリの履歴が破壊される

  • git pullの種類(マージ型とリベース型)

    • git pull <リモート名> <ブランチ名> マージコミットが残るマージ型(挙動はfetch/merge)
    • git pull --rebase <リモート名> <ブランチ名> マージコミットが残らないリベース型(挙動はfetch/rebase)

過去のコミットの修正

  • git rebase -i <コミットID> 複数のコミットの修正
  • git rebase -i HEAD~n n番目の親(世代) コミットを起点としてそれ以降のコミットを 修正
  • git rebase -i HEAD ^n (マージした場合)複数の親コミットの内、n番目の親を指定して修正
  • 各コミットのうち修正したいコミットをpickからeditに変更する(修正画面のコミット順はgit logとは逆の並びになっている)
  • editに変更したコミットに、git commit --amendを適用し、ステージからの変更内容を該当のコミットに取り込む
  • 取り込み完了後、git rebase --continueで次のコミットへ
  • コミットを 削除 したい場合は-i の編集画面で行を削除
  • コミット順を 入替え たい場合は-i の編集画面で行を並び替え
  • コミットを まとめる 場合は、対象のコミットのpickをsquashに変更することで、直前のコミットとまとめる事ができる
  • コミットの 分割 したい場合は-i の編集画面で対象のコミットをpickからeditに変更、その後git reset HEAD^ コマンドでgit add とgit commitを取り消す
    (コミットを取り消して、ワークツリーのファイルをステージングしていない状態にまで戻す)
    その後git add とgit commitを分割して行う

タグ (主にリリースポイントのコミットにつける)

  • git tag タグの一覧を表示
    • -i パターンを指定してタグを表示
  • git tag -a <タグ名> -m "メッセージ" 注釈付きタグを作成(名前・コメント・署名を記載できる)
  • git tag <タグ名> 軽量版タグを作成
  • git tag <タグ名> <コミット名> 過去のコミットに後からタグ付けする
  • git show <タグ名> タグのデータを表示
  • git push <リモート名> <タグ名> リモートリポジトリにタグを送信
  • git push <リモート名> -tags リモートリポジトリにタグを一斉送信

スタッシュ (作業を一時避難させる)

  • git stash 作業した変更分をstashに一時 避難 させる
  • git stash list 避難させた作業の一覧を表示
  • git stash apply 避難させた最新の作業を 復元 させる
  • git stash apply --index ステージの状況も復元させる
  • git stash apply <スタッシュ名> 特定の作業を復元させる
    スタッシュのナンバリングは最新のスタッシュが@0となり、
    過去に遡るにつれ番号が増加
  • git stash drop 最新の作業を削除
  • git stash drop <スタッシュ名> 特定の避難作業を削除
  • git stash clear 全ての避難を削除

その他コマンド解説

  • git status
    ワークツリーとステージの変更内容を表示(ステージ上のインデックスの情報とワークツリーのファイルを比較)
    ステージとリポジトリの変更内容を表示(コミットファイルのスナップショットとインデックスの情報を比較)
  • git diff [オプション] <ファイル名> ステージに追加する前のワークツリーとステージの変更分
  • git log 変更履歴を確認する
    • -oneline 1行で表示
    • -p ファイルの変更差分を表示
    • -n <コミット数> 表示するコミット数を制限
  • git rm [オプション] <ファイル名 or ディレクトリ名> ファイルの削除を記録(デフォルトではファイルごと削除)
    • cached ファイルを残したい時に指定
  • git mv <旧ファイル> <新ファイル> ファイルの移動(リネーム等)を記録