Git脱初心者の冒険 ~ force push は怖くない ~

# はじめに
force pushが怖いですか？
ええ、怖いですよね。わかります。

しかしとある現場にて、「どの様な状況でもforce pushは禁止」という現場があり、大変面倒な思いをしたことがあります。
Gitを使いこなしている方ならこの辛さ、わかりますよね？

本記事では、force pushに関わる便利なGitの機能を紹介しながら、force pushは有効的に使えれば怖くないし便利であるということをお伝えできば良いなと思っています！

# 1. Git Graphを見よう
みなさん、git graphは見ているでしょうか？
git graphを見ながら管理することで、コミット履歴を綺麗に保つことができ、以下の様なメリットを享受できます。

- 予期せぬ不具合が発生した際に、グラフで原因特定を素早く追うことができる
- グラフを見ながらGit操作することで、誤操作を減らすことができる
- 複数チームで同一リポジトリを触る時に、別チームの状況を確認しながら進められるため、コンフリクトが起きづらくなる

以降で紹介する機能は、graphを意識していることが前提になっていますので、ご注意ください！

# 2. rebaseを使おう
1を前提に、続いてはrebaseについてです。
rebaseとは、コミット履歴を直線的でクリーンな状態に保つことができる機能です。

```sh
# featureブランチなどにいる状態で
git rebase main
```

例えば、以下の様な状態の時

