web-dev-qa-db-ja.com

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

どうすればGitで次のことができますか?

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

590
solsberg

あなたのファイルはまだ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

コメント付き by benjohngit stashのmanページ を参照):

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

git stash -u
853
VonC

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

git checkout branch2

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

git checkout -m branch2

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

git reset
83
CB Bailey

前述のstashアプローチに代わるより短い方法は、次のとおりです。

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

  1. git stash

新しいブランチを作成してそれに切り替えて、ワンステップでそれに隠し棒をポップします。

  1. git stash branch new_branch_name

それから、この新しいブランチへの変更をaddcommitに変更します。

11
rbento

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

2
claf

これまでの答えは、マージの競合を解決するために多くの不必要な作業を必要としたり、間違っていたりすることが多いため、理想的ではありません。これはどうやってそれを完璧にするかです。リンクは私自身のサイトへのものです。

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

my_branchからのすべての変更をコミットせずに、masterにコミットする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)は、後でmaster内でgit clean -f -dを実行したときに追跡されていないファイルを失うことを防ぎます。

git checkout masterの後にgit stash popを付けないことが重要です。なぜなら、後でこの隠し場所が必要になるからです。 my_branchで作成した隠し場所をポップしてからmaster内でgit stashを実行すると、後でその隠し場所をmy_branchに適用するときに不要なマージの競合が発生します。

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

git checkout .git clean -f -dは、コミットされていないものすべて、つまり追跡されているファイルに対するすべての変更、追跡されていないすべてのファイルとディレクトリを破棄します。それらはすでにstashに保存されており、masterに残されていると、my_branchに切り替えるときに不必要なマージの競合が発生します。

最後のgit stash popは、元のmy_branchに基づいているため、マージの競合は発生しません。しかし、あなたの隠し場所があなたが習得しようとしている追跡されていないファイルを含んでいる場合、gitは「追跡されていないファイルを隠し場所から復元できなかった」と不平を言います。この競合を解決するには、作業ツリーからそれらのファイルを削除し、次にgit stash popgit add .、およびgit resetを削除します。

1
Vladimir Kornea