web-dev-qa-db-ja.com

GITを使用して、あるコミットからの変更を別の「フォーク」に選択的にマージするにはどうすればよいですか?

このシナリオを見てください:

  1. Github.comでコードベースを「フォーク」し、ルーチンを実行することにしました。編集-コミット-プッシュ。別名ハックハックハック。
  2. いくつかの変更を行った後、同じプロジェクトで他の人が行ったいくつかの変更を確認し、それらが気に入っています!
  3. 私はそれらを私のものにマージしたいと決めました。問題は、彼が行ったいくつかのコミットのうち、1つの特定のコミットの「一部」だけが欲しいということです。

これらの選択された量の変更を取得し、「フォーク」にマージする最も効率的な方法は何ですか?

79
Tim

IRC世界の波をトローリングした後、誰かが素晴らしい解決策を与えました:

git cherry-pick SHA1 --no-commit
git add --patch

うまくいけば、それは同じ質問を持つ他の人を助ける!

編集:OK、多分それはそれほど単純ではありません。完全な手順は次のとおりです。

  1. 最初にリポジトリにいる必要があり、必要なcd- ingを実行して作業ディレクトリに移動します。

  2. ここで、リモートブランチを追加してからフェッチする必要があります。これを行う:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. git log someUser/masterなどのコマンドを実行して、「部分的に」マージするコミットSHA1を見つけることができます。

  4. SHAを取得したら、次を実行できます。

    git cherry-pick -n SHA1

    ここで、SHA1はコミットSHAです。

  5. コミットの年齢や、プロジェクトの特定の領域が変更される頻度に応じて、競合が発生する可能性が非常に高くなります。申し訳ありませんが、信頼できるエディターでこれらを手動で解決する必要があります。だから、VIM、またはあなたが使用する他のものを引き出し、あなたが変更が好きな段階に到達するまで競合をハックします。

  6. インデックスをHEADリビジョンにリセットする必要があります。その後、信頼できるGIT add --patchコマンドを使用して、必要な変更を選択できます。

    git reset HEAD

    git add --patchまたはgit add -p

  7. わーい!コミット時間:

    git commit -m "I merged a select amount of changes"

  8. 混乱(git add --patchでノーと言ったもの)をクリーンアップし、選択した変更のみを作業リポジトリに保持するには、次を実行します。

    git reset --hard HEAD

    どうやらgit checkout -fも別のオプションです。

117
Tim

私はティムのソリューションが本当に好きですが、時にはvimdiffをいじるのが好きです。この問題に対する私の解決策は粗雑ですが、私はvimが好きなので私にとってはうまくいきます。

Difftoolとしてvimdiffを設定し、選択的にマージするためにブランチをdiffします:

git difftool <branch> <file>

次に、現在のブランチのバージョンを使用してペインに移動し、vimでオリジナルを編集し(必要ではない場合がありますが、vimdiffが/ tmpでバージョンを開くことがあります)、読み取り専用モードを無効にします。

:e <file>
:set readonly!

これで、dodpなどのvimのパッチツールを使用して、必要なものを適用したり、他の小さな編集を行ったりすることができます。完了したら、ファイルを保存してvimを終了し、通常の編集のようにgitでファイルをステージングしてコミットします。

先ほど言ったように、これは特に洗練されたものではありませんが、非常に強力であり、純粋にコマンドラインにあります。 gitには自動的にマージメッセージが含まれないため、明確なコミットメッセージを必ず追加してください。

vimdiffの例http://j.mp/1dZVllt

2
Mike Dacre

私はあなたが何を望むか明確ではありません。他のフォークから特定のコミットのみを取り込みたい場合は、git cherry-pick SHAgitready の詳細な説明。

2
hgmnz

コミットのポートのみが必要な場合は、必要なコミットをチェリーピッキングし、不要なファイルをリセットすることをお勧めします。

git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN

もちろん、ファイル内に複数の変更されたパーツがあり、それらの一部のみを保持したい場合は、ファイルを手動で編集して変更をカットする以外に選択肢はありません。

1
Bombe