Gitコマンド入門::rebase(-i,コミット入替え)「第二十四回」
みなさん、こんにちは! 今日は、コミット順番を入れ替えてみたいと思います! もう、ここまでやってきたので、お分かりだと思いますが、gitは差分管理なので、基本的には入れ替えなんて、、、そんな無茶なことして大丈夫なのか? って思うと思いますが、、、基本それで正しいです。(爆笑) じゃ、なんでコミットの入れ替え機能なんて出来るのか?! 答えは、複数ファイルにおいて、そのような事ができると便利だということなんですよね。
まあ~、前置きはこのぐらいにして、具体的に試して行きましょう!
前回の記事はこちらから!
git本家本元の情報はこちらから!
今回は、a.txt,b.txt,c.txt,3つのファイルを使います!
echo "# rebase exchange" >> README.md
echo "A" > a.txt
git add a.txt
git commit -m "A"
echo "B" > b.txt
git add b.txt
git commit -m "B"
echo "C" > c.txt
git add c.txt
git commit -m "C"
ここまでは、README.md の内容をコミット毎に変更しましたが、今回は、a.txt, b.txt, c.txtのファイルを、それぞれ追加した状態です。
ハッシュ値 | コメント | ファイルの中身 | 補足事項 |
---|---|---|---|
97926e9 | 1st | # rebase exchange | README.md を追加 |
01c48ba | A::a.txt | A | a.txt を追加 |
07804af | B::b.txt | B | b.txt を追加 |
7f44cc2 | C::c.txt | C | c.txt を追加 |
$ git log --oneline --reverse -p
97926e9 1st
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ba3d811
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# rebase exchange
01c48ba A::a.txt
diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..f70f10e
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+A
07804af B::b.txt
diff --git a/b.txt b/b.txt
new file mode 100644
index 0000000..223b783
--- /dev/null
+++ b/b.txt
@@ -0,0 +1 @@
+B
7f44cc2 (HEAD -> main) C::c.txt
diff --git a/c.txt b/c.txt
new file mode 100644
index 0000000..3cc58df
--- /dev/null
+++ b/c.txt
@@ -0,0 +1 @@
+C
git rebase -i --root
$ git rebase -i --root
// viが起動!
pick 97926e9 1st
pick 01c48ba A::a.txt // この行を一番したに移動してみましょう!
pick 07804af B::b.txt
pick 7f44cc2 C::c.txt
// 編集後は、こうなりますね。
pick 97926e9 1st
pick 07804af B::b.txt
pick 7f44cc2 C::c.txt
pick 01c48ba A::a.txt // 一番下に移動しました!
// Esc + wq でエディターの保存終了!
// なんの問題もなく成功!
Successfully rebased and updated refs/heads/main.
// 確認すると、順番も、1st -> B, C, A
$ git log --oneline --reverse
97926e9 1st
947efac B::b.txt
5de6b4c C::c.txt
c3e45b5 (HEAD -> main) A::a.txt
無事完了ですね!
まあ~、どのコミットも、ファイルが増えるだけですから、順番を変えても問題ありません。勿論、まだまだ、複雑なことも想像できるのですが、今は、シンプルに覚えて置きましょう。
[1]
実験: git rm a.txt で削除したら?$ ls
README.md a.txt b.txt c.txt
git rm a.txt
rm 'a.txt'
$ ls
README.md b.txt c.txt
$ git add . // <-- ピリオドは、全てのファイルを指します。
$ git commit -m "a.txt delete"
[main 757d814] a.txt delete
1 file changed, 1 deletion(-)
delete mode 100644 a.txt
$ git log --oneline --reverse
97926e9 1st
01c48ba A::a.txt
07804af B::b.txt
7f44cc2 C::c.txt
757d814 (HEAD -> main) a.txt delete
deleteコミットの後に、a.txtを移動!
$ git rebase -i --root
// viが起動!
pick 97926e9 1st
pick 01c48ba A::a.txt // この行を一番したに移動してみましょう!
pick 07804af B::b.txt
pick 7f44cc2 C::c.txt
pick 757d814 a.txt delete
pick 97926e9 1st
pick 07804af B::b.txt
pick 7f44cc2 C::c.txt
pick 757d814 a.txt delete
pick 01c48ba A::a.txt // 一番下に移動しました!
// Esc + wq でエディターの保存終了!
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-empty
Otherwise, please use 'git cherry-pick --skip'
interactive rebase in progress; onto 653a31d
Last commands done (4 commands done):
pick 7f44cc2 C::c.txt
pick 757d814 a.txt delete
Next command to do (1 remaining command):
pick 01c48ba A::a.txt
You are currently rebasing branch 'main' on '653a31d'.
nothing to commit, working tree clean
Could not apply 757d814... a.txt delete
はい! しっかりエラーになりました!(笑)
Google翻訳
以前のチェリーピックは、おそらく競合解決のために空になりました。
とにかくコミットしたい場合は、以下を使用してください。git commit --allow-empty
それ以外の場合は、「git cherry-pick --skip」を使用してください
進行中のインタラクティブなリベース。 653a31dに
最後に実行されたコマンド(4つのコマンドが実行されました):
7f44cc2 C :: c.txtを選択してください
757d814a.txtを選択して削除
次に実行するコマンド(残りの1つのコマンド):
01c48ba A :: a.txtを選択してください
現在、ブランチ「main」を「653a31d」にリベースしています。コミットするものは何もありません。
757d814を適用できませんでした... a.txt削除
それでは最後に、HEADを移動させて、その都度、lsコマンドで、ファイルの存在を確認してみましょう!
// 現状、私の環境は、rebaseして、このような並びになっています。
$ git log --oneline --reverse
97926e9 1st
bcddb69 C::c.txt
de3e7a1 A::a.txt
af2792e a.txt delete
45e0420 (HEAD -> main) B::b.txt
// では、1stにヘッダーを移動!
$ git reset --hard 97926e9
HEAD is now at 97926e9 1st
// 当然、README.md 1ファイルのみですね!
$ ls
README.md
// 次に、C::c.txtにヘッダーを移動!
$ git reset --hard bcddb69
HEAD is now at bcddb69 C::c.txt
// c.txt が追加されました!
$ ls
README.md c.txt
// 次に、A::a.txtにヘッダーを移動!
$ git reset --hard de3e7a1
HEAD is now at de3e7a1 A::a.txt
// a.txt が追加されました!
$ ls
README.md a.txt c.txt
// 次に、a.txt deleteにヘッダーを移動!
$ git reset --hard af2792e
HEAD is now at af2792e a.txt delete
// a.txt が削除されています。
$ ls
README.md c.txt
// 最後に、B::b.txtにヘッダーを移動!
$ git reset --hard 45e0420
HEAD is now at 45e0420 B::b.txt
// b.txt が追加されました!
$ ls
README.md b.txt c.txt
さあ~、ここまで、いかがでしたか? gitは、ファイル単体の差分だけではなく、ファイルの存在そのものも管理しているんですよね。尚、HEADの位置が変わると、、、あれ?ファイルが無いなあ~、なんてことも起こるので、そのあたりにも慣れて置きましょう。
それでは、今回はここまで、お疲れ様でした!
-
git rm コマンドは、おそらく、linuxの、rmコマンドのラッピングのみだと思うので、通常通り、
$ rm a.txt
でも問題ありませんが、いまのところは、git rm を使いましょう! ↩︎
Discussion