Slide 1

Slide 1 text

GIT 中級者への道 GIT 中級者への道 Makuake Tech Talk #45 Makuake Tech Talk #45 @kkkw

Slide 2

Slide 2 text

agenda agenda 基本知識 オプション編 re og ケーススタディ

Slide 3

Slide 3 text

今日話さないこと 今日話さないこと リモートの話 ブランチの特性とか 細かい解説

Slide 4

Slide 4 text

基本知識 基本知識 GIT とSVN の違い すべてはコミットハッシュでの指定 リベースは連続したcherry-pick

Slide 5

Slide 5 text

GIT とSVN の違い GIT とSVN の違い 根本的な違いを意識しておくとよい GIT はコミットそのものを管理するもの SNV はファイルを管理するもの

Slide 6

Slide 6 text

GIT の場合 GIT の場合 コミットそのものを管理対象として扱う コミットにファイルが紐付いている必要はない よって、コミット操作がすべて

Slide 7

Slide 7 text

SVN の場合 SVN の場合 ファイルを管理対象として扱う すべてのコミットに何かしらのファイルが必要 だから空コミットとか作れない

Slide 8

Slide 8 text

すべてはコミ すべてはコミ ットハッシュ ットハッシュ GIT で指定するものは、コミットハッシュしかない ブランチ名を指定しているようで 実はコミットハッシュを指定している

Slide 9

Slide 9 text

例 例 下記の2 つは同じ意味 git merge origin/master git log origin/master // 先頭のコミットハッシュがxxxxx だとする git merge xxxxx

Slide 10

Slide 10 text

リベースは連続したcherry-pick リベースは連続したcherry-pick rebase の概念は、 指定したコミットの後ろに 指定した複数のコミットを当て直すという作業 merge とは根本的に概念が違う

Slide 11

Slide 11 text

オプション編 オプション編 普段使っているサブコマンドにある 知っていると便利(or 必須) なオプション紹介

Slide 12

Slide 12 text

add のオプション add のオプション f force .gitignore に入っているものを追加したいとき n dry-run git add -n ./ とか git add -fn foo とか p patch 難しいので後述

Slide 13

Slide 13 text

git add -p git add -p パッチオプション ハンクと呼ばれる差分の塊でステージングしていく 本来の目的の編集とリファクタリングを 一緒にやってしまったあとに それぞれ別でコミットしたいときなどに使う

Slide 14

Slide 14 text

git add -p git add -p // このhunk をステージする y - stage this hunk // このhunk はステージしない n - do not stage this hunk // これ移行の hunk をステージしない q - quit; do not stage this hunk or any of the remaining ones // これ移行すべてをステージ a - stage this hunk and all later hunks in the file // このファイルのhunk はこれ移行すべてステージ d - do not stage this hunk or any of the later hunks in the file // 指定した hunk に移動 g - select a hunk to go to // マッチするhunk を検索 / - search for a hunk matching the given regex // いったんスキップ。次の未解決のhunk を表示 j - leave this hunk undecided see next undecided hunk

Slide 15

Slide 15 text

commit のオプション commit のオプション a 管理下にあるファイル変更点を全て含めてコミッ ト。新規ファイルでステージングもされていない ものは入らない p add と同じ c 指定したコミットと同じメッセージを使う git commit -c HEAD v コミットしようとする内容を表示する

Slide 16

Slide 16 text

grep のオプション grep のオプション v マッチしなかった行が表示される F 正規表現を使わない l ファイル名のみ表示 L マッチしなかったファイル名のみ表示 n 行番号の表示

Slide 17

Slide 17 text

log のオプション log のオプション oneline graph decorate name-status ファイル名を表示

Slide 18

Slide 18 text

log のオプション log のオプション n 数を指定 -1 とかで代用可 特定のパス git grep -- foo/bar/buz S 変更の差分でgrep git log -S"foo" --pretty=oneline --name-only

Slide 19

Slide 19 text

stash のオプション stash のオプション p add と同じ a all git 管理されていないファイルも含める

Slide 20

Slide 20 text

re og re og git は操作した履歴をすべて残している 操作した履歴自体もバージョン管理している これを読めるようになると魔法使い ブランチ消しちゃった マージ間違えた rebase 間違えた を解決できる

Slide 21

Slide 21 text

ケーススタディ ケーススタディ こんなときどうするの

