トップ画像イメージ

筆者の現職では未だにバージョン管理にsvnを多く使っていたりします。筆者も実務ではsvnばっかりだったので、今後のためもう一度gitの基本を勉強したのでまとめておきます。

メモっぽい内容になっていますが、ご容赦ください。

gitの特徴

  • gitはLinuxの生みの親が考えたシステム
    • それこそLinuxのプロジェクト中に使用中のバージョン管理システムが利用できなくなったので、使いやすいバージョン管理システム作ってまえ!みたいなノリで製作された?
  • gitのバージョン管理の構造
    • gitはファイルをスナップショットで保持する

    スナップショットとは、ある時点でのソースコードや、ファイル、ディレクトリ、データベースファイルなどの状態を抜き出したもののことです。

  • 前の世代のファイルから変わった箇所を記録するというよりも、変更されたファイル自体を圧縮して保管しておくイメージ(あくまでイメージですが)
    • gitはブランチでバージョン等を管理しているので、ブランチをマージしたりするとき、差分の計算をせずに、素早くマージすることができる。
  • 容易に元のバージョンに戻せる

サブバージョン(svn)との違いは?

  • gitは個々人のローカルのリポジトリ内容をリモートリポジトリに反映していく、分散型管理システム。サブバージョンは個々人がローカルリポジトリを持っておらず、gitでいうワークツリーのファイルをリモートリポジトリで集中管理するイメージ
    • svnだと、他の人の環境でも動くような、作業が終了したファイルしかコミット出来ない(勿論ブランチは切れるんだろうけどgitよりブランチを切るのもコストが大きいらしい)。
    • gitではローカルリポジトリでもブランチを切って管理でき、簡単にブランチを切り替えられるので、いつでも取りあえず動く状態に戻すことができる

gitの操作の流れ

  • まずローカルのリポジトリにスナップショットを記録する

  • 次にGitHubなどのリモートリポジトリに登録する

    • チーム開発でみんながアクセスでき、バージョンを管理する場所
  • 他人の履歴を取得するときには、Githubの記録を取得し、その変更の内容を自分のローカルリポジトリに反映する

  • gitの操作はローカルがほとんど

  • ローカルで出来たブランチをpullリクエストを出して、承認されたものをmasterブランチに反映させる

  • コミットとは、変更をスナップショットすること

  • ステージはコミットする変更を準備する場所

    • 一旦ステージに git add して、そのステージの状況をリポジトリに登録する
  • なんでわざわざ一回ステージを挟むのか?

    • 開発をしていると、複数のファイルをいじっていて、一方の変更は完了しているので、コミットできる状態。一方は変更が完了していないので、コミットできない状態とかになる。このとき変更が完了したファイルだけステージに追加する。
    • 要するに必要なファイルだけコミットできるように、ステージがある

gitのデータの持ち方

理解を促進するためにイメージを書いていますので、厳密に言えば間違っていることも多々あります

  • gitのリポジトリには、ファイルを圧縮して、ハッシュ関数で暗号化したものを持っている
  • ステージのインデックスに、この圧縮ファイルは●●ファイルのものだよーって記録する。(git add)
  • コミットすると、indexを元にツリーというファイルが作られる。これはindexを参考に、どの圧縮ファイルがどのファイルのものか記録する。また、indexとは別にコミットファイルというものを持っており、作成者、日付コミットメッセージなどの情報が含まれている。
  • コミットで圧縮ファイル・ツリー・コミットという3種類のファイルをリポジトリに追加する。
  • さらに別のファイルをコミットした場合、作られたコミットファイルに親のコミットファイル(直前のコミット)が記録される

gitで使うコマンドまとめ

git statusコマンド

  • git status でワークツリーと ステージの間、ステージとリポジトリとの間の変更されたファイルがわかる

git diffコマンド

  • git diffでワークツリーとステージ間のファイルの変更分を表示する
  • git diff --stagedでステージとリポジトリ間の差分を確認する

git logコマンド

  • git logでコミットの履歴や、情報が見れる
  • git log --onelineで1コミット1行にして情報が見れる
  • git log -n コミット数
    • 表示するコミットの数を指定して表示(直近何回ぶんのコミットか)
  • git log -p ファイル名
    • ファイルの変更差分を表示する

git rmコマンド

  • ファイルの削除を記録するときは
    • ワークツリーのファイルごと削除
      • git rm ファイル名 git rm -r ディレクトリ名
    • ファイルを残しておくけど、リポジトリから削除する
      • git rn --cahched

git mvコマンド

  • ファイルの移動を反映する
  • git mv 旧ファイル 新ファイル
  • git rm 旧ファイル gir add 新ファイルでも同じことができる

git configコマンド

  • git config --gloabal alias.ci commit
    • 色々あるけど、例えばコマンドに別名(アライアス)をつけることもできる。
    • 上ではcommitに ciという別名をつける
    • git ci index.html みたいに省略できる

git checkoutコマンド

  • ファイルへの変更を取り消す
    • ステージにaddされている情報をワークツリーに上書きするイメージ
  • git checkout --ファイル名
  • git checkout . 現在の階層以下のファイルとディレクトリをステージの状態と同じにする

