< Back

【git rebase -i】したときのコマンドをすべて試してみた(p, r, e,s ,f ,x ,d)

git rebase -i したときのコマンドをすべて試してみた(p, r, e,s ,f ,x ,d)

いわゆる git rebase -i HEAD~~ とかしたときに出てくる下のほうに出てくるコメントアウトされているコマンドのことを今回まとめます。

pick 85b703f update 2
pick 4d9e3ec update 3

# Rebase 5d6b0f5..1fc7711 onto 5d6b0f5 (6 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# 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.
#
# Note that empty commits are commented out
英語 なんとなく適当な日本語訳
p, pick use commit コミットを使う
r, reword use commit, but edit the commit message コミットを使うが、コミットメッセージを編集する
e, edit use commit, but stop for amending コミットを使うが、修正を止める
s, squash use commit, but meld into previous commit コミットを使うが、以前のコミットに混ぜる
f, fixup like "squash", but discard this commit's log message squashと似ているが、コミットメッセージは破棄する
x, exec run command (the rest of the line) using shell シェルを使用して、残りのコマンドを実行する
d, drop remove commit コミットを削除する

はじめに

これはgitの正確に記述しして、きちんと学んで形からはいる!!というタイプの記事ではないです。
実際に体験して、なんとなく理解してみようという記事です。

きちんとした記事は以下のようなのを参考にしてください。

実際に使ってみる

ディレクトリの作成とgitをスタートさせる。

$ mkdir git-work
$ cd git-work
$ git init
Initialized empty Git repository in /home/hirao/workspace/git-work/.git/

もし途中でgit操作を間違って最初に戻りたくなったら

$ rm -fr .git/
$ git init
# もうちょっといい方法ありますか…?

でやり直してください。

ファイルの作成

echo 'First line' >> text.md 
git add .
git commit -m 'init'

echo 'line2' >> text.md && git commit -am 'update 2'
echo 'line3' >> text.md && git commit -am 'update 3'
echo 'line4' >> text.md && git commit -am 'update 4'
echo 'line5' >> text.md
echo 'line6' >> text.md && git commit -am 'update 6'
echo 'line7' >> text.md && git commit -am 'update 7'
echo 'line8' >> text.md && git commit -am 'update 8'

一気上をすべてターミナルに流し込む。

ファイルの中身を確認してみましょう。!!

yk:git-work yk$ cat text.md 
First line
line2
line3
line4
line5
line6
line7
line8

ちゃんとファイルの中身があることを確認します。

そしてGITのコミットのハッシュを git log で確認しておきましょう

$ git log --oneline

6e4cd32 (HEAD -> master) update 8
607b771 update 7
da03d43 update 6
bf8452b update 4
89b026f update 3
da1c070 update 2
581d53a init

s, squash = use commit, but meld into previous commit を使ってみる

squashは use commit, but meld into previous commit というメッセージでしたね。私はコミットをまとめるときによく使ってます!。最初のコミットは init というコミットメッセージをつけたので、grepして見つけます。上のように git log --oneline で一番下のやつをコピペしても可能です。

$ git log --oneline | grep init

581d53a init

初回のコミットを取得する。次のコミット update 2 から編集できる。

git rebase -i 581d53a

以下のように編集して。 update2~3 をまとめてみましょう。

$ git rebase -i 581d53a

pick da1c070 update 2
s 89b026f update 3
pick bf8452b update 4
pick da03d43 update 6
pick 607b771 update 7
pick 6e4cd32 update 8

update2~3s オプションでの編集なので、コミットメッセージの編集ができます。以下のような感じ。

$ git rebase -i 581d53a

hint: Waiting for your editor to close the file... 
# This is a combination of 2 commits.
# This is the 1st commit message:

update 2

# This is the commit message #2:

update 3

これを

update2 and update3

へ変更。

$ git log --oneline  

0317cc1 (HEAD -> master) update 8
a1526af update 7
27bce0d update 6
764c9ea update 4
3e13197 update2 and update3
581d53a init

となりました。

e, edit = use commit, but stop for amending を使ってみる

間違って update 5 というコミットを作るつもりだったのに、 update6 にまとまっています。編集しましょう。

$  git log --oneline

0317cc1 (HEAD -> master) update 8
a1526af update 7
27bce0d update 6
764c9ea update 4
3e13197 update2 and update3
581d53a init

また init コミットまでのrebaseをしましょう。

git rebase -i 581d53a

出てきた画面で以下のように update 6picke に変更して、以下のようにする。

pick 3e13197 update2 and update3
pick 764c9ea update 4
e 27bce0d update 6
pick a1526af update 7
pick 0317cc1 update 8

以下のような感じになって、rebaseがストップします。

$ git rebase -i 581d53a

