web-dev-qa-db-ja.com

git stash->隠された変更を現在の変更とマージ

私は自分のブランチにいくつかの変更を加え、そのブランチに必要な他の変更をいくつか隠していたことを忘れました。私が欲しいのは、隠された変更を現在の変更とマージする方法です。

これを行う方法はありますか?

利便性のために、私は最終的にあきらめて最初に現在の変更をコミットし、次に隠された変更をコミットしましたが、一気にそれらを取り込むことを望んでいました。

148
Bemis

コミットされていない変更がインデックスに追加されると(つまり、git add ...を使用して「ステージング」されると)、git stash apply(そしておそらく、git stash pop)が実際に適切なマージを行うことがわかりました。競合がない場合、あなたは黄金です。そうでない場合は、通常どおりgit mergetoolで解決するか、エディターで手動で解決します。

明確にするために、これは私が話しているプロセスです:

mkdir test-repo && cd test-repo && git init
echo test > test.txt
git add test.txt && git commit -m "Initial version"

# here's the interesting part:

# make a local change and stash it:
echo test2 > test.txt
git stash

# make a different local change:
echo test3 > test.txt

# try to apply the previous changes:
git stash apply
# git complains "Cannot apply to a dirty working tree, please stage your changes"

# add "test3" changes to the index, then re-try the stash:
git add test.txt
git stash apply
# git says: "Auto-merging test.txt"
# git says: "CONFLICT (content): Merge conflict in test.txt"

...これはおそらくあなたが探しているものです。


tl; dr

最初にgit addを実行します。

213
Joshua Warner

git stash popまたはgit stash applyの実行は、本質的にマージです。 stashで変更されたファイルが作業コピーでも変更されない限り、現在の変更をコミットする必要はないはずです。その場合、次のエラーメッセージが表示されます。

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

その場合、1ステップで現在の変更にスタッシュを適用することはできません。本当に2つのコミットが必要ない場合は、git rebaseを使用して、変更をコミットし、stashを適用し、再度コミットし、これら2つのコミットを押しつぶすことができますが、それだけの価値があると思われる場合があります。

68
Brandan

私が欲しいのは、隠された変更を現在の変更とマージする方法です

これを行う別のオプションを次に示します。

git stash show -p|git apply
git stash drop

git stash show -pは、最後に保存されたスタッシュのパッチを表示します。 git applyが適用します。マージが完了すると、マージされたスタッシュはgit stash dropでドロップできます。

19
ks1322

たぶん、... diff ...ブランチから(difftool経由で)マージするのは最悪のアイデアではないかもしれません!

> current_branch=$(git status | head -n1 | cut -d' ' -f3)
> stash_branch="$current_branch-stash-$(date +%yy%mm%dd-%Hh%M)"
> git stash branch $stash_branch
> git checkout $current_branch
> git difftool $stash_branch
0

私がこれを行う方法は、最初にgit add、次にgit stash apply <stash code>です。最も簡単な方法です。

0
user3856437

@Brandanが示唆したように、ここに私がやらなければならないことがあります

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

このプロセスに従ってください:

git status  # local changes to `file`
git stash list  # further changes to `file` we want to merge
git commit -m "WIP" file
git stash pop
git commit -m "WIP2" file
git rebase -i HEAD^^  # I always use interactive rebase -- I'm sure you could do this in a single command with the simplicity of this process -- basically squash HEAD into HEAD^
# mark the second commit to squash into the first using your EDITOR
git reset HEAD^

そして、あなたは完全にマージされたlocalfileへの変更を残され、さらなる作業/クリーンアップを行うか、単一の良いコミットを行う準備ができています。または、fileのマージされた内容が正しいことがわかっている場合は、適切なメッセージを書いてgit reset HEAD^をスキップできます。

0
knickum