🗝️

Gitコマンド入門::revert(その3,cherry-pick )「第三十八回」

2021/03/09に公開

みなさん、こんにちは! 今回は、revert その3ということですが、ちょっとここ最近気になっていた、git cherry-pick を、試してみたいと思います。実は、rebase -i の時にも、コンフィクトエラーがでると、この、cherry-pick というワードが出てきていました。正直、さっぱり見当も付かなかったのですが、どうやら、コミット単位で、今のブランチのコミットに取り込めるような、そんな便利ものらしいです。

前回の記事は、こちら!

https://zenn.dev/shiozumi/articles/726d1436a93ef8

git本家本元の情報はこちらから!

https://git-scm.com/book/ja/v2

今日の学習専用レポジトリーはこちら!

https://github.com/shiozumi-makoto/20210309.git

初期時のリポジトリーは、こちらから取得!

git clone https://github.com/shiozumi-makoto/20210309.git -b main v.0038

$ mkdir temp <!-- 適当なフォルダーを作成してください!
$ cd temp <!-- そこに移動して、git clone! 
git clone https://github.com/shiozumi-makoto/20210309.git -b main v.0038

$ ls -a v.0038/
.  ..  .git  README.md
// .gitリポジトリと、README.md があればOKです!

それでは、まずは、sub ブランチを作成!

$ git log --oneline
9fda91b (HEAD -> main, origin/main, sub) 1st
// 初期は、1stのコミット一つのみですね。

$ git branch
* main
// 現在のブランチは、main のみですね。

$ git checkout -b sub
Switched to a new branch 'sub'
// 新しくsubブランチを、mainから作成し、subブランチに切り替え!

$ git branch
  main
* sub
// subブランチが新規に作成されて、選択された状態です。

$ git log --oneline
9fda91b (HEAD -> sub, origin/main, main) 1st
// 無事に複製されていそうです。

$ git diff sub main
$
// ブランチ同士の差分を取ってみましたが、何も表示されませんね。

ブランチの複製が出来たら、subブランチ側に、sub.txt を追加!

$ echo "sub.txt" > sub.txt
$ cat sub.txt
sub.txt

$ git add sub.txt
$ git commit -m "add sub.txt"
[sub f1bad61] add sub.txt
 1 file changed, 1 insertion(+)
 create mode 100644 sub.txt

$ git log --oneline --graph
* f1bad61 (HEAD -> sub) add sub.txt
* 9fda91b (origin/main, main) 1st

// では、もう一度、ブランチ同士の差分を取ります!
$ git diff main sub
diff --git a/sub.txt b/sub.txt
new file mode 100644
index 0000000..f4ff2d2
--- /dev/null
+++ b/sub.txt
@@ -0,0 +1 @@
+sub.txt  // <!-- ここで、差分が出てきましたね!
ハッシュ値 コメント README.md sub.txt 補足説明
9fda91b 1st # git cherry-pick - -
f1bad61 add sub.txt # git cherry-pick sub.txt subテキスト追加

現在のsubブランチのリポジトリーの状態です。後で、mainブランチ側から、
このハッシュ値、f1bad61 のコミットを取り込みます。

次は、mainブランチ側に、main.txt を追加!

$ git switch main
// 今回は、checkout ではなく、switch で切り替えてみます!

$ git branch
* main
  sub
  
$ echo "main.txt" > main.txt
$ cat main.txt
main.txt

$ git add main.txt
$ git commit -m "add main.txt"
[main 347e3a1] add main.txt
 1 file changed, 1 insertion(+)
 create mode 100644 main.txt
 
$ git log --oneline --graph
* 347e3a1 (HEAD -> main) add main.txt
* 9fda91b (origin/main) 1st

// では、もう一度、ブランチ同士の差分を取ります!
// mainブランチを選択中で、subに対して、diffを取ります。

$ git diff sub <main:省略可能>
// 現在選択しているブランチmainは省略可能です。

