1. ホーム
  2. git

[解決済み] Git チェリーピックとリベース

2022-05-03 17:28:07

質問

最近、Git を使うようになりました。

を確認する。 Gitの本 のセクションに以下のような記述がありました。

<ブロッククオート

rebaseコマンドを使用すると、その時点までのすべての変更点を あるブランチにコミットしたものを、別のブランチに再生する。

(引用元 http://git-scm.com/book/en/Git-Branching-Rebasing )

これはまさにgitの定義だと思いました。 チェリーピック (現在チェックアウトされているブランチ上のコミットまたはコミットオブジェクトのセットを再適用する)。

この2つの違いは何ですか?

解決方法は?

当時から git cherry-pick 複数のコミットを適用できるようになったことで、確かにその区別はやや無意味になりましたが、これは収斂進化と呼ぶべきものです ;-)

本当の違いは、両ツールを作った当初の意図にあるのです。

  • git rebase のタスクは、開発者が自分のプライベートリポジトリで、ある上流ブランチのバージョン X に対して行った一連の変更を、同じブランチのバージョン Y にフォワードポートすることです (Y > X)。 これは事実上 ベースを変更する その一連のコミットのことで、quot;rebasing" というわけです。

    (また、開発者は一連のコミットを任意のコミットに移植することができますが、これはあまり明白な用途ではありません)。

  • git cherry-pick は、ある開発ラインから別のラインに興味深いコミットを持ち込むためのものです。 典型的な例は、不安定な開発ブランチで行われたセキュリティ修正を安定版 (メンテナンス) ブランチにバックポートすることで、この場合は merge は、不要な変更を大量に持ち込むことになるため、意味がありません。

    初登場から git cherry-pick は、複数のコミットを一度に一人ずつ選ぶことができるようになりました。

したがって、この2つのコマンドの最も顕著な違いは、作業対象となるブランチをどのように扱うかということでしょう。 git cherry-pick は通常コミット どこからか を記録し、現在のブランチの上に適用します。 新しい コミットする一方 git rebase は現在のブランチを取得し リライト 一連の 自身の を何らかの形でコミットしています。 そうです、これはかなりダブった説明で git rebase しかし、これは意図的なもので、一般的な考えを浸透させるためです。

更新情報 を使用した例をさらに説明します。 git rebase が議論されています。

この状況を考えると



書籍 の状態です。

しかし、もうひとつの方法があります。C3で導入された変更のパッチを、C4の上に再適用するのです。Gitでは、これをリベースと呼びます。リベースコマンドを使うと、あるブランチにコミットされたすべての変更を別のブランチに適用することができます。

この例では、次のように実行します。

$ git checkout experiment
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: added staged command

この例では、(リベースの対象となる) "experiment" ブランチはもともと "master" ブランチからフォークされていたため、(リベースを行う) 事実上、"experiment" は C2 までの "master" とその上のコミット C3 を含んでいることになります。(これは最も単純なケースです。もちろん、"experiment" は元のベースに数十のコミットを追加することができます)。

さて git rebase は、"experiment" をリベースするように指示されています。 現在の の先端にある。 git rebase はこのようになります。

  1. 実行する git merge-base を実行して、"experiment" と "master" の両方が共有している最後のコミットが何であるか(言い換えれば、何が転用されているのか)を確認します。これはC2です。
  2. 転換点以降に行われたすべてのコミットを保存します。このおもちゃの例では、C3だけです。
  3. HEAD (この操作が実行される前に "experiment" の先端のコミットを指している) を巻き戻して "master" の先端を指すようにします - 私たちはこの上にリベースしています。
  4. 保存された各コミットを適用しようとします(あたかも git apply ) を順番に実行します。このおもちゃの例では、C3 という一つのコミットだけです。その適用により、コミット C3' が生成されるとします。
  5. すべてがうまくいった場合、"experiment" の参照は、最後に保存されたコミット(この例では C3')を適用した結果のコミットを指すように更新されます。

さて、質問に戻りましょう。ご覧のように、ここでは 技術的に git rebase は確かに "experiment" からの一連のコミットを "master" の先端に移植しているので、その過程で "another branch" があることは正しく認識できます。しかし、要は "experiment" の先端のコミットは結局 "experiment" の新しい先端のコミットとなり、そのベースが変わっただけなのです。

繰り返しになりますが、技術的には git rebase は、master" からの特定のコミットを取り込んでいます。