はじめに
業務で初めてgitに出会ってから3年が経ちました。
自分より新しい人もたくさん増えて、自分が当たり前のように使っているコマンドを知らない人が周りにいることを先日知りました。
そういえば、1年目のときは全然わからなくてラージャンのような怖い先輩にいっぱい怒られて苦手で大嫌いだったgitも、今では普通に使っていて人に教えるようになっているとは・・・とちょっと感慨深くなったので、周りで苦戦しているみなさんにも知って欲しいなと思って共有します。
基本的なgitはOK!という人に、次のステップとしてぜひ習得してもらいたいgitコマンドたちです。
確認編
- ソース修正〜commitまでの一連の動作についておさらいです
- 普段、意図しない差分がcommitされていないか、ちゃんと最終確認していますか?
- やってない人は、今一度自分の作業を見直してみましょう
ソース修正〜commitまでの一連の動作
- ソース修正
-
git status
->git diff
を繰り返し、差分を確認 - 必要な差分を
git add
- indexに
add
された差分をgit diff --cached
で最終確認 git commit
-
git show
でもう一度確認 (ここまでできればgood!)
ここまでOKであれば、基本的なgit操作は大丈夫ですね\(^o^)/
まだ怪しいよって人は身に染み付くまで繰り返しやってください。そうすればこの一連の作業を息をするように出来るようになると思います。
準備編
- よく使うコマンド、オプションはaliasに設定しておきましょう!作業効率UPです
例
alias.co checkout
alias.s status
alias.b branch
alias.r remote
alias.d diff
alias.m merge --no-ff
alias.fe fetch --all
alias.up pull --rebase
alias.l log --oneline --decorate --graph --all -20
alias.lp log --oneline --decorate --graph
alias.llp log --graph --decorate --pretty='format:%C(yellow)%h%Cblue%d%Creset %s %C(black bold)%an [%ai]%Creset' -20
alias.rh reset head
alias.d1 diff HEAD~
alias.d2 diff HEAD~~
alias.d3 diff HEAD~~~
alias.d4 diff HEAD~~~~
alias.d5 diff HEAD~~~~~
1. 「さっきのブランチに戻りたいなあ〜」→ git checkout -
- 一つ前のブランチに戻れます
- ブランチ名に特定のプレフィックスがついてる場合など、補完しにくいときなどはこれを使えば行き来が楽です。
(master)
$ git checkout work
(work)
$ git checkout -
(master)
$
2. 「この行の修正だけcommitしたいなあ〜」→ git add -p
-
add
を差分ごとに実行できます。 - 基本的に以下4つさえ覚えておけばたいていのことはできます。めっちゃ便利です。
- y - この差分をindexにいれる
- n - スキップする
- q - 終了する
- s - 差分を分割する
- 私のgit人生のバイブルと思っている記事を紹介します
-
git add (ファイル名)
で差分単位ではなくファイルごとaddできますが、git add -p (ディレクトリ名/ファイル名)
とすれば、add -p
の対象を絞ることも可能です。
3. 「差分のあるファイルってどれだっけ?」→ git diff --stat
-
diff
(差分)をファイル単位で出力できます - 差分が多くなったので確認したいとき、差分のあるファイル名をコピペしたいときなどに
- 同類で、ファイル名だけを出す場合は
--name-only
が使えます
$ git diff --stat
sample.rb | 3 ---
test.rb | 3 +++
2 files changed, 3 insertions(+), 3 deletions(-)
$ git diff --name-only
sample.rb
test.rb
4. 「あのブランチのあのcommitが欲しい!」→ git cherry-pick [commit番号]
- 他のブランチに存在している、指定した
commit
を自分のブランチに取り込むことができます - 差分が出そう、commitメッセージは変えたいという場合には、オプションとして
-n
をつければindexに取り込んでくれる便利具合です。
$ git cherry-pick a1sd2f3 -n
5. 「あのブランチのあのファイルが欲しい!」→ git checkout [ブランチ名] -- [ファイル名]
- 特定ブランチの特定ファイルのみの差分をindexに引っ張ってこれます
(master)
$ git checkout work -- test.rb
(master)
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: test.rb
6.「インデント変えただけなのに差分が大量にあって見づらいよ〜」→ git diff -w
- 生意気な後輩に教えてもらった秘伝オプションです。詳細は記事にある通り。
-
-w
で、ホワイトスペースを全部無視、-b
でホワイトスペースの数を無視です - インデント変更は意図しない差分を生みやすいので、それだけでまずcommitしてしまうのが良いですね◎
7.「この差分、commitしたくないけど消したくないよ〜」→ git stash
- 一時保存コマンド、
stash
が使えるようになればぐんと作業が捗ります - 複数の作業ブランチを並行稼動しているときに毎回commitしなくて済むのですごく便利です
- また、同じ機能を何度も修正・開発するときなどに決まったログを仕込んで出すことがありますが、何回も消して書いてをしなくても、
stash save
してstash apply
すれば一次保存ではなくsnippet的な利用も可能です - レビューしているブランチでログ仕込んだり変更したり好きなようにいじって
stash
, レビュー返却してまた返って来たらstash pop
して確認・・・とかも可能 - ログ出力の差分をcommitなんかしたら怖い先輩に
殺さ怒られるのでstashを活用して絶対commitしない運用にしておきましょう
便利なstashさん一族
-
stash
-> 保存 -
stash list
-> 保存内容一覧。stash{1}
などそれぞれに番号がついていますね。それが保存番号です。 -
stash pop
-> 保存を取り出す&消す- 保存番号をつけなければ、最新の保存内容を取得します。保存番号を指定する場合は、
stash pop stash{1}
という感じに。他コマンドも同様。 - conflictしたら消えません。正しく取り出せたら
drop
しましょう
- 保存番号をつけなければ、最新の保存内容を取得します。保存番号を指定する場合は、
-
stash apply
-> 保存を消さないで取り出す。後でまたその差分を使いたいときに。 -
stash drop
-> 保存を消す -
stash show
-> 保存内容を見る -
stash save "message"
-> 名前をつけて保存 - その他、stashについてわかりやすい記事こちら
stash
を多用する人は、定期的にstash list
して保存内容を確認・断捨離しましょう。
でないと30個とか溜まってしまったりして、周りから整理できない系女子と揶揄されます。
8.「このブランチを最新のmasterから切ったことにしたいな〜」→ git rebase
- masterブランチから切って作業を開始して、開発に時間がかかってしまうとmasterと差分がたくさん発生してしまうことがあります
- 基本的には、masterをpullして定期的にmergeするかと思いますが、merge commitが多くなると、初期のcommitが追いづらくなりますよね
- そんなときには
git rebase master
とやれば、mergeでなく最新のmasterから切ったように差分を付け替えてくれます - また、もしworkブランチに、既にmasterにmergeされているcommitがあれば、そのcommitはスキップしてくれます
- 注意しなければいけないのは、commit番号が再生成され、commit時間もrebaseした時間になるということ
- commit時間を気にしなくても良いのであれば、rebaseを使っておけばlogを参照する場合には見やすくなります。どちらが良いかは好みです。
9.「この差分ってどのcommitに入ってたっけ?」→ git log -S
-
git log -S [検索したいキーワード]
とやれば、その単語の差分が入ったcommit一覧が表示されます
$ git log -S "hello"
-
git blame
で追えないときに使える! -
-p
をつければ正規表現も使える! -
git log
系もオプションがたくさんあって楽しいgitの1つです。
応用編
10.「logはきれいに整理しておきたいよ」というこだわり派のあなたにgit rebase -i
- 俗に言う歴史書き換え系です。
push
する前の自分の作業ブランチでのみ使いましょう。 -
commit
の順番の入れ替え、統合、メッセージの変更などができます。が、その際にはcommit番号は振り直しされます。 - 細かくcommitしている場合、開発が長引く場合、ログを整理しながら組み立てておくと後々遡って確認するときにどこで間違ったか、なぜこうなっているのかがわかりやすくなります。自分の作業を整理したい場合にどうぞ。
使い方
- 修正したいcommitの1つ前のcommit番号を引数に指定します。
$ git rebase -i 1a2s3d4f
- エディタが開き、指定されたcommitよりも後のcommitが順に並びます
- 修正したいcommitの
pick
の箇所を修正する種類に応じて書き換える- pick -> 何もしない
- reword -> commitメッセージのみを修正する
- edit -> commitした差分を編集する
- squash -> 指定されたcommitとその1つ前のcommitを合体させる(メッセージを変更できる)
- fixup -> 指定されたcommitとその1つ前のcommitを合体させる(メッセージは1つ前のcommitのものを使用する)
- pick行を入れ替えれば順番を変更、pick行ごと削除すればcommitを取り除ける
pick 6f6ee27 test.rb作成
pick 30fab66 new.rb作成
# Rebase e32ab67..30fab66 onto e32ab67 (2 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
- あ、やばいミスった!と思ったら、
rebase --abort
すれば戻せます。 - コンフリクトが発生した場合は修正が複雑になりミスする可能性が高いので中止を推奨します
- 慣れたらやりたい放題できるので、個人的には大好きなgitコマンドです٩( 'ω' )و
やらかした人へのリカバリ集
3年もgitやってればいろんな贖罪が発生するわけです。手順間違えて共有ブランチを壊しかけたり、bundleをpushしてしまったり・・・(;´∀`)
そんなときにも焦らずにちゃんと調べればいろんなリカバリ方法が出てきます。
実際に自分も助けてもらった記事やノウハウの一例を紹介します。
$ git fsck
gitがオブジェクトであることとか、ハッシュによる保存方法、fsck
, gc
っていうコマンドについて、このとき初めて学びました。
このあたりのgitの仕組みについては正直まだ勉強不足ですが、中身を知ると結構面白いです。
最後に
gitの便利コマンドを紹介する記事はいろいろありますが、全部を一気に覚える必要はありません。
叩いてみて、 こんなのがあるんだーというのを知って、実際に業務で困った時・不便だなと思ったときに、
「あれ、そういや◯◯を✕✕するコマンドあったな?」と思い返して、調べて使ってみる・・・を繰り返せば
そのうち自然と覚えているかと思います。
gitに慣れる、gitで思ったことがある程度出来るようになれば、それは開発が早くなる近道です。
そしてgitに慣れるには、叩いて使って失敗してリカバリして…という繰り返しの経験が必要不可欠です。
やったこと・失敗したことをぜひ手元にメモしてノウハウとして蓄積してみてください。
1年後にはきっといろんな操作がスイスイ〜っとできるはずです(`・ω・´)!