0
1

rebase(Git管理)

Last updated at Posted at 2024-08-03

Gitにおけるrebaseについて

なぜこの記事を書こうと思ったのか

自己紹介については前記事を参照願います。
https://qiita.com/nuhaha_2023/items/6821f5dec3d1f7703a8f

エンジニア経験は1年のフロントエンドエンジニアなのですが、
現場入ってみてからよく聞くんだけど、なんとなく「食わず嫌い化」してしまっていることが増えてきました!
前回記事では「cherry-pick」に関することを書いたのですが、今回はタイトルの通りに、Gitの「rebase」に関することを書いていきたいと思います。それではよろしくお願いします!

まずは

Q1. Rebaseって何かと?

「リベースは、現在の作業ブランチを最新の状態に更新し、コミットの履歴を整理する方法です」

Q2. 使い方をイメージするにはどんな運用を行う?

ローカル上で作業を行い、適宜コミットを行う。
基本的にgit add、commitを繰り返し実行していくことでコミットが溜まっていきます。

git add <ファイル>
git commit -m "変更内容"

コミットが多すぎる状態だとプルリクを投げたレビュワーからしてみると見づらい!!とのこと。

そこでRebaseを使用して、コミットを整理し、まとめることができます。

例え話として

前回記事で書かせていただいた内容と似ているのですが、
https://qiita.com/nuhaha_2023/items/6821f5dec3d1f7703a8f

今回も、gitをおつかいに例えて見たいと思います。
まず、ローカルの開発は「個人」であり
リモートは、「共有場所」であります。
おつかいで一人で買い物に行っている時間、これはローカルです。
おつかいにいった結果を家で共有する、これがリモートです。

立場的には、
お使いを依頼するお母さんが「レビュワー」
お使いを頼まれる子供が「開発者」
お使いに行け!!!と指示されるお父さんが「開発者」
。。。。

初回コミットとHEADの最終コミットのコード(index.html)

初回コミット時(まだ何もしていない)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
</body>
</html>

2回目コミット時(買い物カゴを持ちました)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>買い物カゴを持ちました</h1>
  <ul>
    
  </ul>
</body>
</html>

最終コミット時(お会計が終わって帰宅)

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>買い物カゴを持ちました</h1>
  <ul>
    <li>りんご</li>
    <li>ブドウ</li>
    <li>いちご</li>
  </ul>
  <div>会計をしました</div>
  <h2>帰宅しました</h2>
</body>
</html>

GitLogで出力したコミットの履歴

81fb9f77071bc4ba45d069e3c3aae1ffbd0505ab 帰宅しました  (HEAD -> main)
961face8e94740185c9bbbfeda55cbf27e560d3b お会計をしました。3000円でした。 
b327b91ebc2d5f27d1c06dfa59f283e6f9000d0f いちごを買い物かごに入れました 
cfe15fc704e49c08dd9ded2ef310350ea9e897ba ブドウを一つ入れました 
76980b6eab62602726f7db6b60a75780fd39d4c8 りんごを買い物かごに追加しました 
84e16ed3db008fd824f47850a06ea5c6f35cbd78 買い物カゴを持ちました 
57d03fda3641ec16724488d27d31ec9b5c60a897 お店に入ってきました 

初学者(子供)だったらこれでも問題無いんだけどね

レビュワーである「お母さん」は、子供におつかいを依頼していた場合に色々な出来事ですとか、こんなことをしたんだよ!とか時間をかけて耳を傾けてくれるでしょう。経験の浅い初学者なんかだったら多少は許されます。
このままHEADが存在している最終コミットの状態でリモートにpushしてしてプルリクしてしまえばいいのです、
多分今まで許されていたのは、
①「初学者だからまぁいいか」
②「話長いけど結論問題なさそうだからとりあえずマージしま〜す。ウィ〜」
のどちらかでしょう。

経験者だったらどうでしょうか?

今まで何度もおつかいを経験しているお父さんが、レビュワーであるお母さんに対して帰宅後の雑談、
「とりあえずお店入ってさ〜買い物かご持って〜りんごを買い物かごに入れて〜〜ブドウを〜いちごを〜」

お母さん「つまらない話ばっかしてないで少し黙れ!!!!!!!!!こっちは忙しいんだ!!!!!!!」

となります。(この話はフィクションです)

だ!か!ら!リベースを実行して、出来事をまとめましょう!!!

※生きるために!!!

もう一度最終コミットのindex.htmlを確認する

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>買い物カゴを持ちました</h1>
  <ul>
    <li>りんご</li>
    <li>ブドウ</li>
    <li>いちご</li>
  </ul>
  <div>会計をしました</div>
  <h2>帰宅しました</h2>
</body>
</html>
81fb9f77071bc4ba45d069e3c3aae1ffbd0505ab 帰宅しました  (HEAD -> main)
961face8e94740185c9bbbfeda55cbf27e560d3b お会計をしました。3000円でした。 
b327b91ebc2d5f27d1c06dfa59f283e6f9000d0f いちごを買い物かごに入れました 
cfe15fc704e49c08dd9ded2ef310350ea9e897ba ブドウを一つ入れました 
76980b6eab62602726f7db6b60a75780fd39d4c8 りんごを買い物かごに追加しました 
84e16ed3db008fd824f47850a06ea5c6f35cbd78 買い物カゴを持ちました 
57d03fda3641ec16724488d27d31ec9b5c60a897 お店に入ってきました 

ログから確認したいと思うのですが、まずレビュワーであるお母さんは
開発者のお父さんの買い物の動線とか出来事は割とどうでも良いのです。
つまり、要約する場合にまず、「買い物カゴを持ったという情報と」、「何を買い物かごに入れた」という情報の、つまらない話は聞いてくれません。レビュワーであるお母さんが欲しているのは、「買い物の合計金額」です。

