コミットをマージまたは追加せずに、ブランチbからaに変更を適用する


89

私のシナリオでは、ビルドプロセスに大幅な改善を加えたブランチ(ブランチA)と、無関係の機能に取り組んでいるブランチ(ブランチB)があります。ですから、ブランチBをハッキングしているときは、ビルドをより速く、より簡単にしたいので、ブランチAで書いたものを取り入れたいと思います。ただし、ブランチBを「汚染」したくはありません。ブランチAからステージングされていない変更に変更を追加するだけです。

私が試したこと(branchBに立っているとき):

git merge --no-commit branchA

マージ内に入るため、機能しません。そうでなければ、それは完璧でしょう。

git checkout branchA -- .

変更master..branchAではなくbranchA..branchB間の変更を適用するため、機能しません。

他に何か?

編集:はい、ブランチAの変更はコミットされます。この例では、ビルドが改善されたブランチは1つだけですが、機能ブランチでの作業中に適用したいビルドが改善されたブランチが最大N個ある場合があります。


Aの変更はすでにコミットされていますか?
Theolodis 2013年

回答:


155

同様のことをする必要--squashがあり、mergeコマンドに追加することで修正できました

git merge --no-commit --squash branchA
git reset HEAD # to unstage the changes

4
これには、その機能についても説明が必要です。それはあなたの現在のブランチにbranchAからの変更点の差分をステージ
KareemElashmawy

ちょうどbranchAからmasterにコードをマージしたが、何かを忘れて、git履歴に別のマージコミットとして表示されることなく、このマージコミットにさらにいくつかのコード/変更を追加したいとします。この方法は機能しますか?
Sushmit Sagar 2018

@Sushmitできると思いますがgit commit —amend、最後のコミットに新しい変更が追加されます。マージコミットで機能するかどうかは完全には
わかり

1
ここでは--no-commitは必要ないと思いますか?デフォルトである必要があります。
ペッター

11

cherry-pick -n 必要なことを実行する必要がありますが、ステージングされていない変更としてビルドの改善が必要な理由がわかりません。これにより、いくつかのことが難しくなります(たとえば、変更されたファイルへの他の変更をマージしたり、何かをリベースしたりします)。

この例では、ビルドが改善されたブランチは1つだけですが、機能ブランチでの作業中に適用したいビルドが改善されたブランチが最大N個ある場合があります。

その場合、新しいブランチCを作成します。これは、AとBの両方(およびビルドが改善された他のブランチ)からマージします。機能ブランチBで変更をコミットしてから、それらをCブランチにマージします。Cブランチには、ビルドの改善と機能ブランチの変更が含まれているため、一緒にテストできます。さらに変更を加える必要がある場合は、Cではなく適切なブランチで行ってからCにマージします。したがって、Cブランチでは何も変更せず、他のブランチからの変更を統合するために使用します。

つまり、ダーティツリーでコミットされていない変更をジャグリングする代わりに、ブランチCでGitのすべての機能を使用できます。


UseCase for cherry-pick -n:ランダムな場所にたくさんのものを追加して、コードの作業コピーを作成しました。この機能のブランチにコミットする前に、コードをクリーンアップしたいと思います。そこで、一時ブランチに切り替えて、すべての変更をコミットします。機能ブランチに戻って、cherry-pickコミットします。これを行うためのより良い方法はありますか?
Tejas Kale

6

コミットをチェリーピックできるはずです(-nすぐにコミットしないようにするため)。


-nは機能しませんでした。チェリーピックコミットが失敗した場合、-mオプションはありません。
アレハンドロサンスディアス

5

はっきりと理解できたかどうかは100%わかりませんが、私の場合は、ブランチ間にdiffパッチを作成し、このパスをBブランチに適用しました。

ブランチAの内部:

 git diff branchA..branchB > patch.diff
 git apply patch.diff

4

私はあなたの要件を理解しているかどうかわかりません。

マージを実行してから、を呼び出すことができますgit reset HEAD~1


次のシーケンスは、の間masterおよびbranchA上ですべてのコミットを再生する必要がありbranchBます。すでに適用されているコミットはbranchBスキップされます。

# start from branchA
git checkout branchA
# create a temporary branch wip
git checkout -b wip
# use rebase to replay each commit between master and wip on branchB
git rebase --onto branchB master wip

# if you want to remove all the commit history and only keep the resulting diffs,
# use git reset
git reset branchB

# change the active branch
git checkout branchB
# remove temp branch
git branch -d wip

それは私が望まないgitのステージング領域にファイルを追加します。さらに、すべてのブランチがマスターブランチの同じコミットから分岐している場合にのみうまく機能するようです。それ以外の場合は、master..branchAの範囲にない差分が導入されます。
ビョルンLindqvist

@BjörnLindqvist:--softステージングされた領域で変更を加えたくない場合は、オプションを削除してください。ブランチがどのように設定されているかをグラフで描いていただけますか?
LeGEC 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.