Slide 22

Slide 22 text

とりあえず一つ前に戻し とりあえず一つ前に戻し たい たい ペアプロとかでwip でコミット&push して 次の人が再開する前に git reset HEAD~

Slide 23

Slide 23 text

reset のオプション reset のオプション --soft ステージングには残す -- hard working tree からも消す default ステージングから消して、working tree には残す

Slide 24

Slide 24 text

間違ってマージしたので 間違ってマージしたので 元に戻したい 元に戻したい git reset --hard ORIG_HEAD

Slide 25

Slide 25 text

マージコミットを マージコミットを リバートしたい リバートしたい git revert -m 1 xxxxx

Slide 26

Slide 26 text

マージコミットの マージコミットの リバートの考え方 リバートの考え方 マージコミットには、歴史が2 つある m に指定するの は、どちらの歴史が正しいか。 1 つ目はマージされた側 github ow だと、大抵master のHEAD 2 つ目はマージする側 github ow だと、大抵PR のブランチのHEAD なので大抵1 を指定することになる

Slide 27

Slide 27 text

リバートのリバート リバートのリバート 難しく考えないで、 リバートしたコミットハッシュを リバートすればよい

Slide 28

Slide 28 text

一連のコミット群を移動したい 一連のコミット群を移動したい 派生元のブランチを変えたい 間違ったブランチにコミットを複数積んでしまった 時に正しいブランチに移動したい などの時に使う git rebase --onto master xxxxx git rebase --onto origin/master master git rebase --onto feature/foo master

Slide 29

Slide 29 text

github ow でありがちな状況 github ow でありがちな状況 こんな感じで派生したブランチがあって、 future-foo を先にmaster にマージしてしまった。 future-bar の派生元をmaster に変更したい master └── future-foo └── future-bar

Slide 30

Slide 30 text

github ow でありがちな状況 github ow でありがちな状況 feature/bar の git log --oneline 左端はコミットハッシュ こんな感じで指定する bar-ci-3 (HEAD -> feature/bar, origin/feature/bar) some bar comme bar-ci-2 some bar comment 2 bar-ci-1 some bar comment 1 pr-3-ci (origin/master, origin/HEAD, master) Merge pull request # pr-2-ci Merge pull request #2 from feature/some-pr-2 pr-1-ci Merge pull request #1 from feature/some-pr-1 git checkout future-bar git log --oneline // 派生元のコミットハッシュを見つける git rebase --onto master pr-3-ci // コミットハッシュか派生元ブランチを指

Slide 31

Slide 31 text

消しちゃったブランチを 消しちゃったブランチを 復活したい 復活したい re og から対象のHEAD を見つける git checkout -b feature/foo HEAD@{1}

Slide 32

Slide 32 text

ステージングされたファイルを ステージングされたファイルを 全部アンステージしたい 全部アンステージしたい git reset HEAD ./

Slide 33

Slide 33 text

カオスなコミットを カオスなコミットを 全部やり直したい 全部やり直したい 開発中こまめにコミットしていたら、 コミットの整理をするのも辛くなってきた もう一度最初から適切な単位、 順番でコミット積みなおしたいという時

Slide 34

Slide 34 text

カオスなコミットを カオスなコミットを 全部やり直したい 全部やり直したい 下記コマンドで一旦全部unstage 状態にして コミットを積みなおすのが速い // ブランチの派生元のコミットハッシュを特定する git log --oneline or git show-branch --merge-base feature/foo HEAD //unstage にする git reset xxxxx

Slide 35

Slide 35 text

同じコンフリクトを 同じコンフリクトを 何度も解決するの辛い 何度も解決するの辛い git rerere の設定をしておく rerere is "Reuse recorded resolution of con icted merges" git config rerere.enabled true

Slide 36

Slide 36 text

自分だけ無視したい 自分だけ無視したい ファイルたち ファイルたち 使い回すテストコードを書いたファイルとか ${project-root}/.git/info/exclude にgitignore と同じ形式で記述する 参考 git status -s | grep '??' | awk '{print $2}' >> .git/info/exclude

Slide 37

Slide 37 text

git 管理していない git 管理していない ファイルを消す ファイルを消す git clean -i

Slide 38

Slide 38 text

ご静聴 ご静聴 ありがとう ありがとう ございました。 ございました。