![](https://storage.googleapis.com/zenn-user-upload/0b2699aad984-20250111.png)

以下の様にマージしちゃってませんか？

![](https://storage.googleapis.com/zenn-user-upload/4678c2e1c3cc-20250111.png)

これをrebaseをすると以下になります。

![](https://storage.googleapis.com/zenn-user-upload/a4dcb29be0c4-20250111.png)

同じ「mainの内容を取り込む」という目的でも、こんなに綺麗に取り込めました！
不要なマージコミットも無くなって良い感じですね。

注意点としては、リモートブランチが既にある場合は、**force pushが必要になる**という点です。

# 3. cherry-pickを使おう
続いては、cherry-pickです。
cherry-pickとは、特定のコミットを選んで別のブランチに適用する機能です。

```sh
git cherry-pick <コミットハッシュ>
```

例えば、モノレポ構成のディレクトリで、バックエンドチームが先に開発したAPIを一時的に取り込んで、フロントエンドチームで動作確認したいという様な「自分の作業ブランチには含めたくないけど、一時的に取り込みたいコミット」がある場合に役立ちます。

![](https://storage.googleapis.com/zenn-user-upload/92c3b9694c00-20250111.png)

backendの作業をcherry-pickすると、以下の様にbackendの作業を取り込めます！

![](https://storage.googleapis.com/zenn-user-upload/cbc79d59ede2-20250111.png)

こちらも、もしリモートブランチがあってcherry-pickした内容を含めてpushしたい場合は、**force pushが必要です。**

# 4. amendを使おう
続いては、--amendオプションです。
amendは、一つ前のコミットを上書きする機能です。

```sh
# コミットメッセージだけを変更する場合
git commit --amend -m "新しいコミットメッセージ"

# エディタを開かずにそのままコミットする場合
git commit --amend --no-edit
```

例としては、直前のコミットメッセージを変更したい場合や、実装にtypoがあった場合などで役立ちます。
グラフだとわかりづらいですが、以下の様なコミットを残さず

![](https://storage.googleapis.com/zenn-user-upload/7bdb0b1f977a-20250111.png)

amendして直前のコミットにまとめましょう！

![](https://storage.googleapis.com/zenn-user-upload/a3bfa3e76611-20250111.png)

こちらも、もしリモートブランチがある場合は、**force pushが必要です。**

# 5. reset hardを使おう
続いては、resetの--hardオプションです。
reset hardは、任意のコミットへ強制的に変更する機能です。

```sh
git reset --hard <コミットID>

# もしくは相対参照を使って戻る
git reset --hard HEAD^
```

例えば、大きめのリリースを行なったもののデグレが発生してしまい、何が原因かパッとわからない場合などに便利です。
以下の様な状態でデグレが発生した場合に

![](https://storage.googleapis.com/zenn-user-upload/af1fad64fc32-20250111.png)

適当に作業用ブランチを切ります。

![](https://storage.googleapis.com/zenn-user-upload/94afa1afc8df-20250111.png)

作業ブランチでhard resetを実施し、原因を特定します。
下記コミットに戻して問題が解消したなら、次のコミットに問題があるとわかるので、原因特定が効率的になるとういわけです！

![](https://storage.googleapis.com/zenn-user-upload/79b1768a7df3-20250111.png)

もちろんこちらも、リモートブランチが既にあってpushしたい場合は、**force pushが必要になります。**

# 本当にforce pushは怖いですか？
ここまでforce pushに関わる機能を紹介してきましたが、優秀なみなさんならお気づきなはず。
そうです。これらの作業で発生するforce pushは、**自身の作業ブランチでしか発生しない**のです。

force pushが怖い理由は、**誤操作で壊したくないブランチに対してpushしてしまうのではないか**という危機感や実際に問題が起こった過去の教訓からだと思いますが、以下を考慮しておけばforce pushは作業効率UPのための、一つの有効な手段になってくれるはずです...！

- git graphを見て視覚的に現在のブランチやコミットを確認しながら作業する
- Githubなどで、force pushさせたくないブランチをロックしておく
- force pushするのは原則自身の作業ブランチのみであることを念頭に置いて作業する

これで危惧していたことは防止できるはずです...！

# おまけ
## GUIツールは使うべき？
個人的には使うことをおすすめします！
やはり、視覚的に確認しながら作業できることは、誤操作の防止につながりますし、graphを綺麗に保つことを前提にすると必須かなと思っているためです...！

...なんですが、**初学者の方はCLIを理解した上で、GUIツールを使うことをおすすめします。**

例えば、最近は少なくなってきましたが、Linuxマシンに入ってgitの操作をしたい場合に、GUIの操作しかわからないとgit操作を行えないですよね。
CLIを理解した上でGUIツールを触ることで、GUIツールの誤操作も減ることになるので、まずは本質を理解することは大事です！

（ちなみに私は使い慣れたsouce treeを使ってます）

## 履歴を持たない流動的なブランチ、verificationブランチを使おう
最近はCI/CD環境があることが当たり前になってきているので、pushをトリガーに環境へのデプロイをやってくれる仕組みにしている現場がほとんどだと思います。
そこで、develop環境等の開発・検証環境へのデプロイを、verification_devなどのブランチもトリガーにデプロイする様にしておくと、ブランチワークがすごく楽になります！

方法は上記でも紹介した、rest hardとforce pushを使って運用していく方法です。
verification_devを常にこの方法で運用することで、履歴を持たずに環境へのデプロイが可能になります！

例えば、以下の様な状態で

![](https://storage.googleapis.com/zenn-user-upload/b8f501df761a-20250111.png)

フロントの作業をdevlopブランチに取り込む前に検証したい！となったら、以下の様にreset hardとforce pushを行えば、簡単にデプロイできるというわけです！

![](https://storage.googleapis.com/zenn-user-upload/01411cf71e48-20250111.png)

終わったら、元のコミットに戻してpushしておけば、環境も元通りです！

# おわりに
いかがでしたでしょうか？
少しはforce pushが怖くなくなりましたか？笑

意外とノリでgitを使っている人も多いのではないでしょうか？？
git脱初心者のための、礎になれば幸いです！

最後に宣伝ですが、先日[PaPut](https://paput.io)というサービスのβ版をリリースしました！
日々のインプットを手軽にアウトプットできるサービスです！
是非手軽に使って、フィードバックいただけますと嬉しいです！
PaPutについてはぜひ[こちら](https://zenn.dev/mizuko_dev/articles/b2c2844b9438ab)もご覧ください！
Xもフォローしてね！！！