Gitコマンド入門::Gitブランチ機能(rebase,その3)第六十八回

4 min read読了の目安(約4100字

みなさんこんにちは! 今日もrebaseの続きを学習していきますね。公開リポジトリにプッシュしたコミットをリベースしてはいけない。そんな注意書きがありますけど、まあ~、言われてみれば当然ですね。公開するってことは、それなりに責任があるわけですし、そんなにむきになって、リベースしなくても、不都合はありませんしね。(^▽^;) マージでいいんじゃないかな? って、個人的には思います。

今日の学習は、こちら!

https://git-scm.com/book/ja/v2/Git-のブランチ機能-リベース
こちらのページの下段、Figure 43. 最終的なコミット履歴の下に移動、スクロールすると、ほんとうは怖いリベース という項目があるので、ここを学習して行きます。

前回の記事はこちらから!

https://zenn.dev/shiozumi/articles/8482fa655d19f5

git本家本元の情報はこちらから!

https://git-scm.com/book/ja/v2

同じ環境のシェルスクリプトも取得できます!

https://gist.github.com/1608ea24877848d5c76e075ae6c41108.git

では、いつもの環境づくり!

# --------------------
# フォルダー作成
# --------------------
mkdir func0068 && cd $_

# --------------------
# いつものgit init
# --------------------
git init

# --------------------
# master
# --------------------

echo "c1" > c1.txt
git add c1.txt
git commit -m "C1"

# --------------------
# my_01
# --------------------

git checkout -b my_01

echo "c2" > c2.txt
git add c2.txt
git commit -m "C2"

echo "c3" > c3.txt
git add c3.txt
git commit -m "C3"

git switch master

# --------------------
# you_04 + 05
# --------------------

git checkout -b you_04

echo "c4" > c4.txt
git add c4.txt
git commit -m "C4"

git switch master

git checkout -b you_05

echo "c5" > c5.txt
git add c5.txt
git commit -m "C5"

git switch you_04

git merge you_05 -m "C6"

# --------------------
# my_01 + you_04
# --------------------
git switch my_01
git merge you_04 -m "C7"


git branch -avv
  master 06e949b C1
* my_01  dde7801 C7
  you_04 0f2ca6e C6
  you_05 9622095 C5
  
git log --oneline --graph my_01

*   dde7801 (HEAD -> my_01) C7
|\
| *   0f2ca6e (you_04) C6
| |\
| | * 9622095 (you_05) C5
| * | 77eafab C4
| |/
* | 4c225cf C3
* | 94d26a2 C2
|/
* 06e949b (master) C1

git log --oneline --graph you_04
*   0f2ca6e (you_04) C6
|\
| * 9622095 (you_05) C5
* | 77eafab C4
|/
* 06e949b (master) C1

Figure 44. リポジトリをクローンし、なんらかの作業をすませた状態

まずは、ここまでの環境が出来たと思います。

git log --oneline --graph you_04

こちらの、C4 + C5 をマージした後に、リベースしてしまうと、C4コミットと、C6のマージコミットが無くなって、C4' が追加される。

git switch you_04
Switched to branch 'you_04'

git log --oneline --graph

*   05fa487 (HEAD -> you_04) C6
|\
| * 1d25454 (you_05) C5
* | 1f239f9 C4 // <!-- ハッシュ値 1f239f9 C4 を確認
|/
* a132c55 (master) C1

ハッシュ値 1f239f9 のコメントC4に戻り、rebase !

git reset --hard 1f239f9
HEAD is now at 1f239f9 C4

git rebase you_05
First, rewinding head to replay your work on top of it...
Applying: C4

git switch you_05
Switched to branch 'you_05'

git merge you_04
Updating 1d25454..7ba4f0b
Fast-forward
 c4.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 c4.txt

$ git log --oneline --graph
* 7ba4f0b (HEAD -> you_05, you_04) C4
* 1d25454 C5
* a132c55 (master) C1

you_05 ブランチのログは、C1 → C5 → [新]C4

  1. 7ba4f0b =「新」C4
  2. 1f239f9 =「旧」C4

リベース前のC4と、リベース後のC4の二つが存在することになりました。

次に、you_05 をマージします!

git switch my_01
Switched to branch 'my_01'

// 現状のログを確認してから。
git log --oneline --graph
*   6b8818c (HEAD -> my_01) C7
|\
| *   05fa487 C6
| |\
| | * 1d25454 C5
| * | 1f239f9 C4
| |/
* | 265dca8 C3
* | 2c81e3b C2
|/
* a132c55 (master) C1

// マージしてからのログを確認!
git merge you_05
Merge made by the 'recursive' strategy.

$ git log --oneline --graph
*   5ce5302 (HEAD -> my_01) Merge branch 'you_04' into my_01
|\
| * 7ba4f0b (you_05, you_04) C4 <!-- 「新」C4
* |   6b8818c C7
|\ \
| * \   05fa487 C6
| |\ \
| | |/
| | * 1d25454 C5 <!-- 枝分かれして、C6と「新」C4へ
| * | 1f239f9 C4 <!--「旧」C4
| |/
* | 265dca8 C3
* | 2c81e3b C2
|/
* a132c55 (master) C1

リベースしたものを取り込んでも、C4とC6が残る。

  1. 1d25454 C5 から枝分かれして、05fa487 C6 と、7ba4f0b「新」C4 に繋がっていますね。
  2. 5ce5302 最終コミットは、6b8818c C7 と、7ba4f0b「新」C4 をマージしています。

まとめ

みなさんは、いかがでしょうか? 今回は、一度マージしたものをリモートにpushし、その後から、又、リベースしてしまったときに起こる問題でした。[1]元のマージをブランチを、pullした人にとって、その後にリベースしたブランチをpullした場合、履歴が整理されるどころか、C4,C6などのコミットが、重複して残ってしまうので、さらに複雑な履歴ができあがるんですね。

それでは、今回はここまで、お疲れ様でした!

https://zenn.dev/shiozumi/articles/06d75a5b1432c5
https://twitter.com/esmile2013
脚注
  1. 今回は、リモートリポジトリを使わず、全てローカルブランチのみで、シミュレーションしてみましたので、よければ、GitHubにも実際にpushしてみてください! ↩︎