Git 備忘録

2016-07-31   (Updated : 2019-05-15)

Git の中身を詳しく知りたい人に説明する時のメモ

  • 時間があるなら Pro Git を読めば OK
  • Git は分散型 VCS
    • (SVN とか Perforce はみんなが中央サーバにアクセスする集中型
    • 各自のマシンにリポジトリのクローンが作られる
  • リポジトリとは .git/ があるディレクトリのこと
  • 差分の蓄積ではなくスナップショットを保存して歴史を管理
    • あらゆるスナップショットやコミットオブジェクトなどにダイジェスト (SHA-1 ハッシュ) がついてる

  • ファイルのとりうる状態
    • Untracked / Unmodified / Modified / Staged
    • (Stash) / Workspace / Stage / Local Repo. / ……… / Remote Repo.

  • master ブランチは git init した時のデフォルトのブランチ名
  • origingit clone した時のデフォルトのリモート名
  • コミットは、その時の「ルートディレクトリのスナップショット」への参照を持つ
    • コミットは「1 つ前のコミット」(親コミット)への参照を持つ。これにより歴史が辿れる
    • Git のコミットグラフの図では、矢印は 1 つ前のコミットを指している。時間軸の方向ではないので注意
    • マージコミットは複数の親を持つコミット

  • ブランチとはコミットを指すポインタ
    • これが Git の優れた設計ポイントと言える
    • ブランチを作るのはポインタを 1 個作る程度のコストでしかない
    • ブランチを切った時点では歴史は分岐していない。コミットして初めて分岐する
  • origin/masterリモートブランチ
    • リモートにあるリポジトリ内の master ブランチが、どのコミットを指しているかを意味する
    • git fetch origin master すると origin/master がリモートと同じ状態になる

  • git pull とは、git fetch して git merge しろという意味
    • git fetch origin masterorigin/master が最新になる
    • git merge origin/master でローカルブランチの master に リモートブランチの origin/master がマージされる

リファレンス

よい資料

ブランチ運用モデル

Tips

プルリク開発

業務の開発も OSS 開発のように行おうという姿勢

コミットメッセージ系

よくやる

pull –rebase

コミット後・push 前にリモートから差分取得する時にマージコミットができるとログが見づらくなってイヤ、 という時は merge の代わりに rebase をする以下のオプションが使われる:

git pull --rebase origin master
  • チームの rebase の理解度が低いとコンフリクト時に事故が起こりやすいので注意
  • Pull Request ベースで開発していて Squash Merge する運用ならこの辺はあまり気にしなくてよい

checkout -b

# ブランチを作ってそこに移動
git checkout -b new_branch

# ↑ は以下のコマンドのショートカット
git branch new_branch
git checkout new_branch

git log

ログから対象文字列を含むコミットを検索

# --since は "2 days" みたいに柔軟な指定ができる
git log -S "target_word" --since="1 week"

特定ファイルの変更履歴を表示

git log -p {TARGET_FILE}

git branch

ブランチを消す

git branch -d branch_name     # ローカルのを消す
git push origin :branch_name  # リモートのを消す

【補足】

  • git push origin master
    git push origin master:master の略。
  • ローカルブランチの master をリモートブランチの master に push するという意味。
  • 上記の消すやつは空 branch を push してる感じ

作成者を含めてブランチ一覧表示

git for-each-ref --format='%(authorname) %09 %(refname)' | grep 'refs/remotes/origin' | sort -k5n -k2M -k3n -k4n

消されたブランチを手元でも消す

誰かがリモートブランチを削除しても、ローカルでは残っている。 以下のコマンドでそれを整理できる

git remote prune origin

ローカルのブランチ名を修正

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

現在のローカルブランチの追跡先を確認

git branch -vv

現在のローカルブランチの追跡先を origin/hoge にする

# u は upstream
git branch -u origin/hoge

git diff

git diff で作ったパッチを当てる

git diff > patch.txt
patch -p1 < patch.txt

git tag

# 一覧
git tag

# タグを打つ
git tag v1.0.0

# 特定コミットにタグを打つ
git tag v1.0.0 <commit_hash>

# リモートにタグ全部 push
git push origin --tags

# ログ見るとき、%d でタグ情報も表示できるよ
git log --pretty=format:"%C(yellow)%h%C(reset) %C(blue)%ad %C(reset)%C(red)%an%C(reset) - %s %C(green)%d%C(reset)" --graph --date-order -30 --date=iso

アレを直す系 Tips

push 前に commit を取り消す

git reset --hard <commitId>

うっかり commit しちゃったファイルを git の履歴からも消す

特定のリビジョンの内容に戻して commit

git reset --hard 56e05fced
git reset --soft HEAD@{1}
git commit -m "Revert to 56e05fced"

操作系 Tips

Untracked files を一瞬で消し去る

git clean -fdx

# n をつけると dry-run
git clean -fdxn

コミット A から B までをまとめて cherry-pick

git cherry-pick A^..B

.gitignore に足したんだけどもうそれ add しちゃってたとき

  • すでに add されてるファイルはキャッシュ残ってて .gitignore 効かない
  • 再反映する
git rm -r --cached .
git add .
git commit -m "Reapply .gitignore"
git push origin master

調査系 Tips

あのファイル消えてるけどどこで消えちゃったんだろう

git rev-list --pretty HEAD -- 対象のファイルパス
# 最後の commit だけ表示したいなら -n 1 を与えればよい

その他 Tips

プルリクの差分を手元で見る

でかい差分が GitHub 上で見づらいとき

# feature -> master のプルリクの差分を見たいとき
# (トリプルドットを使う)
git diff master...feature

# 僕は周辺行を多く表示するのが好き(コンテキストを理解しやすい)
# (-U<行数> オプションを使う。grep の -C みたいなもの)
git diff master...feature -U30

^M とかを無視する

git config --global core.whitespace cr-at-eol

リポジトリのサイズを調べる

  • unpacked object の数とサイズを表示 :
git count-objects -vH
  • ディスクの使用容量はまあ du -sh ./ とかで