git resetコマンド

  • ステージに追加した変更を元に戻したい時
  • git reset HEAD ファイル名
  • git reset HEAD ディレクトリ名
  • git reset HEAD .
    • 指定した変更をステージから取り消すだけなので、ワークツリーのファイルには影響を与えない
    • ワークツリーの変更も元に戻したければ、git reset HEAD .の後にgit checkout .
    • git resetではリポジトリに保存されている最新のコミットの状態を取ってきて、ステージに反映する

git commit -amend コマンド

  • git commit --amend
    • amend は 修正する・改正する という意味合い
  • 「あかん。コミットメッセージミスってもうた・・・」とかの時に、使う
  • 今のステージの状態をリポジトリに上書きする
  • 注意事項!!リモートリポジトリにPushしたコミットはやり直さない!!してしまうと、ローカルのgit履歴とリモートの履歴が違うことになるため、不整合が起きる

git fetchコマンド

  • git fetch リモート名
    • リモートリポジトリからコミット情報を、ローカルリポジトリに情報を落としてくる
    • git fetch origin
    • コミット情報をローカルリポジトリに反映させるだけなので、ワークツリーのファイルが変わるわけではない
    • ワークツリーにファイルの状態を反映したい時にはgit merge
    • 情報は remotes/というブランチに保存される

git pullコマンド

  • git pull
    • イメージ的にはgit fetch + git merge
  • リモートリポジトリから情報を取得して、マージまでを一気にやりたい時(ワークツリーにまで反映したい)
  • git pull origin master
    • git pullでも可
  • git pullの注意点
    • git pull今自分がいるブランチにmergeされる。
      • うっかり予期せぬブランチにマージしちゃうから要注意

ブランチとマージって?

ブランチ(枝葉)とは

  • 並行して複数の機能を開発するための仕組み
  • 機能ごとにブランチを作って、作成後に変更をマスターブランチに取り込む
  • HEADとは自分が作業しているブランチの最新のコミットのこと
  • ブランチの作成
    • git branch ブランチ名
      • ブランチを作成するだけで、ブランチの切り替えをするわけではない
    • git branch
    • git branch -a
      • リモートリポジトリも表示する

ブランチの切り替え

  • git checkout 既存ブランチ名
    • オプションを付けないと、既存のブランチの切り替えしかできない
  • git checkout -b 新ブランチ名
    • ブランチを新しく作って、切り替える
  • git checkoutをすることで、ブランチを切り替える。特定のブランチで追加したファイルやフォルダなども、それがコミットされていないブランチではプロジェクトフォルダには無い状態になっている。

ブランチのマージ

  • マージとは他の人の変更を自分のブランチに取り込む
  • git merge ブランチ名
  • git merge リモート名/ブランチ名
    • リモートリポジトリのブランチを取り込む
  • git merge origin/master
    • 作業中のブランチにマージする
  • mergeをしてできたコミットは、マージした複数のブランチを親として持つことになる

コンフリクト

  • 同じファイルの同じ行を複数人が弄ると、コンフリクト(衝突)が生じる
  • コンフリクトが起こった場合、どの変更を反映するのか、競合を解決する必要がある。

ブランチ名の変更

  • git branch -m ブランチ名(新しいブランチ名)
    • 今作業中のブランチの名前を変更する

ブランチの削除

  • git branch -d ブランチ名
    • -dは安全な削除。masterにマージされていない変更が残っている場合は削除しない
  • git branch -D ブランチ名
    • masterにマージしていない変更があっても、強制的に削除する

ブランチを使った開発の流れ

  • masterブランチをリリース用ブランチ、開発はトピックブランチを作成して進めるのが基本
    • masterで開発しないで、masterはマージするだけ
    • そうすればmasterブランチは常にリリースの状態に整えておける

コミットにわかりやすいタグをつける

  • コミットを参照しやすくするために、わかりやすい名前をつけるのがタグ。よくリリースポイントに使われる。
  • git tagでタグの一覧を見れる
  • タグには注釈付き版と軽量版がある
    • git tag -a タグ名 -m 'メッセージ名'
      • 注釈付き版
    • git tag タグ名
      • 軽量版(名前をつけるだけ)
    • git tag タグ名 コミット名
      • 昔のコミットに後からタグをつける
    • git show タグ名
      • タグのデータと関連づけられたコミットを表示する
  • タグをリモートに送信するにはgit push リモートリポジトリ名 タグ名
    • git push origin --tagsでローカルにあってリモートに存在しないタグを一斉に送信する

スタッシュ(作業中ファイル・フォルダの一時退避)

  • 作業途中でまだコミットできないけど、他のブランチで作業しなければならなくなったとき、作業を一時避難する
  • git stash git stash save
    • 一時避難
  • ワークツリー・ステージにある変更分をスタッシュに一時退避し、ファイルの変更が無かったことにする
  • git stash list
    • 避難させた作業の一覧を表示する
  • git stash apply
    • 最新の避難したスタッシュを復元
  • git stash applay --index
    • ステージの状況も復元する
  • git stash drop スタッシュ名
    • 最新の作業を削除する
  • git stash clear
    • 全作業を削除する