92733


Git でCherry-pick 後に Mergeすると同じCommitが複数できてしまいました。

以下のようにしたときに同じ内容のコミット履歴ができてしまいました。  
これを解消するにはどうしたらよいでしょうか。

【前提】  
Branch:A , Branch: B  
【手順】  
1.Branch：A のCommit1をBranch:Bにcherry-pickする  
2.Branch：A のCommit2をBranch:Bにcherry-pickする  
3.Branch:A をBranch:B に mergeする

例:  
1.git checkout branchB  
2.git cherry-pick commitid1(Branch:Aのsha1)  
3.git cherry-pick commitid2(Branch:Aのsha1)  
4.git merge origin/branchB

例の4が終わったあとに commitid1, commitid2 に対応する コミットの履歴が複数できてしまいました。（commitid は同じではない）  
同じcommit内容が履歴に残らないようにするにはどうしたら良いでしょうか。  
また、すでにPUSHされてしまった重複する履歴をまとめるもしくは削除するにはどうしたら良いでしょうか。  
ご教示頂けますと幸いです。


CC BY-SA 4.0
2022-12-02T14:37:44.357
92543
2023-01-02T21:22:08.720
2022-12-03T05:38:21.033
3060
42827
question
git github
Git でCherry-pick 後に Mergeすると同じCommitの履歴が複数できてしまう


次のようにコミットを行ったとき、

[code]

    git init
    touch hello.txt
    git add .
    git commit -m init
    git branch branchA
    git branch branchB
    git checkout branchA
    echo 'edit 1' >> hello.txt
    git commit -am 'commit 1'
    echo 'edit 2' >> hello.txt
    git commit -am 'commit 2'
    git checkout branchB
    git cherry-pick -x branchA^^..branchA
    git merge --no-edit branchA
    
[/code]

`git log` コマンドを実行すると次のような結果になります:

[code]

    commit 441d9cdca924b7979a0ea95e70b3a6d9df43a012 (HEAD -> branchB)
    Merge: f10473e ac17f85
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:41 2022 +0900
    
        Merge branch 'branchA' into branchB
    
    commit f10473ee50e5d6f1a73d5e5be95b9cadfafb00d1
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:40 2022 +0900
    
        commit 2
    
        (cherry picked from commit ac17f85eda899e20952ad5d4ef41515af4174cb1)
    
    commit ac17f85eda899e20952ad5d4ef41515af4174cb1 (branchA)
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:40 2022 +0900
    
        commit 2
    
    commit bd740a9896832c5a6218921fe90c3ff93d3ae438
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:40 2022 +0900
    
        commit 1
    
        (cherry picked from commit d0b43f3e15de1177e1c21da4f92231eb065a978e)
    
    commit d0b43f3e15de1177e1c21da4f92231eb065a978e
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:40 2022 +0900
    
        commit 1
    
    commit d7b431119cb57e33d986dcbd0c9c1c34653a2a2e (main)
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:39 2022 +0900
    
        init
    
[/code]

コミットしているので履歴に残るのは当然です。履歴から抹消したいのであれば `rebase` でコミットを削除する必要があります。  
ただしコミットはそのままでも、出力時に非表示にすることはできます。

`git merge` でマージしたブランチ(今回の場合は`branchA`)のコミットを非表示にしたいのであれば、 [`--first-
parent`](https://git-scm.com/docs/git-log#Documentation/git-log.txt---first-
parent)オプションが利用可能です:

[code]

    $ git checkout branchB
    $ git log --first-parent
    commit 441d9cdca924b7979a0ea95e70b3a6d9df43a012 (HEAD -> branchB)
    Merge: f10473e ac17f85
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:41 2022 +0900
    
        Merge branch 'branchA' into branchB
    
    commit f10473ee50e5d6f1a73d5e5be95b9cadfafb00d1
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:40 2022 +0900
    
        commit 2
    
        (cherry picked from commit ac17f85eda899e20952ad5d4ef41515af4174cb1)
    
    commit bd740a9896832c5a6218921fe90c3ff93d3ae438
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:40 2022 +0900
    
        commit 1
    
        (cherry picked from commit d0b43f3e15de1177e1c21da4f92231eb065a978e)
    
    commit d7b431119cb57e33d986dcbd0c9c1c34653a2a2e (main)
    Author: yukihane <myname@example.com>
    Date:   Tue Dec 13 09:35:39 2022 +0900
    
        init
    
[/code]

* * *

([コメント](https://ja.stackoverflow.com/questions/92543/git-%e3%81%a7cherry-
pick-%e5%be%8c%e3%81%ab-
merge%e3%81%99%e3%82%8b%e3%81%a8%e5%90%8c%e3%81%98commit%e3%81%ae%e5%b1%a5%e6%ad%b4%e3%81%8c%e8%a4%87%e6%95%b0%e3%81%a7%e3%81%8d%e3%81%a6%e3%81%97%e3%81%be%e3%81%86/92733?noredirect=1#comment106181_92733)をうけて追記)

履歴から抹消する(cherry-pick による変更を無かったことにする)場合、いくつかやり方はありますが、今回の例のように直近に行ったのが cherry-
pick だけなのであれば、`git reset --hard` で cherry-pick する前に戻ればよいです。  
具体的には:

[code]

    git init
    touch hello.txt
    git add .
    git commit -m init
    git branch branchA
    git branch branchB
    git checkout branchA
    echo 'edit 1' >> hello.txt
    git commit -am 'commit 1'
    echo 'edit 2' >> hello.txt
    git commit -am 'commit 2'
    git checkout branchB
    git cherry-pick -x branchA^^..branchA
    git reset --hard @^^ # cherry-pick する直前のコミットに戻る
    git merge --no-edit branchA
    
[/code]

そうでなく、 cherry-pick 以外のコミットも混ざっている場合には、 `git rebase -i` で cherry-pick
コミットだけを削除することになります。次のコマンドを実行後

[code]

    git init
    touch hello.txt
    git add .
    git commit -m init
    git branch branchA
    git branch branchB
    git checkout branchA
    echo 'edit 1' >> hello.txt
    git commit -am 'commit 1'
    echo 'edit 2' >> hello.txt
    git commit -am 'commit 2'
    git checkout branchB
    git cherry-pick -x branchA^^..branchA
    echo edit3 >> hello.txt 
    git commit -am 'additional edit' # chery-pick の後に変更を加えた
    
[/code]

`git rebase -i` で編集画面を開き

[code]

    git rebase -i @^^^ # cherry-pick 直前のコミットを指定
    
[/code]

cherry-pick コミット似該当する行を削除します。(今回の場合は上2行を削除)

[code]

    pick 0eae88f commit 1 # cherry-pick コミットなので削除
    pick 7aff1b2 commit 2 # cherry-pick コミットなので削除
    pick f659246 additional edit # 削除せず残す
    
[/code]

最後にマージして完了です。

[code]

    git merge --no-edit branchA
    
[/code]


CC BY-SA 4.0
2022-12-13T00:50:20.577
92733
2023-01-02T21:22:08.720
2023-01-02T21:22:08.720
2808
2808
92543
answer