🎸

個人的Git利用法

2020/10/11に公開

「Gitの使い方」みたいな初心者向け記事は一杯あるのですが、私は割とそういう記事に書かれているのとは違うやり方を使うので、ちょっと書いてみます。
このやり方を真似すべき、とは言いません。ただ、こんなやり方もあるんだなと思ってもらえればいいかと思います。
割とコミット履歴改竄してしまう派なので気に食わない人も多いと思います。リモートリポジトリに影響を与える操作に関しては、共同開発ならコミュニティやリポジトリオーナーの意向に合わせるので、必ずしもこの通りにする訳ではありません。

リモートリポジトリを作る前にローカルで初期化する

個人プロジェクトは大抵の場合、リモートリポジトリを作成してからcloneではなく、ローカルである程度作業してからリモートリポジトリを作ってpushすることが多いです。
ローカルリポジトリ初期化まで含めてやってくれるcliツールもありますし。cargoとか。
そのため、こんな感じでコマンドを実行することが多いです

git init
git commit --allow-empty -m "Initial commit."
git remote add origin git@github.com:kazatsuyu/example.git
# ここでpushする前にリモートリポジトリを作っておく
git push --set-upstream origin master

最近はgithubのデフォルトブランチがmainになったりしたようですが、少なくともgitコマンドが変わらない限りわざわざmasterをmainにリネームするつもりはないです。

共同開発の場合、ローカルのデフォルトブランチは消す

masterやmainなどのデフォルトブランチは、その性質上頻繁に更新されます。
ですので、たまたまcloneした時点でorigin/masterと同じコミットを指していただけのブランチを保持する意味はないと私は考えています。1分後には変わっている可能性すらありますし。
個人プロジェクトの場合はmasterのままコミットを増やすこともありますが、共同開発の場合は消してしまいます。

git clone git@example.com:foo/bar.git
cd foo
git switch -d
git branch -d master

リモートの最新に切り替えたい時は、

git switch -d origin/master

で可能です。

HEADにコミットする

特定の機能の実装やバグ修正などに着手するとき、トピックブランチを作らずにorigin/masterに移動して作業開始することが多いです。
ある程度作業が一段落してコミットをする時、デタッチされた状態なのでHEADだけが移動することになりますが、特に気にせず実行します。
コミットが終わってから

git switch -c feature/foo

としてトピックブランチの作成と切り替えを行うことも多いです。

pullは使わない

まあこれは同じようにやっている人も多いかと思いますが、pullは利用しません。
そもそもローカルにmasterがあるからpullをしなければいけないのです。masterを消してしまえば必要がありません。
自分が作業中のトピックブランチならpullしなければいけないようなこともまずありませんし。
リモートと同期をしたい場合はこうです。

git fetch

必要に応じて--prune, --recurse-submodules, --all などのオプションも利用します。
fetchはリモートブランチを更新するだけなので、fetchを終えた後にコミットを移動したい時はswitchを使います。

rebaseは結構使う

rebaseは使わない方がいい、という主張があることは知っていますが、私は頻繁にrebaseを使います。
もちろんデフォルトブランチやリリースタグの付いた場所をrebaseしたりはしませんが、ローカルでの作業中やトピックブランチでの作業中はよくrebaseを実行します。
これは好みの問題だろうと思うので特に推奨はしません。業務ではMR中(業務はgitlabを使っている)にもrebaseしたりしますが、これはプロジェクトメンバーと話し合ってOKかどうか決めておくべきことですね。

stashは短時間で使う

1ヶ月前にstashしたコードが何なのかなんて思い出せないので、長期に渡って保持するつもりがある作業コードは素直にトピックブランチを生やします。
stashを使うよくあるケースは、「origin/masterから作業を開始するつもりだったのに別のトピックブランチから作業を始めてしまった」みたいな時です。
switchで切り替えることができるケースもありますが、複雑な差分が生まれるとswitchはできないので、その場合はstashしてからswitchして、即座にstash popをします。
たまにstash popでコンフリクトが発生することもありますが、そういう場合は何をどうやってもコンフリクトするので素直に直します。
また、stash popの途中でコンフリクトが発生した場合、コンフリクト解消してもスタッシュが残り続けてしまうのでstash dropで消します。

commit -aは使わない

これは同じようにやってる人も多いと思いますが、事故防止のためにもaddcommitは分けて行います。
まあコミットの段階なら事故っても直せばいいんですが。pushしてしまってもrebaseする派なのでmasterに入らない限りはrebasecommit --amendで直しちゃいますが。
とは言え事故ったことに気づかないこともありますから、差分を確認しながらaddを行って、その後commitをします。
addはVSCodeのGUI上で行うことが多いです。commitはコマンドラインから叩きます。

GIT_PS1_DESCRIBE_STYLE=branchを使う

git-promptの話です。
デフォルトの設定だと__git_promptはデタッチされた状態で((deadbee...))のようにコミットハッシュを表示するのですが、こうしておくと((feature/foo))((remotes/origin/master))のように表示してくれるので、私のようにだいたいいつもデタッチしている者には合っています。

Discussion