単一のGitコミットをリベース


116

単一のコミットをブランチから別のブランチにリベースする方法はありますか?

私はこのブランチ構造を持っています:

-- -- -- -- -- (Master)
            \
              -- -- -- -- -- XX (Feature-branch)

私がやりたいのは、の最後のコミットFeature-branchをマスターにリベースし、Feature-branch1つのコミットをロールバックすることだけです。

-- -- -- -- -- XX (Master)
            \
              -- -- -- -- -- (Feature-branch)

それ、どうやったら出来るの?


3
任意の数のコミットをリベースできる場合、なぜ1つのコミットのリベースについて質問するのですか?SOで質問できるとしたら、リベース(シングルコミット)とチェリーピッキングの違いは何でしょうか。
Val

9
私はチェリーピッキングが存在することを知らなかったので、「ブランチでファフ」、「別のブランチで修正のリクエストを取得」、「修正」、「間違ったブランチにコミット」、「D'OH!」を実行しました。質問をすることは役に立ちました。
Kevin Meyer 14

回答:


116

XXをマスターすることができます。

git checkout master
git cherry-pick <commit ID of XX>

そして、git resetを使用して、機能ブランチから最後のコミットを削除します。

git checkout Feature-branch
git reset --hard HEAD^

63
特に「git rebase ...」と呼ばれる質問は、まったく異なる概念であり、時にはそれ自体が不潔であると見なされるチェリーピックを含むよりも、受け入れられた回答をどのように持つことができますか?
Bondax

1
これが適切かどうかはわかりませんが、リベースしたいコミットには移動されたファイルがいくつかありcherry-pick、それらが古い場所から削除され、新しい場所に作成されたように見せかけました。リベースで対応できたと思いますが、今は上流にプッシュしているため、テストできません。いずれの場合も、同様の状況に注意してください。
騒々しい

注:変更Feature-branchをオリジンにプッシュするには、の背後で1コミットであると見なされるためgit push -f origin Feature-branch、これを行う必要があります。Feature-branchorigin/Feature-branch
ジョジョ2017

1
このソリューションとCharlesBによるソリューションの実際的な違いは何ですか?
Lii

96
git rebase --onto master branch~1 branch 

これは、「マスターブランチの先端で、ブランチの直前とブランチの間のコミットの範囲(つまり、XXコミット)をリベースする」と述べています。

この操作のbranchヒントがcommit XXで移動された後、次のように設定したい

git checkout branch
git reset --hard branch@{1}^

「以前の状態の前にブランチの先端をコミットにリセットする」と書かれています

だからチェリーピックはより簡単な解決策です...


5
これはうまくいかないようです。XXの前にコミットを失い、ブランチがリベースされて単一のコミットでマスター--ontoするようになりましたが、以前に使用したことがないため、何か間違っている可能性があります。ところでOPはリベースを言ったが、彼がチェリーピックをしたいと思っているようだ。
tewe 2013年

1
私のエラー、リベースは実際にブランチをマスターに移動します、それをリセットする必要があります
CharlesB

1
このソリューションとteweによるソリューションの実際的な違いは何ですか?
Lii

1
@Lii私が見ることができるのは、4ではなく3ステップを使用することだけです
CharlesB

51

実際に行うのはかなり簡単です。解決策は、インタラクティブなリベースを実行し、リベースに含めたくないすべてのコミットを「削除」することです。

git rebase -i <target_branch>target_branchリベースするブランチはどこですか

次に、開かれているファイルとpick、必要なコミットdrop(およびd略して)を使用したくないすべてのコミットを編集します。


6
IMOの方がはるかに優れたソリューションであり、実際に問題に対処します。
GabrielOshiro 2017年

これは、どれほど一般的で直感的で、短いかを考えると、受け入れられる解決策であるべきです。
Pablo Arias

1

@Charlesの応答は正しいです。とにかく、私はこれを何度も使ってしまい、何よりもプロジェクトの特定の構成をリベースするために

  * a8f9182(HEAD->本番)プロダクション構成
  | * daa18b7(プリ)プリプロダクション構成
  | /  
  | * d365f5f(ローカル)ローカル構成
  | /  
  * 27d2835(dev)世界を救う驚くべき新機能
* | 56d2467(マスター)プロジェクトのための退屈な最先端技術
| /

そのための新しいコマンドを作成します。

$猫〜/ bin / git-rebaseshot 
コミット= $ 1
DEST = $ {2:-HEAD}
git rebase $ {COMMIT} ^ $ {COMMIT} --onto $ DEST

通常は、そのコマンドのブランチ名をオートコンプリートしたいので、この関数のソースとして追加します(.bashrcまたは.profileに追加します)。

_git_rebaseshot() 
{ 
    __gitcomp_nl "$(__ git_refs)"
}

git autocompleteはそれを検索します

このコマンドは次のように使用できます。

# rebase config on prepro on actual HEAD
$ git rebaseshot prepro 
# rebase config on local onto dev
$ git rebaseshot local dev
# rebase production config on master
$ git rebaseshot pro master

フィーチャを正しく分割すると、可能性は無限大です。

* a8f9182(HEAD-> postgres)BBDD設定
* a8f9182(ローカル)ローカル構成
* a8f9182(デバッグ)ログレベル設定
* a8f9182(dev)の新機能
|

これはキルトの人々がしたいことだと思います。

このコマンドは、提供する任意のsha / refで動作します。

$ git rebaseshot <Feature branch> master
$ git rebaseshot <commit of XX> master

//、これが動作しているのを確認できるプロジェクトにリンクできますか?
Nathan Basanese

その性質上、リベースショットに使用できるブランチは、ローカルリポジトリの外部ではコミットされません。マスター(ログレベル、データベース接続、構成)の上にいくつかのブランチを作成し、それらの間でコマンドを使用するだけです。効果がわかりやすいです。
albfan 2016年

//、いくつかの問題が発生しました。もう一度やってみます。
Nathan Basanese

0

ここに別のオプションがあります:

  1. 機能ブランチのコピーを持つリモートがあることを確認してください
  2. ローカル機能ブランチを削除する
  3. マスターから削除したばかりの古い機能ブランチと同じ名前の新しいブランチを作成してチェックアウトします
  4. 必要な機能ブランチのリモートコピーから1つのコミットを選択します。

コマンドは次のようになります。

git checkout Feature-branch
git push -u origin HEAD
git checkout master
git branch -D Feature-branch
git checkout -b Feature-branch
git cherry-pick HASH-OF-XX

それはリベースのコマンドではありませんが、精神のリベースです。

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