特定のコミットをgitの別のブランチに基づくように移動するにはどうすればよいですか?


381

状況:

  • マスターはXにいます
  • quickfix1はX + 2コミットです

そのような:

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)

その後、quickfix2の作業を開始しましたが、誤って、quickfix1をコピーするソースブランチとして使用しました。マスターではありません。現在、quickfix2はX + 2コミット+ 2関連コミットにあります。

o-o-X (master HEAD)
     \
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

今度はquickfix2を使用してブランチを作成しますが、quickfix1に属する2つのコミットは使用しません。

      q2a'--q2b' (quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

quickfix2の特定のリビジョンからパッチを作成しようとしましたが、パッチはコミット履歴を保持しません。コミット履歴を保存する方法はありますが、quickfix1を変更せずにブランチがありますか?



8
@Kevinこの質問は、あるブランチから別のブランチにコミットを移動することについてのみ尋ねます。これには、のコミットを含めないという追加の要件がありquickfix1ます。(回答の違いにも注意してください。)
Scott Weldon

回答:


372

これは古典的なケースですrebase --onto

 # let's go to current master (X, where quickfix2 should begin)
 git checkout master

 # replay every commit *after* quickfix1 up to quickfix2 HEAD.
 git rebase --onto master quickfix1 quickfix2 

だからあなたはから行くべきです

o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)
              \
               q2a--q2b (quickfix2 HEAD)

に:

      q2a'--q2b' (new quickfix2 HEAD)
     /
o-o-X (master HEAD)
     \ 
      q1a--q1b (quickfix1 HEAD)

これは、クリーンな作業ツリーで行うのが最善です。特にGit 2.10以降を
参照してくださいgit config --global rebase.autostash true


24
これらの手順でquickfix2の履歴が変更されることに注意してください。すでにブランチを共有している場合は、代わりにチェリーピッキングを使用してください(以下の回答を参照)。
Max Chernyak 2013年

記録のためだけに:SmartGitのログをドラッグq2aして、発生するダイアログのオプションからRebase 2コミットXを選択します。
Thomas S.

1
@ThomasS。面白い。これはのGUI実装として優れていgit rebase --ontoます。
VonC、2015

1
私は認めざるを得ません。私は本当に間違ったブランチにコミットするような愚かなことをします。SmartGitのログビューGUIは同じ状況で何度も私を救ってくれました。
WORMSS 2015

1
@コサイン同意。回答を編集してrebase.autostash構成への参照を追加しました。これにより、リベースを実行するときに作業ツリーで進行中の作業が失われるのを回避できます。
VonC、2017年

155

を使用git cherry-pickして、コピーするコミットを選択できます。

おそらく最良の方法は、マスターからブランチを作成し、そのブランチgit cherry-pickで、必要なquickfix2からの2つのコミットで使用することです。


これは、1つのコミットだけを移動する場合にも最適なオプションです。ありがとう。
Alex

142

あなたができる最も簡単なことは、範囲を選ぶチェリーです。それは同じことをしますrebase --ontoが、目には簡単です:)

git cherry-pick quickfix1..quickfix2

6
また、それは元のコミットIIUCを失うことはないので、私のような "play-it-safes"の方が望ましいようです;)またはrebase --onto、元の変更も保持しますか?
akavel 2013

6
両方rebasecherry-pick新しいSHAキーを提供します。これは、各コミットがリポジトリの一意のスナップショットであるためです。
2013

6
どのような意味@akavelすると、その桜ピックが真である彼らの枝の元のコミットを維持するある
Mr_and_Mrs_D

4
それが価値があるもののために、私はしようとしました cherry-pickはこの答えのような範囲た、そしてそれは私のリポジトリを混乱させました。私は、個々のしなければならなかったcherry-pick各コミット秒。(そしておそらく言うまでもありませんが、誰かが苦労している場合はcherry-pick、コミットが適用された年代順に並べる必要があります。)
カルメニズム

3
git checkoutここで重要です。あなたの頭は何ですか:)?
SławomirLenart

28

私はそれが信じています:

git checkout master
git checkout -b good_quickfix2
git cherry-pick quickfix2^
git cherry-pick quickfix2

3
cherry-pickコミットハッシュで動作するので、どこかからコミットを取得して別の場所に配置したい場合は、これが方法です。checkout <branch>最初に正しいブランチを実行することを確認してください。
John Leidegren

-1
// on your branch that holds the commit you want to pass
$ git log
// copy the commit hash found
$ git checkout [branch that will copy the commit]
$ git reset --hard [hash of the commit you want to copy from the other branch]
// remove the [brackets]

その他の便利なコマンドと説明:Gitガイド

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.