diff --git a/main.txt b/main.txt
new file mode 100644
index 0000000..62f5abc
--- /dev/null  // <!-- sub 側には、main.txtがありません。
+++ b/main.txt
@@ -0,0 +1 @@
+main.txt // <!-- 差分が出てきましたね!

diff --git a/sub.txt b/sub.txt
deleted file mode 100644
index f4ff2d2..0000000
--- a/sub.txt
+++ /dev/null  // <!-- main 側には、sub.txtがありません。
@@ -1 +0,0 @@
-sub.txt // <!-- 差分が出てきましたね!
ハッシュ値 コメント README.md main.txt 補足説明
9fda91b 1st # git cherry-pick - -
347e3a1 add main.txt # git cherry-pick main.txt mainテキスト追加

現在のmainブランチのリポジトリーの状態です。

では、いよいよ、git cherry-pick で、サブブランチ側の、b.txtを追加したコミットを取り込んでみましょう! ハッシュ値は、f1bad61 ですね!

$ git cherry-pick f1bad61
[main e771959] add sub.txt
 Date: Tue Mar 9 07:57:58 2021 +0900
 1 file changed, 1 insertion(+)
 create mode 100644 sub.txt

$ git log --oneline --graph
* e771959 (HEAD -> main) add sub.txt
* 347e3a1 add main.txt
* 9fda91b (origin/main) 1st

$ ls
README.md  main.txt  sub.txt
// これで、sub.txt が取り込めましたね!

$ git diff sub
diff --git a/main.txt b/main.txt
new file mode 100644
index 0000000..62f5abc
--- /dev/null
+++ b/main.txt
@@ -0,0 +1 @@
+main.txt
// 差分表示でも、確認して置きましょう!
ハッシュ値 コメント README.md main.txt sub.txt 補足説明
9fda91b 1st # git cherry-pick - - -
347e3a1 add main.txt # git cherry-pick main.txt - -
e771959 add sub.txt # git cherry-pick main.txt sub.txt f1bad61 を取り込み

コミット番号のハッシュ値、f1bad61 を取り込みました。
コメント分も、"add sub.txt" そのまま取り込んでいますね。

さあ、いかがでしょうか? とても簡単ですね。ファイルのコンフィクトが起こらない場合は、すんなり取り込めることでしょう。実際の開発では、なんとも言えませんけど、毎度、初回からお伝えてしているとおり、複数人数で開発するときは、なるべくファイル共有に置いては、ひとつのファイルを複数人数で編集することのないように分担するのが基本中の基本ですね。

新しいコマンド、git switch

こちらについては、v2.2x ぐらいから実装されたそうです。例の、git restore と同時です。そもそも、git checkout のコマンド機能が多かったので、それを分割して、switch と、restore に分けたそうです。また後日、いろいろ試したいと思っていますが、branch checkout switch clone pull fetch などのリポジトリ操作系のコマンドは、実際どうなるのかしっかり覚えて置かないと、結構、間違って入力してしまいがちになるんですよね~(苦笑)

最終結果をリモートリポジトリから取得する方法は、こちらから、+subブランチのチェックアウトも!

git clone https://github.com/shiozumi-makoto/20210309.git -b main v.0038z

Cloning into 'v.0038z'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 12 (delta 2), reused 11 (delta 1), pack-reused 0
Unpacking objects: 100% (12/12), done.

// タグ名でcloneすると、同じ名前のファルダーが作成されます!
$ cd v.0038z

$ ls
README.md  main.txt  sub.txt

$ git branch
* main

// cherry-pick の元となる、subブランチもチェックアウト!
$ git checkout -b sub origin/sub
Branch 'sub' set up to track remote branch 'sub' from 'origin'.
Switched to a new branch 'sub'

// これで、私と同じ環境になったと思います!
$ git branch
  main
* sub

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

https://zenn.dev/shiozumi/articles/013d34e19fdba1
https://twitter.com/esmile2013

Discussion