Gitコマンド入門::restore(marge,その2)「第十二回」

6 min read読了の目安(約5900字

前回は、コマンド操作に慣れるところを中心に、マージも一番シンプルなケースから入ってみました。そして、元に戻すためのコマンド、git reset --hard HEAD[1] も同時に学習できましたので、是非、しっかり覚えてくださいね。そして今日は、ちょっとだけ複雑なマージに挑戦していきましょう!

前回の内容は、こちらです!

https://zenn.dev/shiozumi/articles/21490ec9e54a28/

ブランチsubと、ブランチmainの両方が更新されている場合のマージに初挑戦!

とういうことで、前回は、ブランチsubのみ更新してマージでしたけど、今回は、main側も更新してから、マージするケースを試して行きましょう! これで複数人数での作業同時進行が可能になりますので、是非、がんばってください!

それでは、前回と同じところまで!

$ git branch
* main
// 初期状態は、mainブランチのみ

git checkout main
Already on 'main'
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

git checkout -b sub
Switched to a new branch 'sub'

git branch
  main
* sub
// subブランチの作成と切り替え!

$ echo "# sub add" >> README.md
$ git add README.md
$ git commit -m "3rd sub"
[sub 73bb8d5] 3rd sub
 1 file changed, 1 insertion(+)

$ git log
commit 73bb8d574be785614fa2166899c199eabe0159b7 (HEAD -> sub)
Date:   Sat Feb 13 13:52:44 2021 +0900

    3rd sub

commit b8c6432555dcffd05d0973179add7bbb19d39d5d (main)
Date:   Wed Feb 10 22:59:21 2021 +0900

    2nd commit

commit a467fbdd7e989b224f388e048823068a0f122d51 (origin/main)
Date:   Wed Feb 10 15:28:42 2021 +0900

    first commit
// subブランチの、README.md を変更して、コミット!

$ git checkout main
Switched to branch 'main'
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)
// ブランチをmainに切り替えて

echo "# main add" >> README.md
$ cat README.md
# test
# (^^)
# main add
// README.md を更新!

$ git add README.md
$ git commit -m "3rd main"
[main c06db10] 3rd main
 1 file changed, 1 insertion(+)

$ git log
commit c06db10cc3a3e02e68a69d4426acd6d4c7436e48 (HEAD -> main)
Date:   Sat Feb 13 13:53:39 2021 +0900

    3rd main

commit b8c6432555dcffd05d0973179add7bbb19d39d5d
Date:   Wed Feb 10 22:59:21 2021 +0900

    2nd commit

commit a467fbdd7e989b224f388e048823068a0f122d51 (origin/main)
Date:   Wed Feb 10 15:28:42 2021 +0900

    first commit
// README.md を変更して、コミット!

では、ここまでの作図で、再確認!

subとmainの順番が逆になっていますけど、まずは、ハッシュ値の確認をしてください。

ブランチsub、ブランチmain共に、README.mdを変更しました。この状態でマージしてみます。

$  git merge sub
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Google翻訳:
README.mdの自動マージ
CONFLICT(コンテンツ):README.mdの競合をマージします
自動マージに失敗しました。 競合を修正してから、結果をコミットします。

$ git status
On branch main
Your branch is ahead of 'origin/main' by 2 commits.
  (use "git push" to publish your local commits)

You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

Google翻訳:
ブランチメイン
あなたのブランチは「origin / main」より2コミット進んでいます。
(「git push」を使用してローカルコミットを公開します)
マージされていないパスがあります。
(競合を修正し、「git commit」を実行します)
(「git merge --abort」を使用してマージを中止します)
マージされていないパス:
(「git add <file> ...」を使用して解決をマークします)
両方が変更されました:README.md
コミットに変更が追加されていません(「git add」または「git commit -a」、あるいはその両方を使用)

当たり前ですけど、当然、自動ではマージできませんね。

さあ~ README.md の中身を覗いてみましょう!

$ cat README.md
# test
# (^^)
<<<<<<< HEAD
# main add
=======
# sub add
>>>>>>> sub

<<<<<<< HEAD から、>>>>>>> sub までを、どう修正するのかは、それぞれ編集したユーザーに確認しながら、修正することになりますね。

今回は、mainとsubの両方を反映するように編集を行います。

$ cat README.md
# test
# (^^)
# main add
# sub add

それでは、git add,commit,status

$ git add README.md
$ git commit -m "main sub merge"
[main c72eda2] main sub merge

$  git status
On branch main
Your branch is ahead of 'origin/main' by 4 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

$ git log
commit c72eda20b35fd2e31abb6c770676d54669e51b64 (HEAD -> main)
Merge: c06db10 73bb8d5
Date:   Sun Feb 14 14:31:18 2021 +0900

    main sub merge

commit c06db10cc3a3e02e68a69d4426acd6d4c7436e48
Date:   Sat Feb 13 13:53:39 2021 +0900

    3rd main

commit 73bb8d574be785614fa2166899c199eabe0159b7 (sub)
Date:   Sat Feb 13 13:52:44 2021 +0900

    3rd sub

commit b8c6432555dcffd05d0973179add7bbb19d39d5d
Date:   Wed Feb 10 22:59:21 2021 +0900

    2nd commit

commit a467fbdd7e989b224f388e048823068a0f122d51 (origin/main)
Date:   Wed Feb 10 15:28:42 2021 +0900

    first commit

これで、無事にマージができましたね!

git log で確認すると、1st, 2nd, 3rd sub, 3rd main, main sub merge と、5つの履歴が残っているのが確認できればOKです!

では、いつもの作図で、イメージをしっかり!

1st 2ndは、全く同じものです。3rd subは、ブランチsub で編集した内容、3rd mainは、ブランチmain で編集した内容となっています。そして5つ目のコミットでは、ブランチmain側で、README.mdファイルを編集し、両方の修正内容を合体して、commitさせた内容となっています。

最新のブランチmainには、5種類、README.mdのバージョンの履歴が記録されています。それぞれ、どの時点でのバージョンを取り出せるように、復習も兼ねて、練習して置きましょう!

かなり単純ですけど!(笑)

  1. 'git restore --source=HEAD^ --worktree README.md' --> これで、3rd main
  2. 'git restore --source=HEAD^^ --worktree README.md' --> これで、3rd sub
  3. 'git restore --source=HEAD^^^ --worktree README.md' --> これで、2nd
  4. 'git restore --source=HEAD^^^^ --worktree README.md' --> これで、1st

と単純に、そう思いきや、間違っていました! 2番の3rdは、2ndとなります。3番は、2ndではなく、1stになります。果たして、3rd sub を取り出すには?!

こちらが正しくなります!(笑)

  1. 'git restore --source=HEAD^ --worktree README.md' --> これで、3rd main
  2. 'git restore --source=73bb8d574be785614fa2166899c199eabe0159b7 --worktree README.md' or 'git restore --source=sub --worktree README.md' --> どちらでも、3rd subOK!
  3. 'git restore --source=HEAD^^ --worktree README.md' --> これで、2nd
  4. 'git restore --source=HEAD^^^ --worktree README.md' --> これで、1st

3rd sub を取り出すときは、--source に、ハッシュ値で直接指定するか、subブランチ名を指定すれば可能です。尚、3番、4番も、^の数にご注意ください。

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

https://zenn.dev/shiozumi/articles/1575ce6eeffea8
https://twitter.com/esmile2013
脚注
  1. 元に戻すときは、git reflog コマンドを使って可能です。詳しい説明は、また次回で! ↩︎