ローカルのコミットされていない変更を別のGitブランチにマージするにはどうすればよいですか?


621

Gitで次のようにするにはどうすればよいですか?

私の現在のブランチはbranch1で、ローカルに変更を加えました。しかし、私は今、実際にこれらの変更をbranch2に適用するつもりであることがわかりました。これらの変更を適用/マージして、branch1でコミットせずに、branch2でローカル変更になる方法はありますか?


2
右の偉大なGitのチュートリアルがあり、ここで SO上で。スタックオーバーフローに関するすべてのgit質問の中心的な役割を果たします。
Decio Lira、

回答:


898

あなたのファイルはまだコミットされていないのでbranch1

git stash
git checkout branch2
git stash pop

または

git stash
git checkout branch2
git stash list       # to check the various stash made in different branch
git stash apply x    # to select the right one

benjohnによるコメントgit stashmanページを参照):

現在追跡されていない(新しく追加された)ファイルも隠して-uおくには、引数を追加します。

git stash -u

2
どういたしまして。unethicalblogger.com/posts/2008/11/…にあるstashの使用例の詳細。
VonC、2009

2
同じ問題の解決策を探しているがTFSを使用している場合、同等の解決策は、変更を保留してから、TFS Power Toolsを使用し、/ migrateスイッチを使用して正しいブランチへのシェルフを解除することです。
xr280xr

1
これでうまくいきました。ただし、「スタッシュポップ」を機能させるには、ローカルブランチも作成する必要がありました。同様のことが起こっている場合は、stackoverflow.com / questions / 1783405 / git-checkout-remote-branchをチェックアウトしてください。
ミモレラ2013

21
現在追跡されていない(新しく追加された)ファイルも隠して-uおくには、引数を追加しますgit stash -u
ベンジョン2015

2
@ベンジョングッドポイント。見やすくするために、回答にコメントを含めました。
VonC、2015

84

隠蔽、一時的なコミット、リベースはすべてやりすぎかもしれません。変更されたファイルをまだインデックスに追加していない場合は、他のブランチをチェックアウトできる可能性があります。

git checkout branch2

これは、編集しているファイルがbranch1とbranch2の間で異なっていない限り機能します。作業中の変更が保存されたままブランチ2に残ります。それらが異なる場合は、ローカルの変更を、-mチェックアウトのオプションを使用してブランチを切り替えることによって導入された変更とマージすることを指定できます。

git checkout -m branch2

変更をインデックスに追加した場合は、最初にリセットしてこれらの変更を取り消す必要があります。(これにより、作業コピーが保持されます。ステージングされた変更が削除されるだけです。)

git reset

3
stashはどういうわけか理解するのに「より単純」だと思いましたが、あなたのアプローチは、さまざまなブランチにわたる作業ディレクトリを考慮に入れる方が優れています。+1
VonC 2009

6
単純な従来のチェックアウトは、手元の問題により適しているように見えました。チェックアウトは軽量で、変更が必要なファイルを更新するだけです。おそらく、スタッシュアプ​​ローチを理解する方が簡単です。あるいは、このユースケースでは、チェックアウトが「安全」であることが十分に明確ではないかもしれません。
CBベイリー、

checkout -mある状況で「安全」でない場合(マージの競合が発生する可能性があります)、stashを使用するとどのような利点がありますか(たとえば、stashのポップを解除できますか)。
クレイグマックイーン

1
@craigMcQueenポップしたスタッシュをポップ解除することはできませんが、ポップするとスタッシュは競合について不平を言うでしょう。競合を修正してコミットできますが、この場合、元のスタッシュはまだスタック上にあります!:)
ショーンF

マージの競合が発生した場合、ファイルは次のようにバックアップされ.origませんか?
jocull

13

前述のスタッシュアプ​​ローチの短い代替案は次のとおりです。

変更を一時的に隠し場所に移動します。

  1. git stash

新しいブランチを作成し、新しいブランチに切り替えて、ワンステップでスタッシュをポップします。

  1. git stash branch new_branch_name

それからちょうどaddそしてcommit、この新しいブランチへの変更。


10

警告: git初心者向けではありません。

これは私のワークフローで十分出てきたので、ほとんど新しいgitコマンドを作成しようとしました。通常のgit stashフローは、移動するための方法であるが、少し厄介です。私は通常、最初に新しいコミットを作成します。変更を見ていると、すべての情報が頭の中で新鮮であり、git commit見つけたもの(通常は、作業中に発見したマスターに属するバグ修正)を開始する方がよいためです。機能ブランチ)すぐに。

また、このような状況が頻繁に発生する場合は、現在のディレクトリに加えて、常にmasterブランチがチェックアウトされている別の作業ディレクトリを用意すると便利です。

だから私がこれを達成する方法は次のようになります:

  1. git commit 適切なコミットメッセージですぐに変更されます。
  2. git reset HEAD~1 現在のブランチからのコミットを取り消す。
  3. (オプション)機能の作業を続行します。

時々(非同期に)、またはすぐに別のターミナルウィンドウで:

  1. cd my-project-master 同じを共有する別のWDです .git
  2. git reflog 私が作ったバグ修正を見つけるために。
  3. git cherry-pick SHA1 コミットの。

オプションで(依然として非同期)、機能ブランチをリベース(またはマージ)してバグ修正を取得できます。通常は、PRを送信しようとして機能ブランチとWDをすでにクリーンアップしている場合です。

  1. cd my-project これは私が取り組んでいるメインWDです。
  2. git rebase master バグ修正を取得します。

