Gitの基本とエンジニアの理解
こんにちは、シニアソフトウェアエンジニアのriddleです。
こんにちは、ミドルソフトウェアエンジニアのひびのです。このポッドキャストでは、僕たち2人で、IT業界に関する様々なこと、業務、キャリア、技術みたいなことを話して、僕らの業界のリアルを届けていこうという趣旨の番組です。
今日のテーマが、働くソフトウェアエンジニアのGitの理解度。
Gitを使ってますね。
はい、Gitを使ってます。バリバリ毎日使ってます。
そうですよね、Gitを使わない日はないといっても、構造書く日であればね、基本使うと思うので過言ではないと思いますが。
ただですね、エンジニアになりたての時ってGitめっちゃ難しくなかったですか?
そうですね、それこそGitの概念を学ぶのにまずちょっと苦労しますよね。
しかもなんかコンフリクトとかを起こした日にはね、どうすんねんみたいな。
いやーわかるな、それこそエンジニアなりたての頃にでかいプルリクを出して、でかいコンフリクトを起こして、それの解決にほぼ1日使うみたいな。
いや、ありますよね。とか、あとはローカルで作業しててリセットしちゃって、やべえ、消しちゃいけないファイル消しちゃった、元に戻したいぜとか、そういうやつとか。
違ってプッシュしちゃうとかね。
ありますね。あと、いわゆるソフトリセットしたかったのにハードリセットしちゃって最初からコード書き直しとか。
ありますね。なんで、もちろんGitにすごい詳しければ詳しいほどいいんですけど、実際働いてるエンジニアはですね、どれくらいGitのことを知ってるんだっていうのをちょっと皆様にリアルを届けようかなと思っていて、これぐらい知ってればいいんじゃねみたいな話をしたいと思います。
よく使うコマンドの解説
どんとこい。
はい。じゃあまずはですね、よく使うコマンドを言っていきましょうか。
よく使うコマンド。一番よく使うのはこの3つですよね。add、commit、push。
そうですね。それぞれ何ですか。
それぞれ。まずGit addはステージングに挙げるというか、このローカルリポジトリの中での、いわゆる次コミットするトラッキング対象のファイルをaddしていくっていう意味のコマンドですよね。
そうですね。で、コミットは、コミットを作る。
はい、コミットを作る。その時、その、はい、コミットを作る。その時のスナップショットを撮るみたいなGitですよね。
そう、なんかGitってスナップショットを撮るんだっけ。なんかスナップショットっていう概念があるのかないのか。怪しいんだよな。
なんか、怪しいというか、多分説明する人によってって感じですよね。
まあまあ、なんというか、ディフを積み上げていくみたいに理解しても、おおむね業務では問題ないですね。
あの、ちょっと最初に言うの忘れましたけど、別にGitの正しい説明しないので、話半分にしてください。
本当にそうだ。これ、ちょっと適当な説明すると全然まさかりが飛んでくる領域だから気をつけなきゃいけないです。
ちゃんとしたやつを知りたい人はもちろん公式ドキュメントを見ていただくんですけれども、
あのですね、私が前所属していた株式会社ミクシーが出している新卒向けの研修資料にGit研修というものがあって、
そこでもうベーシックな内容からアドバンスの内容まで本当に詳しく書かれているので、詳しく知りたい方はそれを参考にしてください。
はい、という前提を置いた上で、まず話を申しますが、プッシュは何ですか。
プッシュはコミットした段階で、そのコミットがローカルリポジトリ、自分の手元だけに作られますよね。
プッシュっていうのは、言ってみたらリモートリポジトリ、あの、チーム開発をしていたら複数の人が触る、
言ってみたらウェブ上にあるGitHubみたいな、そういうところにそのコミットを反映する作業になりますね。
そうですね。じゃあ、プッシュと対別してよく使われるプルについて教えてください。
プルは、本当にその逆でリモートリポジトリのコミットをローカルリポジトリに反映する作業ですよね。
そうですね。なので、アットコミットプッシュプル、これはよく使うかなと思います。
そこからさらにいろいろあるとして、チェックアウトとかブランチですかね。
そうですね。スイッチ、僕まだ未だにスイッチじゃなくて、チェックアウト-Bでブランチ名指定してやりますね。
自分もそのパターンですね。もうGCBっていうエイリアス切ってるから、もうスイッチとかやってない。
それは賢い。そうですよね。本当にGit、いろいろなコマンドがあるから、結構それこそ、
自分のバッシュRCの中で短いコマンドエイリアスを育ててる人たちはたくさんいますよね。
そうですね。Git、チェックアウトって何でしたっけ。
Git、チェックアウトは言ってみたら、ざっくり言うとブランチの移動ですよね。
Gitの中でヘッドっていう概念があって、自分が今いる最新のコミットですよね。
それを別のブランチの最新のコミットに移動するっていうコマンドだと何となく理解しています。
そうですね。もしかしたらブランチじゃなくて、コミットにも移動できるかもしれないんですけど。
そうですね。コミットにも移動できるし、あと何ならタグにも移動できますよね。
そうですね。Gitブランチは何ですか。
Gitブランチはオプションなしで使うと、その今いるヘッドから新しいブランチの名前を作るって何ならそっちに移動するのかな。
あとよく使うオプションとしてブランチ-mかな。今いるブランチの名前をリネームする。
使ったことない。
本当ですか。
そうなんだ。
そうか。
普通にGitチェックアウト配布しちゃうかも。
確かに確かに。そこで何というか、ブランチ名間違えちゃった時とかはブランチ-mでよく切り替えてますね。
そうなった。なるほどね。
ブランチの概念はあんまり説明しないんですけど、コミットに名前つけるみたいなニュアンスが近いのかな。
そうですね。おおむねそう考えておいて差し支えないでしょう。
じゃあそのお友達のGitタグについても。
Gitタグは僕の理解では言ってみたらコミットに目印をつけるみたいな作業かな。
それこそよく使うユースケースとしてはメインブランチのこのコミットをバージョン5としてリリースしましたよみたいな時にそのコミットにバージョン5っていうタグをつけておいて、
そうすると後からそれこそチェックアウトして移動しやすかったりとか後から追いやすいっていうメリットがありますよね。
リベースとその他のコマンド
そうですね。ブランチの違いはブランチはどんどんコミット積んでいくと積むたびにそのブランチの札先が変わっていくんですけどタグは変わらないっていう性質がありますね。
そうですね。あとそれこそ複数のブランチに同じコミット履歴が存在するみたいな状態もあり得るじゃないですか。
例えばメインブランチとフィーチャーブランチがあってそのフィーチャーブランチにもまだメインにマージしてなかったらそのメインから入っていった同じコミットハッシュが積まれてるみたいなタイミング。
そういう中でタグっていうのはそのただ一つのコミットハッシュを指し示すことができますよね。
そうですね。はいじゃあ次に使いそうなやつでマージとリベースの話をしましょう。
いいですね。マージはその例えば複数2つ以上のブランチがあるときにその片方のブランチ。
そうだなちょっと説明が難しいですね。端的に言うと片方。
ブランチじゃなくてもコミットでいいんじゃないかな。2つのコミットこうグイってやるか。
ちょっとファストフォールとかそういう話はちょっと一旦端折りますけど。
そうですね本当に片方のコミットをもう片方のコミットにまず状態としては行動の状態としては合体させて
そのいわゆる一つの歴史としてコミットの履歴として成立するようにする作業ですよね。
どういう時に使います?
それこそフィーチャーブランチで一つ機能を開発しました。それをリリースするためにもともとあったメインブランチにマージして
開発中の機能ではなく正しい流れに乗ったものですよみたいな感じする。ちょっと説明が難しいな。
じゃあ次リベースですね。
リベースはちょっとこれは本当に申し訳ないんですけど、僕はリベースのコンセプトを理解しきれていないです。
というのも僕リベースをやるとき、そうだな、git rebase-i っていうコマンドしかほぼ使わなくて
これ何かっていうとあれですよね、自分のヘッドから過去複数のコミット履歴をリストにして
言ってみたらあれですよね、まとめられるコミットをまとめていく。
僕逆にそういう用途でしか使ってないですね、リベースは。
例えばGitHubとかでプルリク作るときに最新のメインが先に進んでるケースがあるじゃないですか。
で、アップデートブランチとか押すとマージコミットが作られるときもあると思うんですよ。
あれをリベースにすると、もともとたとえばひめのさんがAという小字を入れるときってある時点のメインからAを生やすじゃないですか。
そうなんだけどリベースすると先に進んだメインをベースにしてAを生やすことになるんですよね。
はいはいはいそうですね、確かにおっしゃる通り、そうかマージじゃなくて、
もう過去積み上がった本流の履歴に僕らのフィーチャーブランチの履歴を上乗せするみたいなマージの仕方になるってことですね。
そうですね、なのでチームの状況にもよりますけど、リベースを使った方がGitのコミットの履歴としてはきれいになる。
例えばひめのさんがおっしゃってた-iを使ってコミットを圧縮するというか、整えるというのも含めてですけど、順番並べ替えるとかね。
確かに、なんかそうだ、なんかそれこそGitの教本とかでそういう説明のされ方をしてるけど、普段使わなくてもうその機能を全く忘れてました。
そうですね、僕は別にマージの方が楽なのでマージ派なんですけど、リベース派の人もいらっしゃいます。
そうですね、中にいますね。他に何かあるかな、よく使うコマンド。
ありますね、まずリセット。
あったあった、リセット。
リセットのハードとソフトとミックスと説明できますか。
フィックス?
ミックスと。
ミックスと、すいません、ちょっと僕今ミックスとっていうオプションがあることを初めて知った。
デフォルトがミックスですよ、多分。
あ、そうなんですね。
確かに違うかな。
普段ソフトかハードか必ずどちらかを指定してた。
それで言うとリセットっていうのは本当にもう文字通り今いるコミットの履歴をリセットする作業で、
ハードだとそのコミットの履歴自体が消える、でかつそのコードの変更自体もなくなる。
一方でソフトはコミットが一旦なくなるが、そのコミットで行われてた変更が、
言ってみたらコミット前のトラッキングされた、ステージングに上がった状態に戻るみたいな。
それはミックスをですね。
あ、そうなんですか、なるほど。
あ、違う、嘘ついた、嘘ついた、ごめんなさい、嘘ついた。
ソフトはステージング状態のままで、ミックスではステージング状態じゃないですね。
ソフトはトラッキングされてない状態に戻るってことですね。
ステージングされてない状態かな、本当に。
初めて知った。
別にとりあえずGitReset使っておけば戻したい時は戻せるよねっていう話ですね。
そうですね。
あとはクローン。
あ、GitClone、そうですね、それこそ一番最初に何かしらのプロジェクトに入りました。
リモートリポジトリを手元に持ってくるときにクローン使いますね。
個人的に。
それぐらいですよね。
個人的に僕は手元でいっつもGHQっていうツールを使っていて、
GitCloneじゃなくてGHQgetっていうコマンドで持ってきてますね。
使いますね。あれ多いですね。
基本的なGitコマンド
あとそうな、今思い出したんですけど、僕Gitでよく使う好きなコマンドがあって、
GitStashです。
あー、はいはいはい。
GitStashっていうのは何かというと、手元で変更してたりとか、
あとはステージされているファイルの変更をコミットはしないけど、
一旦チェックポイントを付けるというか、その状態で保存できる機能になります。
どういうときに便利かっていうと、例えば手元でコードをガシガシ書いてましたってときに、
デビュー依頼されて、そうかこっちのブランチを見なきゃいけないってときに、
スタッシュして変更を置いておいて、このブランチを手元に持ってきて動作確認するとか。
そういうときに使いますね。
コミット履歴の管理
ちなみにスタッシュして作られるのはスタッシュじゃないですか。
スタッシュを戻すときはGitStash Popですね。
あとはGitFetch。
GitFetchは正直あんまり使わないけど、言ってみたらあれですよね。
僕の理解では、FetchとMergeが合体したコマンドがプルですよね。
そうですね。リモートの変更を確認したいときに使うとか、持ってきたいときに使うって感じです。
リモートの変更を手元に持ってきて、ただローカルリポジトリに実際にMergeはしないみたいな。
そうですね。
ありますね。でもさすがにこんなもんかがよく使うのは。
いや、もっとありますよ。
本当ですか。リドルさんどうぞ。
まずGitDiffを使いますね。
GitDiff。本当に申し訳ないんですけど、GitDiff普段ほとんど使わず。
IDでやる人じゃん。
いや、DiffしたいときはGitHubにあげて。
そうなんだ。
プルリク作らない手前のDiffが見える画面があるじゃないですか。あれで見たりしてます。
なるほど。GitDiffっていうのは、状態はいろいろ定義できるんですけど、何の修正を自分でしたかっていうのが見れたりとかするんですよね。
そうですね。
これCIでもよく使いまして、GitDiffの何だっけ、-9かなオプション付けると、このコミットにどういう差分があるかっていうのをファイルで一覧出力できたりとか、そもそも差分があるのかないのかをチェックできたりとかするんで、結構CIでも使いますね。
そうですね。本当に。例えばファイルの自動生成するコマンドを実行して、ファイルDiffが生まれてたらCIを落とすみたいな、そういうスペースありますよね。
そうですね。あとはGitStatus、GitLogかな。
GitStatus、GitLogはそうですね、よく使いますよね。
GitLogは自分のコミット履歴とか見れるんで、結構何やったっけ、これ多分ツールというかWebとかGUIで見る人も多いと思うので、叩かない人もいると思います。
そうですね。確かに。
GitStatusはどうぞ。
実際に今僕がいるチームでも、ソースツリーっていうGUIのGitを管理できるツールがあるじゃないですか。あれを対応してる人もいる。
ソースの人によって割とやり方は別だけど、やってることは同じという感じですね。
そうですね。
あとGitStatusは、さっき言ってたステージング状態とか、コミットされたかどうかみたいな、そういうのが見れるので、大体頻繁に叩くことになるかなと思いますね。IDとかで見ない限りは。
確かに確かに。そうか、IDか。なんか僕よくGitコマンドとやっぱり併用して、VS Codeのファイルディフとかをボタンでコミットできる画面があるじゃないですか。
基本的にそのハイブリッドで使いますね。
分かりますね。そういう方結構しますね。
あとはGitRMとGitMove。
GitRM。あー、はいはいはい。ありますね。GitRM、GitMV、Moveですよね。
そう、だいぶ。僕それぞれ単純に、GitRMはファイル削除なんですけど、通常のRMだと残っちゃうので、Git上に。
RMだとちゃんと消せるよっていうやつで、Moveはファイルの移動の場合、通常のMoveだけ使うと完全に新しいファイルとして扱われちゃうんですけど、GitMoveすると今までの履歴とかを残して移動できるので、
基本的にGit管理されたリポジトリでの移動はGitMoveを使いましょうというのが主要概念になってますね。
Gitの応用と確認作業
そういうことだったんです。僕はGitMoveの功用を完全に理解してなかった。
そうね、GitMove使わないとさ、後でヒストリ追えないからさ。
僕それこそ、それについては本当にあれじゃないですか、Git使ってると普通のMoveでもヒストリ引き継がれることはあるじゃないですか、単にリネーム扱いになって。
僕、何かそういうことが起こってるなと思って、リネームが必要な時はリネームだけで1回コミットを積むみたいなことをすると、履歴が引っ付かれるなと思ってずっとそうしてました。
そうなんだ。
でも明日から使います。
ありがとうございます。
ぜひ使ってください。
あとは、これ使ってる人は使ってるんですけど、Kerry Pickとかですかね。
Kerry Pickはそうだ、使いますね。
何かそれこそあれですね。
例えば機能開発の時にまず自分の、何だろう、例えば結構大きい機能だと、古力としてレビュー出すときは複数個に分ける。
それはレビューの、レビュアーの負担を減らすためにみたいなこともあるじゃないですか。
とはいえ、手元で動作確認するときはその大きい機能を1つ、1つの場所で作らなきゃいけないみたいなときに、何か自分の手元で大きい機能を作って動作確認できたらコミット1つ1つをKerry Pickでそれぞれ別のブランチに持っていくみたいな作業をしますね。
結構便利ですよね、独占のコミット持ってくるとか、そういうふうに使えるから。
そうですね。あとなんか地味にそれこそGitの状態、ブランチの状態が複雑になって、何かよくわからないコンフリクトがめちゃめちゃ起こっちゃったみたいなときに、言ってみたらそのブランチを直す作業というか、Gitチャレンジするときに使いますよね。
そうですね。結構便利なんですよ、Kerry Pickなんか。
わかるな。
でもちょっと中級者向けなコマンドの感じがありますね、Kerry Pickは。
そうですね。あとKerry Pickで綺麗にコミットを持ってこようとすると、やっぱりそれこそコミット1つ1つのビュードとかも結構気を使ってないとうまくできないですもんね。
そうですね、ありますね。あとはGitブレイム。
Gitブレイムありますね。
犯人探しコード。
僕Gitブレイムについては手元で叩いたこと1回もないかもしれないです。
GitHubとかIDにあるからね。
GitHubのUIでそれこそできるじゃないですか。
そうですね。Gitフレームは誰が更新したのかっていうのが見えるんですよ、コードの行ごとに。
だからこの変更したのは誰だよみたいなのを見たいときはブレイムで見て、自分じゃんってなる。
そうですね。もちろん犯人探しだけじゃなくて、この行の変更はどのタイミングで変更されたものかみたいなのを追うときにも便利ですよね。
それこそこのタイミングでこの変更が入ったから、
例えばデータ分析のときこういう結果が出ているのはおそらくこれが原因だろうみたいなことの確認をするためにとか。
そう、それ使い方結構しますね。
ありますね。
あとはちょっと細かいんでパパって言っちゃいますが、GitのReflogとか、
Reflog出た。
GitのWork3とか、
GitWork3。
あとGitCleanとか、そういうものをたまに使って、
ワークスペアの人によってはもっといっぱい使うかもしれないですけど、
そんな感じでだいたい20種類ぐらいコマンドを覚えておけば、あとGitConfigとか。
GitConfig、そうですね。
最初叩いてそんな叩くことはないかもしれないけど、そういうものがあるんで、
ちょっと後半の方はそんなに使用頻度高くないんですけど、
だいたい20個ぐらい覚えておけばそんなに困らない。
業務ではバリバリ。
業務ではそんなに困らない。20個多くないか。
20個もないんじゃないかな。
でも最悪、Add、Commit、Pushさえできれば業務はできる。
いや、チェックアウトできないと無理でしょ。
ああ、そうだった。
チェックアウト、スイッチか。
チェックアウトですね。
いやもう、でもあれですよ。
チェックアウトなら新しいブランチを作るのも、メインブランチに戻るのも一つでできるのね。
そう、チェックアウト-Bで生きていくしかないね。
そうですね。
そういう感じでですね、実際に働いてるエンジニアでもこれぐらいのコマンドにさえ知っておけば、
Gitに関しては特に困らないということを皆さんに共有できたかなと思いますので、
今回はこの辺にしようかなと思います。
このポッドキャストはハッシュタグライトで皆様からの感想やコメントを募集しております。
またチャンネル概要欄にGoogleフォームのリンクもありますので、そちらからのご投稿も大歓迎です。
ありがとうございました。
ありがとうございました。