https://gist.github.com/masasuzu/2d69e77683b5fde08f22fe3111ec88b6
name: すずきまさし
work_at: 3-shake inc.
twitter: @masasuz
github: masasuzu
history:
- ネットワーク系のサポートエンジニア(馬喰町) # 3年くらい
- Webアプリケーションエンジニア(Perl)(五反田) # 5年くらい
- インフラエンジニア(五反田) # 5年くらい
- インフラエンジニア(六本木) # 2年くらい
- インフラエンジニア?(新宿御苑) # 1年 現職、インフラ、クラウド技術を中心とした運用構築技術支援業
skills:
- AWS # ちょっとだけわかる
- Google Cloud # なにもわからない
- Perl # 最近触ってない
- Terraform # 最近のコードの90%はHCL
きちぴーで ぱーるのはなしは こんかいもせず
今回のテーマとして原点ということであるが、この言葉から基礎、もしくはルーツ的なものを想像した。
ルーツ的なエモい話は自分にはできないので、技術的な基礎の分野でなにか話せることないかなと考えていた。
そこで思いついたのはAWSのネットワークの話とgitの話である。今回はgitの話をしようと思う
社内でgitの話をしてたところ、あまりCUIでgitコマンドを叩かないという話を耳にした。
SourcetreeやIDEでgit操作している人が多いようだ。
社外でもそんな人が多いのかなと思い自分の知ってるgitのtipsを書くと面白いんじゃないかなと思って今回の発表をしようと思った。
いまどき別にCUI使う必要はないし、使い慣れたツールを使えばいいとは思うが、
覚えておくといざというときに便利かもしれないgitのtipsを紹介する。
人によっては当然知ってることかもしれないので、ゆるふわに聞いていただけたらと。
- gitの基本的な使い方
- gitの内部構造
- マニアックなgitの使い方
- あからさまな歴史改変
変更をhunkごとにコミット対象に追加する。
同時に変更してしまったが、コミットを分けたい場合に使う。
git commit --interactive
やgit add --interactive
のpatchモードでも同様のことができるが、 git add -p
の方がシンプルでわかりやすい
直前のコミットに変更を追加する。
コミットを汚さずにgit addし忘れたファイルを追加したいときに使う。
直前のコミットをなかったことにする。
コミットしたは良いが間違えてたときとかに使う。
git commit --amend
も git reset --soft "HEAD^”
もgitの歴史を改変してるのでリモートレポジトリにpushされてるものに対しては行ってはならない。
歴史改変は基本的にローカルレポジトリのみで行う。
誤ってシークレット等公開してはいけないものをpushしてしまったときだけ例外的にリモートレポジトリの歴史改変を行う。
gitにはhookの機能があり、特定のアクションを実行する際にコマンドを実行することができる。
.git/hooks/
以下にフックするスクリプトを配置されている。
このhookの仕組みを利用して、コミット直前にいい感じにチェックスクリプトを走らせるのが pre-commit
インストール
brew install pre-commit
.pre-commit-config.yaml
を設置した上で、下記のコマンドを打つことで .git/hooks/pre-commit
にいい感じに設定される
pre-commit install
Terraformのレポジトリには以下のような設定を入れている。
# .pre-commit-config.yaml
repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.77.0
hooks:
- id: terraform_fmt
args:
- --args=-no-color
- --args=-diff
- --args=-write=true
- id: terraform_docs
args:
- --hook-config=--path-to-file=README.md
- --hook-config=--add-to-existing-file=true
- --hook-config=--create-file-if-not-exist=true
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-json
毎回毎回 git status
を打つのは煩わしいので現在のブランチ名やレポジトリの状態をプロンプトに表示させている。
現在だと便利系のツールを入れると同じようなことはできるが、自分は昔ながらの素朴なzshとgitの機能だけでプロンプト表示を行っている。
git branch &> /dev/null | grep '^\*' | cut -b 3-
で現在のブランチ名が取得できる。
git status -porcelain
を叩くとスクリプト等でパースしやすい形でstatusを返してくれるので、それをよしなにしてプロンプトにgitレポジトリの状態を表示させてる。
function git_status {
git_index=$(git status --porcelain 2> /dev/null)
git_status=''
if $(echo "${git_index}" | grep --silent '^?? '); then
git_status+="(untracked)"
fi
if $(echo "${git_index}" | grep --silent '^A '); then
git_status+="(added)"
elif $(echo "${git_index}" | grep --silent '^M '); then
git_status+="(added)"
fi
if $(echo "${git_index}" | grep --silent '^ M '); then
git_status+="(modified)"
elif $(echo "${git_index}" | grep --silent '^AM '); then
git_status+="(modified)"
elif $(echo "${git_index}" | grep --silent '^ T '); then
git_status+="(modified)"
fi
if $(echo "${git_index}" | grep --silent '^R '); then
git_status+="(renamed)"
fi
if $(echo "${git_index}" | grep --silent '^ D '); then
git_status+="(deleted)"
elif $(echo "${git_index}" | grep --silent '^AD '); then
git_status+="(deleted)"
fi
if $(echo "${git_index}" | grep --silent '^UU '); then
git_status+="(unmerged)"
fi
echo "%{$fg[yellow]%}${git_status}%{${reset_color}%}"
}
空のディレクトリはgit管理されないので、空のディレクトリをgit管理させたいときに.gitkeepファイルを使う
gitの履歴を確認する
git log -p
diff付きで履歴確認する
git log --graph
変更をいったんstash 領域に保存する。stashはスタックになってるのでpopで取り出すことができる。
git stash list
stash一覧を表示する
git stash push
現在の差分をstashに追加
git stash pop
引数の指定がなければ最新のstashを取り出す
git stash drop
指定したstashを削除する
git stash clear
stashをすべて削除する
今作業中の変更をいったん避けて、別作業を行うときに使う。
git管理下のファイルから文字列検索する
git grep --cached
コミット対象(インデックス)も含めて検索する
git grep --no-index
git 管理されていないファイルも含めて検索する
めんどくさいからとにかくなんでもいいから全部コミットしてくれ
コミット対象にしたもの以外をとにかく変更を戻してくれ
git reset
コミット対象(インデックス)から外す。変更はそのまま
git reset --hard
とにかくHEADの状態にもとに戻してくれ。変更もなかったことに
別ブランチのコミットを持ってくる。
git cherry-pick ${コミットハッシュ}
頻繁にfeatureブランチがマージされるような運用だとあまり使うことが少ないが、
未mergeのfeatureブランチの特定の変更だけ、開発中ブランチに持ってきたいときに使う。
指定コミットのスナップショットを作成する。
git archive --format=tar.gz--output=archive.tar.gz main
めったに使わないが、レポジトリのファイルを丸ごと受け渡したいときに使う。
ワークツリーをお掃除する
git clean -n
レポジトリ管理外のファイルを確認する
git clean -f
いいから掃除する
git clean -fd
ディレクトリも含めて掃除する