Stopped at 27bce0d...  update 6
You can amend the commit now, with

  git commit --amend 

Once you are satisfied with your changes, run

  git rebase --continue

最後のコミットを確認します。これを編集してコミットするか、リセットしてやりなおすか…

$ g show 

commit 27bce0d8e8e4c9ef38ae702d7259b72ee775e6a5 (HEAD)
Author: Yuki <author@example.com>
Date:   Mon Sep 16 21:41:29 2019 +0900

    update 6

diff --git a/text.md b/text.md
index a5e67f7..d3a7cc2 100644
--- a/text.md
+++ b/text.md
@@ -2,3 +2,5 @@ First line
 line2
 line3
 line4
+line5
+line6

一個前のコミットを削除しましょう。!! line5line6 という行を追加したコミットです。

$ git reset --hard HEAD~
HEAD is now at 764c9ea update 4

$ git log --oneline
764c9ea (HEAD) update 4
3e13197 update2 and update3
581d53a init

この時、 update 4 までしか表示してないのは、rebaseの途中で動作を止めるオプション e/edit を使ったからです。
コミット削除したら、一行ずつ追加してコミットしていきます。

$ echo 'line5' >> text.md && git commit -am 'update 5'
$ echo 'line6' >> text.md && git commit -am 'update 6'

ちゃんとコミットされているか、確認します。

$ git log --oneline
b9e284b (HEAD) update 6
fd9fe8c update 5
764c9ea update 4
3e13197 update2 and update3
581d53a init

大丈夫そうなら git rebase --continue して続けます。

$ git log --oneline

818cfad (HEAD -> master) update 8
b9fffe7 update 7
b9e284b update 6
fd9fe8c update 5
764c9ea update 4
3e13197 update2 and update3
581d53a init

これで5と6を分割できましたね。
ただしeオプションは、下手にやると update 7 以降のコミットによってコンフリクトが発生するので、置きをつけてください。

f, fixup = like "squash", but discard this commit's log message を使ってみる

メッセージの編集なしの s オプションと同じです。

$ git rebase -i 581d53a

pick 3e13197 update2 and update3
f 764c9ea update 4
f fd9fe8c update 5
f b9e284b update 6
f b9fffe7 update 7
pick 818cfad update 8

と最後のコミット以外をf オプションをつけて update2 and update3 にすべて統合してみましょう!!!
コミットメッセージが確認されずにコミットされましたね。

$ git log --oneline

4b3bee7 (HEAD -> master) update 8
0cd592f update2 and update3
581d53a init

コミット update6~8 がまとまりましたが、コミットメッセージは何も聞かれませんでした。これは f コマンドはコミットメッセージはそのままコミットをまとめるものだからです。

r, reword = use commit, but edit the commit message を使ってみよう

r を使ってコミットのメッセージを変更しよう。

$ git rebase -i 581d53a

pick 0cd592f update2 and update3
r 3c72cf0 update 8

するとvimが立ち上がるので

last commit 

と入力して閉じるとコミットメッセージが変更されています。

$ git log --oneline

1826743 (HEAD -> master) last commit
0cd592f update2 and update3
581d53a init

実は一番最後のコミットメッセージの変更でしたら

git commit --amend

で大丈夫です。

last commit (2)

に編集してみましょう。

$ git log --oneline
89a9f1c (HEAD -> master) last commit (2)
0cd592f update2 and update3
581d53a init

d, drop = remove commit を使ってみよう

実は最後のコミットは使わないコミットでした。的な場合は d オプションで消しましょう。

$ git rebase -i 581d53a

pick 0cd592f update2 and update3
d 89a9f1c last commit (2)

最後のコミットを消せたと思います。

$ git log --oneline
0cd592f (HEAD -> master) update2 and update3
581d53a init

$ cat text.md
First line
line2
line3
line4
line5
line6
line7

line8が消えました。

p, pick = use commit を使ってみる

今まで何回も使っていましたね。何もしないのが pick みたいです。

x, exec = run command (the rest of the line) using shell を使ってみよう

x コマンドはすごくいろんなことができるので調べてみると楽しいかもしれません。今回は先人たちの記事の紹介のみにとどめておきます。理由は、私がこれを使わなければいけないシチュエーションを思いつかなかったからです。

以下の記事では exec git stash pop; git commit -a --amend -C HEADexec ruby -e '$<.read == "Alfa\nBravo\n" ? exit(0) : exit(1)' < example.txt などが紹介されており、gitの他のコマンドを実行したり、rubyを実行したり、さまざまな使用例がありそうでした。

終わりに

git rebase -i のときのオプションはいかがだったでしょうか!

ドキュメントを読んで知っていたけど、実際に使ったのは初めて、というのもあるかもしれません。

最後まで読んでいただきありがとうございました!

.