はじめに
※@Yametaro氏リスペクト、ワイ記法でお送りいたします。
こんにちは。
Git使い始めの頃、筆者が犯してしまった過ちを告白します。
筆者は前プロジェクトではテキトーにSVNを使っていましたが、Gitプロジェクトに移行して、結構な過ちを犯してしまいました。
反面教師としてお使いください。
過去に戻るで
過去のワイ 「Gitか……クソややこしいから嫌いなんよ……」
ワイ 「SVNでええやん、なんか簡単ぽいし※」
※SVNなら理解できていたとは言っていない
ワイ 「まずさぁ……」
ワイ 「git pull origin masterってなんやねん」
ワイ 「まずmasterは最新ソースコードの保管所みたいなもんやな。originは……まぁリモートのことやろ。完全に理解した」
ワイ 「んで、肝心のgit pullは……」
ワイ 「何々……git fetchとgit mergeを組み合わせたコマンド……」
ワイ 「mergeってなんやねん。怖いわ。なんかせっかく作ったのとか全部上書きされてしまいそうやん?」
ワイ 「怖いし後にしとこ」
??? 「……て……」
ワイ 「ん?」
??? 「待て!!!!」
ワイ 「誰や!?」
??? 「ワシは……Git神!!!」
ワイ 「うわ!!!リー○ス・トー○ルズやんけ!!!」
Git神 「違う!!!Git神だ!!!!」
ワイ 「だからそれリーナ……」
Git神 「違うと言っておろうが!」
Git神 「Git神はGit神なのだ。決して創造神ではない」
ワイ 「なんか見た目同じなんやけどなぁ……まあええわ。で、何しに来たの?」
Git神 「貴様のような無知蒙昧な愚民でもGitチョットデキルように教えに来た」
ワイ 「暴言のキレが凄い」
ワイ 「まあええわ……せっかくやし教えてくれたまえよ」
Git神 「なんで上から目線なんだ貴様」
git pull (origin master)は積極的に
Git神 「git pullは怖がらなくていいぞ」
ワイ 「でもなんかせっかく作ったのとか全部上書きされてしまいそうで怖いやん? 特に同じファイルに更新があったって分かってる場合とか。手戻りしてしまいそうやわ」
Git神 「Gitを舐めるな」
Git神 「Gitを舐めるな」
print("Git神 「Gitを舐めるな」")
ワイ 「……くどいわ!」
Git神 「まぁGitはチョット凄いってことだ」
Git神 「Gitはお前が変更してるところ……チョット専門的な言い方をすると"hunk"……つまり、変更している箇所の断片的なカタマリみたいなものだな。__そのカタマリ単位で干渉してない限り、"merge" したときになんやかんやええ感じにお前の作ったコードに反映してくれる。__要するに、チョット近いところの更新程度なら干渉しないってことだな。かなりピンポイントで同じ箇所を更新していない限り大丈夫だ。」
Git神 「もう一度繰り返すぞ。なんやかんやええ感じに反映してくれる」
ワイ 「なんやかんやええ感じに!?」
Git神 「なんやかんやええ感じに」
ワイ 「とはいえ、同じところ……その、同じhunkをみんなでいじってたら?」
Git神 「そのときは……まぁ頑張って手で直して」
ワイ 「ええ……」
Git神 「そのときはどこが干渉してるかGit側が教えてくれるから、なんやかんやええ感じに『お前が』直すのだ」
ワイ 「怖い」
Git神 「大丈夫、実際やってみたらそこまで難しくはない。あとファイル名が変更されているとかそういうことがあってもGitは割と上手い感じに拾ってくれるのだ。今の段階だととにかく適当にやってみるのがよい」
Git神 「むしろ最新のmasterを頻繁に反映する癖をつけておかねば、いざってときに滅茶苦茶手元の状態が遅れてて整合性取るのに苦労することが結構あるから、意識的にpullすべきなのだ」
Git神 「あと現場によってはmergeじゃなくてrebaseしたほうが良いとか、git pull origin developの方が良いとか色々あると思うけど、この記事では細かいところには立ち入らぬ。許せ」
ワイ 「誰に向かって言ってんねや(お約束)」
こまめなcommitは良い、雑なcommitは許されない
ワイ 「ちょっと疲れたな……ん?なんや上司殿。『緊急対応優先して欲しい』やって? かしこまり」
ワイ 「今の作業は……うん、今の状態だと全く動かんけどcommitしとくか、commitはこまめにって言うしな」
ワイ 「そもそもgitは個人個人のlocalで管理して作業できるのが魅力なんや、ワイは分かってる。適当にcommitしても許されるんや。」
Git神 「んなわけねーだろ!!!!!!!」
ワイ 「グワーッ!!!!!!!!!(緊急回避)」
ワイ「え、今本気で殴りかかってきた……??」
Git神 「当たり前だ!!!!貴様の都合でcommitログを汚すな!!!!」
ワイ 「えぇ……だって個々人のローカル環境で分散できるのがgitの魅力で、最終的にpushしてmergeするなら、個々のcommitとか割とどうでもええやん……」
現在のワイ 「↑これ本気で思ってたで……今思うとゾッとするで……」
Git神 「なんで中途半端に知識あるのだ貴様は……それはそうとダメ絶対!!!commitログは一生残る!」
Git神 「しかも『どの作業でどういう変更があったか』は、Gitであってもブランチ単位やプルリクエスト単位で見ることはあるが、『どこかに切り戻す』っていう前提で見ると、やっぱりcommit単位でみることになるのだ」
Git神 「commitをこまめに、かつ毎回きっちり動く状態でしておくことで、"cherry-pick" や "revert"などのとっても便利な機能が使えるし、何より……」
Git神 「良いcommitログは、あとから他の開発者が履歴を見て、それだけで開発の参考になるのだ」
ワイ 「commitログってあの生物進化の系統樹みたいなやつやろ? あれわけわからんから怖いねん」
Git神 「生物進化の系統樹みたいになるのはブランチの分岐が記録されてるからで、commitそのものとはあまり関係ないのだが……まぁ、大丈夫だ」
Git神 「いつか貴様も系統樹を見てニヤつく優秀な生物学者のごとく、自分が立ち上げたプロジェクトのGitログを見て、それがいかに複雑でも『美しい……』とか呟くようになるから」
ワイ 「なりたくない……」
Git神 「とにかく、だ。今回みたいに『作業を中断して』というときは__『stash(スタッシュ)』__を使うんやな。それこそゲームで言うところの一時セーブみたいな機能や」
ワイ 「頑張りまスタッシュ」
Git神 「」
ワイ 「」
今のワイによる補足 「Gitのログはシンプルな方が良いっていう観点でrebaseやらsquashを多用して無理やりキレイにする、っていうのは個人的にはあまり好きじゃないで。よっぽど更新内容が軽微だったり無意味なものならともかく、基本的にログは複雑なままでもええと思う。もちろんOSSとして公開前提なら別やけど、クローズな開発現場やったら、例えば迂闊なミスでCI段階でテストが落ちてしまったとして、その修正後、ログをキレイにするために工数かけるのってアホらしいと思うのよね。まぁこれはあくまでも個人の意見として聞いてくれや」
ワイ 「……ハッ、なんか未来が見えた!!!!!」
Git神 「大丈夫か貴様」
ワイ 「……なんや……未来が流れ込んでくる……!?」
Git神 「大丈夫か……? 貴様ーーーーーーーーーーーッ!!!!」
現在のワイに戻る
現在のワイ 「ふぅ……」
現在のワイ 「ここまで書いて思ったけど」
- 最新のmasterをpullすることに謎の抵抗があった
- stashの代わりにcommitしてた
現在のワイ 「このふたつの過ちが大きすぎて他が思いつかへん……」
現在のワイ 「特に2番目はもし今の現場でするやつがおったら今すぐ会議室に連れ込んでGit教え込むレベルやわ……」
現在のワイ 「Gitは神のツールや。怖がらず使い倒すことで真価を発揮する」
現在のワイ 「--force ってつける強制系のコマンドは危険なことが多いけど、それ以外は取り返しつくことがほとんどやからな。失敗しまくって覚えたらええ」
現在のワイ 「間違ったcommitしたり、commitのコメント間違ったり。そういった失敗をどう直すかって考えてる中でだんだんと使い方が分かってくるんや」
現在のワイ 「そう、失敗しないことが一番の失敗なんや」
現在のワイ 「ええこと言ったから終わるで」
Git神 「特にオチないのか貴様……」
ついでに
「Gitでここが困った!」的なまとめって結構需要ありそうな気がするんですが、Gitって「理解してる人」と「なんとなくで使い続けてる人」に二極化するツールな気がしてて、いずれにせよ「ここが困った」って具体的に言うのって難しい気がするんですよね。
前者の場合、あらゆる「困った」はいつの間にか勉強して解決済みですし、後者の場合「何が困ってるか」が分からない状態だったりしますし。
Gitって、本気で使い倒そうとすると滅茶苦茶多機能ですからね。
何かそういった初心者あるある事例持ってる方いらっしゃいましたら是非お気軽にコメントしてくださいね。
ではまた。