まとめた理想的はこんな感じかな。

81fb9f77071bc4ba45d069e3c3aae1ffbd0505ab 3000円分買い物して帰宅しました  (HEAD -> main)
57d03fda3641ec16724488d27d31ec9b5c60a897 お店に入ってきました

こういう操作が実行可能なのが、Rebaseなんですね。

さぁ、やってみよう!!!

以下を実行

git rebase -i HEAD~6

実行するとこのようになります。何やらたくさん出てきますが重要なのは上端のpickが書いてある箇所です。他は使い方のコメントです。恐れずに。

pick 84e16ed 買い物カゴを持ちました
pick 76980b6 りんごを買い物かごに追加しました
pick cfe15fc ブドウを一つ入れました
pick b327b91 いちごを買い物かごに入れました
pick 961face お会計をしました。3000円でした。
pick 81fb9f7 帰宅しました

# Rebase 57d03fd..81fb9f7 onto 57d03fd (6 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
#         create a merge commit using the original merge commit's
#         message (or the oneline, if no original merge commit was
#         specified); use -c <commit> to reword the commit message
# u, update-ref <ref> = track a placeholder for the <ref> to be updated
#                       to this position in the new commits. The <ref> is
#                       updated at the end of the rebase
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.

vimコマンド入力画面。好きになれそうにない。

pick, squashについて。

rebaseではpickを基準として、squashの内容が取り込まれます。古いコミットが「pick = 基準」になるということも割とポイントみたい。

git rebaseを実行してから表示されるこの内容を

pick 84e16ed 買い物カゴを持ちました
pick 76980b6 りんごを買い物かごに追加しました
pick cfe15fc ブドウを一つ入れました
pick b327b91 いちごを買い物かごに入れました
pick 961face お会計をしました。3000円でした。
pick 81fb9f7 帰宅しました

このような形に書き換えます。(後で解説あり)

pick 84e16ed 買い物カゴを持ちました
squash 76980b6 りんごを買い物かごに追加しました
squash cfe15fc ブドウを一つ入れました
squash b327b91 いちごを買い物かごに入れました
squash 961face お会計をしました。3000円でした。
squash 81fb9f7 帰宅しました

rebaseコマンドの実行後、「i」を入力することで入力モードに切り替わり、pickなどの書き換えが可能になります。
pick, squshの書き換えが完了したらば、先ほどの「i」での入力モードを「esc」キーで解除し、
「:wq」を入力して「enter」キーを押します。(Vimコマンドなかなかとっつきづらいですが慣れるしかなさそうですね)

rebaseが完了したらば今度はコミットメッセージをまとめる

次にこのような形で画面が出力されます。

# This is a combination of 6 commits.
# This is the 1st commit message:

買い物カゴを持ちました

# This is the commit message #2:

りんごを買い物かごに追加しました

# This is the commit message #3:

ブドウを一つ入れました

# This is the commit message #4:

いちごを買い物かごに入れました

# This is the commit message #5:

お会計をしました。3000円でした。

# This is the commit message #6:

帰宅しました

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Aug 4 05:57:19 2024 +0900
#
# interactive rebase in progress; onto 57d03fd
# Last commands done (6 commands done):
#    squash 961face お会計をしました。3000円でした。
#    squash 81fb9f7 帰宅しました
# No commands remaining.
# You are currently rebasing branch 'main' on '57d03fd'.
#
# Changes to be committed:
#       modified:   index.html
#
~                                                                                                                                                                                                         
"~/Desktop/try/.git/COMMIT_EDITMSG" 40L, 991B

過去のコミットメッセージをどうするかが入力可能なため、不要なコミットメッセージは削除してしまいましょう。
最終的にこうなりました。

# This is a combination of 6 commits.
# This is the 1st commit message:

3000円分買い物して帰宅

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Sun Aug 4 05:57:19 2024 +0900
#
# interactive rebase in progress; onto 57d03fd
# Last commands done (6 commands done):
#    squash 961face お会計をしました。3000円でした。
#    squash 81fb9f7 帰宅しました
# No commands remaining.
# You are currently rebasing branch 'main' on '57d03fd'.
#
# Changes to be committed:
#       modified:   index.html
#
~                                                                                                                                                                                                         
"~/Desktop/try/.git/COMMIT_EDITMSG" 40L, 991B

ここまで出来たら
「esc」キーで入力モードを解除し、「:wq」を入力して「enter」キーを押します。

git log出力の結果

f56a27ea818ed78ead8dfd8f9b2b79aba9fb1acf 3000円分買い物して帰宅  (HEAD -> main)
57d03fda3641ec16724488d27d31ec9b5c60a897 お店に入ってきました 

まとまりました!!これで余計なコメントを残さずに、レビュワー(お母さん)にまとまった内容だけをcommitとして示すことができます!!

Vimの基本操作について

Vimを初めて使う方のために、基本的な操作方法を簡単に説明します。

  • 挿入モードに入る: iを押すと挿入モードに入り、テキストを編集できます。
  • ノーマルモードに戻る: Escキーを押すとノーマルモードに戻ります。
  • 変更を保存して終了する: :wqと入力してEnterキーを押すと、変更を保存してVimを終了します。

このようにして、Vimを使った編集が少しずつ慣れていくと思います。

追記

squashとpickのみをご紹介しましたが、
「reword」というものもあります。 これで過去のコミットメッセージを変更することが可能です。

感想

執筆しながら実行して見たのですがgitのコマンドとしてはなかなか難しいなぁという印象でした。
ルールが色々あるので、また調査しながらこの記事内容を更新していきたいと思います。ありがとうございました!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1