私は中断のない機能で作業を続けることができず、この方法では、心配する必要はgit stash何も-ingたりする前に、私のWDをきれいにすることgit checkoutになり、すべての私のバグフィックスを持って、まだ(。その後、再びチェックに機能ブランチのバックアウトを持つ)とmasterの代わりに、私の機能ブランチに隠されています。

IMO git stashgit checkoutあなたには、いくつかの大きな特徴に取り組んの真ん中にあるとき本当のPIAです。


私の回答に対する興味深い有効な代替案。+1
VonC、2015年

水銀から来ていますか?my-project-master同じ共有.git、それはそれのように聞こえるが。なぜgit checkout -b bugfixABC; git commit -a; git reset HEAD^ --hard、後で(非同期で)オンmasterになっているのgit cherry-pick <SHA1 of the commit(s) in bugfixABCですか?(または、git rebase --onto master feature bugfixABC現在ブランチが存在する場所からSHA1を見つける必要を回避するためです。つまり、git reset上記の直後に、の間、それを実行できますfeature。)
Gauthier

ただし、OPは変更をコミットする準備ができていないようcheckout -mです。その場合は、その方が優れています。
ゴーティエ2017

2

コミットされた変更に関するものである場合は、git-rebaseを確認する必要がありますが、VonCのコメントで指摘されているように、ローカルの変更について話しているときは、git-stashが確かにこれを行うための良い方法です。


私はこのソリューションを理解していません。ブランチ1からブランチ2のコミット履歴を書き換えます...
ブランチ

@VonC:同意しました。この場合、ブランチ間のブランチ1への最後のマージ以降、リベースはコミットされたすべての変更を取得します。最初は、この質問の「コミットされていない」パラメーターを取得していません。リベースは良い答えではありません。
クラフ2009

@claferri:ちょっと…頭痛がし始めていました;)私はあなたの答えに反対票を投じたでしょうが、私がそれを公表したので、「明確な利益相反」がありました。あなたの更新された投稿により、私は今、全く反対投票する必要はありません。ありがとう:)
VonC、2009

@VonC:私の答えがこれと同じくらい間違っている限り、次回は遠慮なく投票してください;)
claf

1

これまでの回答は、マージの競合を解決するために多くの不必要な作業を必要とするか、または誤っていることが多い仮定を行いすぎるため、理想的ではありません。これが完璧に行う方法です。リンクは私のサイトへのリンクです。

gitで別のブランチにコミットする方法

からのすべての変更をコミットせずmy_branchmaster、コミットするコミットされていない変更がありますmy_branch

git merge master
git stash -u
git checkout master
git stash apply
git reset
git add example.js
git commit
git checkout .
git clean -f -d
git checkout my_branch
git merge master
git stash pop

説明

masterいずれにしても最終的にはそれを行う必要があるため、ブランチにマージすることから始めます。今が競合を解決するのに最適なタイミングです。

-uオプション(別名--include-untracked)を使用git stash -uすると、後でgit clean -f -d内で実行したときに、追跡されていないファイルが失われるのを防ぐことができますmaster

後はgit checkout master、あなたがしないことが重要であるgit stash popあなたは、後でこのスタッシュが必要になりますので、。で作成されたスタッシュをポップmy_branchgit stashmasterから実行すると、後でそのスタッシュをに適用するときに、不要なマージ競合が発生しますmy_branch

git resetから生じるすべてのステージを解除しますgit stash apply。たとえば、スタッシュで変更されたが、存在しないファイルmasterは、「削除された」という競合としてステージングされます。

git checkout .そしてgit clean -f -d、コミットされていない廃棄すべて:追跡されたファイルへのすべての変更、およびすべての人跡未踏のファイルとディレクトリ。それらは既にスタッシュに保存されており、そのままにしておくと、masterに切り替えたときに不要なマージの競合が発生しmy_branchます。

最後git stash popは元のに基づいているmy_branchため、マージの競合は発生しません。ただし、マスターにコミットした追跡されていないファイルがstashに含まれている場合、gitは「追跡されていないファイルをstashから復元できませんでした」というメッセージを表示します。この競合を解決するには、あなたの作業ツリー、その後からそれらのファイルを削除してgit stash popgit add .git reset


2
あなたの回答はあなたのウェブサイトにリンクされていたため削除されませんでした。別のアカウントからのこの他の回答と同一だったため、削除されました。私がいることがわかり、他のアカウントはあなたと同じ形状を有している、あなたは2つのアカウントを使用していますか?両方のアカウントを統合することができます。また、modにフラグを付けて状況を説明すれば、元の回答(賛成票あり)を元に戻すことができます。

1
それらが統合されている場合、それらを別々に保つことはできませんが、それらを使用して投票詐欺を犯さない限り(または一般的に相互に相互作用させている限り)、複数のアカウントを持つことできます。modに状況を説明します。また、削除は正直な間違いでした。2つの異なるアカウントを使用していることを誰かにどのように伝えることができますか?

3
あなたはフラグ立てる必要がありますあなたの投稿、Modの注意を引くためにその他のオプションを使用ます、あなたが削除した回答を編集するとき彼らは注意を払いません。私はすでにあなたの投稿にmodの注目を集めるようフラグを付けましたが、それらはかなり忙しいので、辛抱してください、彼らは最終的にあなたに近づきます。

1
特に異なるアカウントからの重複したコンテンツを投稿しないでください。2つの質問が同じ場合は、投票するかフラグを立てて、重複して終了する。
トカゲに請求する2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.