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
980
開発効率をあげる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
130
mrubyで始める自作シェル / Handmade bash-like shell with mruby
buty4649
1
640
AWS DirectConnectを使ったハイブリットクラウドの構築と活用 / hybrid cloud with aws directconnect
buty4649
0
740
Mackerelとペパボとプラグインと / Mackerel & Pepabo & Plugins
buty4649
0
2.1k
プライベートクラウドではじめるDevOps / Private Cloud and DevOps
buty4649
1
3.6k
ラズパイで始める電子工作 / 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.1k
Other Decks in Programming
See All in Programming
30分でDoctrineの仕組みと使い方を完全にマスターする / phpconkagawa 2025 Doctrine
ttskch
2
380
関数の挙動書き換える
takatofukui
4
750
Developing Specifications - Jakarta EE: a Real World Example
ivargrimstad
0
180
Reactive Thinking with Signals and the new Resource API
manfredsteyer
PRO
0
110
Flutterアプリ運用の現場で役立った監視Tips 5選
ostk0069
1
500
Eloquentを使ってどこまでコードの治安を保てるのか?を新人が考察してみた
itokoh0405
0
3.2k
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
6
8.6k
Building AI Agents with TypeScript #TSKaigiHokuriku
izumin5210
5
970
モデル駆動設計をやってみよう Modeling Forum2025ワークショップ/Let’s Try Model-Driven Design
haru860
0
180
オフライン対応!Flutterアプリに全文検索エンジンを実装する @FlutterKaigi2025
itsmedreamwalker
2
250
Micro Frontendsで築いた 共通基盤と運用の試行錯誤 / Building a Shared Platform with Micro Frontends: Operational Learnings
kyntk
0
120
AWS CDKの推しポイントN選
akihisaikeda
1
120
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.5k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Side Projects
sachag
455
43k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
340
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.5k
Stop Working from a Prison Cell
hatefulcrawdad
272
21k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.8k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
1
45
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
34
2.3k
GraphQLとの向き合い方2022年版
quramy
49
14k
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コマンドのタイプ数を減らすと効率があがる • シェルスクリプトを駆使してサブコマンドを作ると便利だし楽しい • 便利なツールを使うとより生産性があがる