Gitコマンド入門::rebase(-i,drop,その5,何故#Bの修正が必要なのか?)「第二十一回」
みなさん、こんにちは!
もう、表題の通りで、どうして、Aをdropすると、Bの修正が必要になるのか? しかも同じ内容で、add,commitすることになるので、普通に考えれば、只の二度手間です。(苦笑) そしてさらに、異なる内容で修正すると、こんどは、BとCでコンフィクトとなり、その次は、CとDと、数珠つなぎでコミットの修正を求められる。また、git rebase --skip を実行すると、今度は、Bが消える。dropしたいのは、Aだけなのに、Bまで消えていく、この操作も、やや理解に苦しみますけどね~ とにかく処理のパターンが増えてしまい複雑怪奇です。まあ~、なにはともあれ、途中をdropするのは、きっと実際ではレアケースで、クリティカルな変更を迫られたシーンのときに、使用する裏技に思えてきましたよ!(大爆笑)
とはとは言えども、ここで、ガッツリ勉強して置くと、なんか理解も深まりそうなので、さらに深堀り、実験を繰り返して見ますね!
次回の記事はこちらから!
git本家本元の情報はこちらから!
基本は、gitは、差分管理と心得て!
まあ~、何回か出てきましたけど、差分管理ですから、Aがdropされると、1stとBの間が、すっぽり抜けてしまいますので、1stとA、AとBの差分管理で整合性が取れなくなるのでしょう。で、Bの内容が、"# B"と同じにすれば、1stとBの間の差分情報が、再設定されて無事完了! おそらくその部分は、git側で自動処理しないのは、なんらかの理由があるのでしょう。
"# B"以外に修正すると、Cともマージコンフィクト
こちらの動作も、いきなり面をくらいますね。差分管理をしているので、ひとつ手前のコミットが書き換わると「もしくは、Aがdropされたりも同様」自分自身のコミットも修正しないと、過去との整合性も取れなくなるのでしょう。まあ、元のファイルをベースにして、いまがある。基本は、親子関係ですからね~ 親の苗字が変わったら、子も変わる。そんな関係を管理しているのが、gitそのものですからね。なので、Bが変わったら、Cも変わる。なので数珠つなぎに連鎖していくのでしょう。
"# B"以外に修正して、Cは、"# C"と同じにすれば!
ということで、Bを変更すると、こんどは、BとCで、マージコンフィクトになりますが、そこで、Cを、"# C"に、以前と同じ内容で、add,commit すれば、CとDのコンフィクトは発生しません。
ハッシュ値 | コメント | README.md | 更新 | 説明 |
---|---|---|---|---|
c0f998d | 1st | # rebase | - | - |
0fa830d | A | # A | drop削除 | - |
f8b5ccd | B | # B | # B+ | BとCの間で、コンフィクトが発生! |
2d138a2 | C | # C | # C | ここでは、変更しない。 |
cb468d1 | D | # D | - | 何も起こらず! |
では、実際にこの動作を試してみましょう!
- git rebase -i -root [1]
- Aをdrop [vi エディターの操作] [2]
- 1stとBのコンフィクトでは、# B+ と変更する。
- add,commit -m "B+"
- git rebase --continue
- BとCのコンフィクトでは、# C のままでとする。
- add,commit -m "C"
- git rebase --continue
1~4までの処理!
$ git rebase --root -i
// Aをdrop して、Esc + wq
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not apply f8b5ccd... B
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply f8b5ccd... B
$ git log --oneline --reverse
c0f998d (HEAD) 1st
// # B+ と編集する!
$ vi README.md
$ cat README.md
# B+
$ git add README.md
$ git commit -m "B+"
[detached HEAD a690765] B+
$ git log --oneline --reverse
c0f998d 1st
a690765 (HEAD) B+
5~8までの処理!
$ git rebase --continue
// 今度は、BとCでコンフィクトが発生!
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not apply 2d138a2... C
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 2d138a2... C
$ vi README.md
// # C と編集する!・・・前と同じ内容です。
$ cat README.md
# C
$ git add README.md
$ git commit -m "C"
[detached HEAD 5039c01] C
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline --reverse
c0f998d 1st
a690765 B+
5039c01 (HEAD) C
$ git rebase --continue
Successfully rebased and updated refs/heads/main.
$ git log --oneline --reverse
c0f998d 1st
a690765 B+
5039c01 C
ebb1ab2 (HEAD -> main) D
次は、1stとBで、コンフィクトした後は、全てskip
- git rebase -i -root
- Aをdrop [vi エディターの操作]
- git rebase --skip を繰り返す!
$ git rebase -i --root
// Aをdrop して、Esc + wq
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not apply f8b5ccd... B
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply f8b5ccd... B
// 1stとBでコンフィクト --skip実行!
$ git rebase --skip
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not apply 2d138a2... C
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 2d138a2... C
// 今度は、1st と Cのコンフィクト、マージエラー!
$ cat README.md
<<<<<<< HEAD
# rebase
=======
# C
>>>>>>> 2d138a2... C
// --skip実行!
$ git rebase --skip
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not apply cb468d1... D
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply cb468d1... D
// 今度は、1st Dのコンフィクト、マージエラー!
$ cat README.md
<<<<<<< HEAD
# rebase
=======
# D
>>>>>>> cb468d1... D
// --skip実行!
$ git rebase --skip
Successfully rebased and updated refs/heads/main.
// 結果、1stのみとなる。
$ git log --oneline --reverse
c0f998d (HEAD -> main) 1st
まとめ::その1
gitは差分管理なので、dropやeditした場合は、親子関係の再構築、ファイルの内容は同じでも、add,commit で再設定する必要がある。尚、--skipすると、そのコミットが省かれる。その動作は、dropと同じです。そもそも、このコマンドを使うのはレアケースであると思います。ただ、gitの仕組みを理解するには、とてもよいきっかけとなりましたね。(^^;;
まとめ::その2
Aを、drop すると、Bの立場からすれば、A=親が急にいなくなったと同じ、その親の1st=を新しい親だと認識する。ただ、1stと、Aとはファイルの差分が異なるため、コンフィクトエラーとなってしまう。従って同じ内容でコミットすることになるけども、1stとBの差分情報が更新されて、無事、親子関係を設定して完了! 今の時点では、このように解釈して置きましょう![3]
次回の課題
edit にて、コミットの分割、また、editにて、B=子、C=孫、D=ひ孫が、変化することも、試して見たいと思います!
それでは、今回はここまで、お疲れ様でした!
Discussion