Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
開発効率をあげるgitテクニック / Useful git
Search
buty4649
August 27, 2018
Programming
1
990
開発効率をあげるgitテクニック / Useful git
2018/08/27にペパボ社内で行われたシェル大活用講座の発表資料です
buty4649
August 27, 2018
Tweet
Share
More Decks by buty4649
See All by buty4649
mrubyでワンバイナリーなテキストフィルタツールを作った / Building Text Filtering Tools with mruby #tokyorubykaigi
buty4649
0
140
mrubyで始める自作シェル / Handmade bash-like shell with mruby
buty4649
1
670
AWS DirectConnectを使ったハイブリットクラウドの構築と活用 / hybrid cloud with aws directconnect
buty4649
0
750
Mackerelとペパボとプラグインと / Mackerel & Pepabo & Plugins
buty4649
0
2.2k
プライベートクラウドではじめるDevOps / Private Cloud and DevOps
buty4649
1
3.7k
ラズパイで始める電子工作 / Raspberry PI de Asobu
buty4649
0
1.2k
5分でわかるOpenStack Octavia / OpenStack Octavia in 5min
buty4649
0
1.2k
Mackerel User Groupの説明 / about mackerel user group
buty4649
0
3k
100行あったmod_rewirteを ngx_mrubyで書き換えた話
buty4649
5
9.2k
Other Decks in Programming
See All in Programming
登壇資料を作る時に意識していること #登壇資料_findy
konifar
3
920
フルサイクルエンジニアリングをAI Agentで全自動化したい 〜構想と現在地〜
kamina_zzz
0
400
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
0
890
CSC307 Lecture 03
javiergs
PRO
1
490
AIエージェントの設計で注意するべきポイント6選
har1101
7
3.4k
CSC307 Lecture 09
javiergs
PRO
1
830
AI巻き込み型コードレビューのススメ
nealle
0
100
Apache Iceberg V3 and migration to V3
tomtanaka
0
150
コントリビューターによるDenoのすゝめ / Deno Recommendations by a Contributor
petamoriken
0
200
Grafana:建立系統全知視角的捷徑
blueswen
0
320
今こそ知るべき耐量子計算機暗号(PQC)入門 / PQC: What You Need to Know Now
mackey0225
3
370
AIで開発はどれくらい加速したのか?AIエージェントによるコード生成を、現場の評価と研究開発の評価の両面からdeep diveしてみる
daisuketakeda
1
970
Featured
See All Featured
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
640
Designing Experiences People Love
moore
144
24k
Six Lessons from altMBA
skipperchong
29
4.1k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.7k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
3.6k
A Soul's Torment
seathinner
5
2.2k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Paper Plane (Part 1)
katiecoart
PRO
0
4k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2k
GraphQLとの向き合い方2022年版
quramy
50
14k
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
Transcript
開発効率をあげるgitテクニック 〜シェル芸もあるよ〜
高谷雄貴 @buty4649 シニアエンジニア 技術部 プラットフォームグループ
git
• 普段からgitを使っている ◦ GitHub / GH:E ◦ GitHub Workflow •
gitコマンドを便利にして生産性↑↑ 今日のテーマ
• gitってなに???って話はしません ◦ ググるか誰かに聞いてください • bashを使うことを前提で書いている部分があります。 ◦ zsh/fish/bsh/ksh/csh/tcsh/ash/dash な人は適宜読み替えてください おことわり
目次 1. 減らす 2. 便利にする
PRを作る場合のオペレーション例 普段どんなオペレーションをしますか? $ git clone
[email protected]
/foo/bar $ cd bar $
git checkout -b new-branch <ファイルを変更する> $ git status $ git add foobar $ git commit $ git push origin new-branch <ブラウザを開いてPRを作る> 1.減らす
PRを作る場合のオペレーション例 普段どんなオペレーションをしますか? $ git clone
[email protected]
/foo/bar $ cd bar $
git checkout -b new-branch <ファイルを変更する> $ git status $ git add foobar $ git commit $ git push origin new-branch <ブラウザを開いてPRを作る> 打鍵数が多い! 84文字! (下線部のみ) 1.減らす
減らす
alias g=git
1.減らす • シェルのエイリアス機能 ◦ コマンドに別名を割り当てる • g で gitコマンドが実行される alias
g=git
1. 減らす • 引数はそのまま処理される ◦ g status は git status
として実行される • 引数付きのコマンドもエイリアスにできる ◦ alias gs=’git status’ とするとgsでgit statusが実行される • エイリアスを消したい場合は unalias コマンドを使う ◦ unalias g ◦ 一時的に無効にしたい場合はコマンド名の頭に \ をつける • エイリアスはカレントシェルのみに反映される ◦ 永続化したい場合は ~/.bash_profile へ エイリアス機能の補足
84文字 → 74文字!! エイリアスによって削減 $ g clone
[email protected]
/foo/bar $ cd
bar $ g checkout -b new-branch <ファイルを変更する> $ g status $ g add foobar $ g commit $ g push origin new-branch <ブラウザを開いてPRを作る> 1.減らす
まだ減らす
git config --global alias.st status
1.減らす • “git” のエイリアス機能 ◦ サブコマンドをにエイリアスをつけられる • よく使うサブコマンドを短い文字にエリアスする ◦ st
→ status, a → add など • 設定された内容は ~/.gitconfig に保存される ◦ ~ は $HOME と同じ意味 ◦ ファイルに設定を書いても良い(即時反映される) git config --global alias.st status $ cat ~/.gitconfig [alias] st = status
1.減らす gitサブコマンドのエイリアス例 $ cat ~/.gitconfig [alias] a = add cl
= clone cm = commit co = checkout cob = checkout -b p = push st = status
84文字 → 50文字!! エイリアスによって削減 $ g cl
[email protected]
/foo/bar $ cd
bar $ g cob new-branch <ファイルを変更する> $ g st $ g a foobar $ g cm $ g p origin new-branch <ブラウザを開いてPRを作る> 1.減らす
1.減らす • よく使うコマンドを短くすると効果的 • 引数を含めよく使うコマンドもエイリアスにする ◦ サブコマンド+オプションにするとよいと思う ◦ 例: git
checkout -b → git cob • シェルのエイリアスとの使い分け ◦ シェルのエイリアスにした方がサブコマンドのスペースが減らせる ◦ 例: alias gcob=’git checkout -b’ ◦ シェルの補完が効かないしコマンド名がかぶる可能性 ◦ 好みの問題かも エイリアス作成のコツ(私のやり方)
1. 減らす 私の設定例 [alias] br = branch cm = commit
-v cma = commit -v --amend cman = commit -v --amend --no-edit co = checkout cob = checkout -b d = diff dc = diff --cached g = grep 詳しくは https://github.com/buty4649/dotfiles/blob/master/cookbooks/configfiles/files/.gitconfig
もっと減らす
もっと減らす $ g cl
[email protected]
/foo/bar $ cd bar $ g
cob new-branch <ファイルを変更する> $ g st $ g a foobar $ g cm $ g p origin new-branch <ブラウザを開いてPRを作る> 1.減らす めんどくさい!
1.減らす • いちいちファイル名を書くのが手間 ◦ git add . でもいいけど、一部だけaddしたい場合不便 • 極力ファイル名を打ちたくない!
◦ 浅い階層ならいいが深い階層だとその分タイプ数が増える ファイル名を書くのがめんどくさい! どうしたらファイル名を打たずにgit addできるか?
1.減らす • git addのあとにaddしたいファイル名を羅列する ◦ git add <file1> <file2> …
• このコマンドを生成できればよい • 変更がかかったファイルはgit statusで取れる • つまり↑をいい感じにしてgit addするスクリプトを書けばよい! どうしたらファイル名を打たずにgit addできるか?
1.減らす • 生のgit statusの結果はパースしづらいのでオプションをつける スクリプトを作る $ git status --short MM
file1 ワークツリーの状態 インデックスの状態 M: 変更された A:追加された D:削除された U:更新されたがマージされていない(コンフリクトなど) ※ 詳しくはgit status --helpを参照
1.減らす • 出力結果をフィルタする必要がある ◦ Dなファイルをgit addに渡すとエラーになる ◦ addしたいファイルのみを選択したい ▪ コマンドラインセレクターを使うと便利!
▪ 例えば peco (詳しくはこのあとのudzuraさんの発表で) • スクリプトをどこに書くか? ◦ gitのエイリアスはスクリプトが書ける ◦ !を先頭に書くとスクリプトとして解釈される ◦ 例: v = !vim → git v でvimが起動する スクリプトを作る
1.減らす 完成したコマンド [alias] a = !"git status --short | awk
'!/^[ADRM] /' | peco | awk '{print $NF}' | xargs -r git add" git status --short | awk '!/^[ADRM] /' | peco | awk '{print $NF}' | xargs -r git add 先頭がADRMを除外 ファイルを選択 ファイル名のみ切り出し git addを組み立て
1.減らす 解説(awk) $ git status --short D file1 M file2
$ git status --short | awk ‘!/[ADRM] /’ M file2 $ git status --short | awk ‘!/[ADRM] /’ | > awk ‘{print $NF}’ file2
1.減らす 解説(xargs) • 標準入力をコマンドの引数に追加し実行する ◦ 例: echo b | xargs
echo a → echo a b が実行される • forやwhileでも同じことができる ◦ 例: date | xargs echo → date | while read LINE;do echo $LINE;done ◦ サブシェルを作らない分xargsのほうが早い • -r オプションをつけると入力が空の場合実行しない ◦ macOSのxargsにはないかも… • 通常は末尾に引数を追加するが-Iで任意の場所に追加できる ◦ -Iに続いて置換する文字列を書く ◦ 2文字以上でも使える ◦ 例: date | xargs -I{} echo {} hogehoge • これ以外にもすごく便利なのだけどそれを書くには十分な余白がry
1.減らす これでpushはgit gpushでいけるようになる git push origin new-branchも短くする [alias] gpush =
!"git rev-parse --abbrev-ref HEAD | xargs git push origin" $ git rev-parse --abbrev-ref HEAD new-branch
1.減らす これでpushはgit gpushでいけるようになる git push origin new-branchも短くする [alias] gpush =
!"git rev-parse --abbrev-ref HEAD | xargs git push origin" $ git rev-parse --abbrev-ref HEAD new-branch
1.減らす • git push origin HEAD でいける ◦ この資料を作っているときに知った。。 •
つまり、↑をエイリアスすればよい git push origin new-branchも短くする [alias] gpush = push orogin HEAD
1.減らす 私の設定例 # ブランチを選択してcheckout c = !"git branch | awk
'!/^\\*/' | peco | xargs -r git checkout" # リモートブランチを選択してcheckout cobr = !"git branch -r | grep -vE '/(HEAD|master$)' | sed -e 's,origin/,,g' | peco | xargs -r -I{} git checkout -b {} origin/{}" # 変更されたファイルを選択してcheckout cof = !"git status --short | peco | awk '{print $2}' | xargs -r git checkout --" ※ \ はエスケープする必要がある
84文字 → 29文字!! 65%効率アップ!!!! 最終結果 $ g cl
[email protected]
/foo/bar $
cd bar $ g cob new-branch <ファイルを変更する> $ g st $ g a $ g cm $ g gpush <ブラウザを開いてPRを作る> 1.減らす
目次 1. 減らす 2. 便利にする
• 減らすではタイプ数を減らすことに注力した • 次はタイプ数削減以外の方法で効率化する • 便利なツールや機能を使ってより作業効率をあげる 2.便利にする
2.便利にする git-completion.bash & git-prompt.sh • gitをインストールするとついてくる便利スクリプト • bashの補完機能を提供 ◦ (brew)
/usr/local/etc/bash_completion.d/git-completion.bash ◦ sourceで読み込む • プロンプトにカレントブランチを表示 ◦ (brew) /usr/local/etc/bash_completion.d/git-prompt.sh ◦ PS1環境変数に __git_ps1関数を追加する $ git branch 20180827-pepabo-college ~/path/to/hoge ( 20180827-pepabo-college ) $ echo $PS1 \w$(__git_ps1 " (\[\e[0;31m\]%s\[\e[00m\])")\n\$
2.便利にする ghq • ローカルリポジトリの管理ツール ◦ https://github.com/motemen/ghq • 指定のディレクトリ配下にgit cloneする ◦
デフォルトは ~/.ghq ◦ GOPATHと合わせておくと便利 ▪ git config --global ghq.root ~/src • 使い方 ◦ リモートリポジトリのクローン ▪ ghq get <リモートブランチのURL> ◦ ローカルリポジトリのフルパスを一覧で表示 ▪ ghq list -p
2.便利にする ghq • ghq list と pecoを組み合わせて移動できる ◦ cd $(ghq
list -p | peco) • これをコマンドにする ◦ 外部コマンドではcdできないので関数で定義する ◦ 例: gcd() { cd $(ghq list -p | peco); }
2.便利にする tig • TUIなgitクライアント ◦ https://github.com/jonas/tig • 詳しくはこのあとのjune29の発表で!!! • 私の使い方
◦ git ll にエイリアスしている ◦ fixup / squash できるようにしている $ cat ~/.gitconfig [tig "bind"] diff = F ?!git commit --fixup %(commit) diff = S ?!git commit --squash %(commit) main = F ?!git commit --fixup %(commit) main = S ?!git commit --squash %(commit)
2.便利にする hub • Github社が作ったgitコマンドラッパー ◦ https://github.com/github/hub • gitにエイリアスして使う ◦ eval
$(hub alias -s) • gitに機能を追加する ◦ issueやPRの作成ができる ◦ 詳しくは https://hub.github.com/hub.1.html • ローカルリポジトリでhub browseすると便利 ◦ GH:Eなリポジトリを見るときは設定が必要 ◦ git config --global hub.host <GHEのFQDN>
2.便利にする git hookを使う • 特定のアクションの実行前/後にスクリプトを実行する ◦ 詳しくは https://git-scm.com/docs/githooks • hookスクリプトは
.git/hooks 配下にある ◦ 例えばcommit前にhookするなら ▪ .git/hooks/pre-commit ▪ chmod +x するのを忘れない(重要)
2.便利にする hook利用例(1): プッシュ前にlintを行う • プッシュした後にCIのlintチェックで落ちると悲しい… • git pushする前にlintすれば回避できる! $ cat
.git/hooks/pre-push #!/bin/bash rake lint • しかし、プッシュに時間がかかるようになるというデメリット
2.便利にする hook利用例(2): master pushを防ぐ • master pushやりがち • Github側で設定変更するという手段もある ◦
すべてのリポジトリに設定するのは手間 • hookを使って防ぐ
2.便利にする hook利用例(2): master pushを防ぐ https://github.com/buty4649/dotfiles/blob/master/cookbooks/configfiles/files/.git_template/hooks/pre-push $ cat .git/hooks/pre-push #!/bin/bash CURRENT_BRANCH="$(git
rev-parse --abbrev-ref HEAD)" if [ "$CURRENT_BRANCH" = "master" ];then if [ -z "$ALLOW_GIT_MASTER_PUSH" -a \ -z "$(git config --get git.allow-master-push)" ];then echo "WARN: It's the master branch !!" echo 'If you want git push, please set either.' echo '* $ALLOW_GIT_MASTER_PUSH=1' echo '* git config --local git.allow-master-push 1' exit 1 fi fi
2.便利にする hook利用例(2): master pushを防ぐ $ git branch master $ git
push WARN: It's the master branch !! If you want git push, please set either. * $ALLOW_GIT_MASTER_PUSH=1 * git config --local git.allow-master-push 1 error: failed to push some refs to 'foobar'
2.便利にする hook利用例(2): master pushを防ぐ • master pushしなくなって悲しみが減った • ただ、master pushでもいいときに回避するのが手間
◦ プロンプトをだしてyを入力したらpushでもいいかも • hookにスクリプトを直接書くと変更するときに面倒 ◦ hookからはコマンドを呼び出すだけにしたほうが良いかも • git init / git cloneの度にhookを配置するのが手間 ◦ git-templateを使うと便利 ◦ https://git-template.readthedocs.io/en/latest/ • すでにあるリポジトリに設置したい ◦ ghq list -p | xargs -L1 -I{} cp -pv pre-push "{}/.git/hooks" ◦ (自信なし)
まとめ
まとめ • gitコマンドのタイプ数を減らすと効率があがる • シェルスクリプトを駆使してサブコマンドを作ると便利だし楽しい • 便利なツールを使うとより生産性があがる