DUICUO

Git Rebaseチュートリアル: Git Rebaseで時間を巻き戻す

革新的な新機能を開発していると想像してみてください。素晴らしい成果になるでしょうが、時間がかかります。何日も、あるいは何週間もかけて取り組むことになるかもしれません。

[[122011]]

フィーチャーブランチはマスターブランチより6コミット進んでいます。あなたは優秀な開発者で、意味のあるセマンティックコミットも行っています。しかし、一つだけ気になることがあります。この奇妙な作業がマスターブランチにマージされるまでには、まだ時間が必要だということに気づき始めているのです。

  1. m1 - m2 - m3 - m4 (マスター)
  2. \
  3. f1 - f2 - f3 - f4 - f5 - f6 (機能)

ご存知の通り、一部は実際には重複が最小限の新機能です。これらはもっと早くメインブランチにマージできたはずです。しかし残念ながら、メインブランチに部分的にマージしたいコンテンツは、6つのコミットのどこかに存在しています。さらに悪いことに、そのコミットには、機能ブランチに依存する以前のコミットも含まれています。***箇所に2つのコミットを作成すべきだと言う人もいるかもしれませんが、誰も***しません。

  1. m1 - m2 - m3 - m4 (マスター)
  2. \
  3. f1 - f2 - f3 - f4 - f5 - f6 (機能)
  4. ^
  5. |
  6. 混合コミット

コミットの準備をしていたとき、その機能をメインブランチに徐々にマージする必要があるとは予想していませんでした。おっと!こんなに時間がかかるとは思っていませんでした。

必要なのは、時間をさかのぼって 2 つのコミットに分割し、コードを安全に分離してマスター ブランチに移植できるようにする方法です。

コミュニケーションに画像を使用するのはまさに私たちが必要としていることです。

  1. m1 - m2 - m3 - m4 (マスター)
  2. \
  3. f1 - f2 - f3a - f3b - f4 - f5 - f6 (機能)

作業を 2 つのコミットに分割した後、前の部分をメイン ブランチにチェリーピックできます。

Gitには強力なコマンド「git rebase -i」が付属しており、これを使って履歴を変更できます。履歴の変更は問題を引き起こす可能性があるため、原則として、履歴を他のユーザーと共有することは避けるべきです。ただし、今回の場合はローカルのfeatureブランチの履歴のみを変更するので、誰にも悪影響はありません。さあ、やってみましょう!

さて、f3コミットで実際に何が変更されたのかを詳しく見てみましょう。userService.jsとwishlistService.jsという2つのファイルを変更したことがわかりました。例えば、userService.jsへの変更はメインブランチに直接マージできますが、wishlistService.jsへの変更はできません。これは、wishlistService.jsがメインブランチに存在せず、f1コミットで導入されたためです。

専門家は、Gitは単一のファイルへの変更も処理できると主張しています。しかし、このブログ記事では状況を単純化して説明します。

練習用に公開デモリポジトリを用意しました。追跡を容易にするため、各コミットメッセージには、上の図で使用した偽のSHA-256をプレフィックスとして付加しています。以下は、f3を個別にコミットした場合のgitのブランチ図です。

まず最初に、Gitのチェックアウト機能を使ってfeatureブランチをチェックアウトします。`git rebase -i master`でリベースを開始します。

これで、git は設定されたエディター (デフォルトでは Vim) を使用して一時ファイルを開きます。

このドキュメントでは、リベースのオプションをいくつか紹介し、ヒント(青いテキスト)も示しています。各コミットで実行可能なアクションは、pick、rwork、edit、squash、fixup、execです。各アクションは、p、r、e、s、f、e という略語で参照することもできます。各オプションの説明はこのドキュメントの範囲を超えているため、ここでは具体的なタスクに焦点を当てます。

F3 送信の編集オプションを選択したいので、内容を次のように変更します。

ファイルを保存します(Vimでは「:wq」と入力してEnterキーを押します)。次に、編集オプションで選択したコミットでgitがリベースを停止していることを確認します。

これは、git が通常のリベースと同様に f1、f2、f3 を適用し始めるものの、f3 が有効になった後に停止することを意味します。実際、停止した時点のログを確認することで、このことを確認できます。

f3 を2つのコミットに分割するには、作業ディレクトリを現在の状態のままにしたまま、git ポインタを前のコミット (f2) にリセットするだけです。これは、`git reset` が混合モードで行うことです。混合モードは `git reset` のデフォルトモードなので、`git reset head~1` とするだけで済みます。これを実行してから、`git status` で何が起こったかを確認してください。

`git status` コマンドを実行すると、`userService.js` と `wishlistService.js` が変更されたことがわかります。`git diff` を実行すると、`f3` キーでどのような変更が行われたかを正確に確認できます。

ログを見ると、f3 が消えていることがわかります。

以前のコミット f3 はコミットする準備が整いましたが、元のコミット f3 は消えてしまいました。まだリベース処理の途中ですが、コミット f4、f5、f6 は失われておらず、後で復元されます。

2つの新しいコミットを作成しましょう。まず、userService.js のコミットを作成し、メインブランチにコミットします。`git add userService.js` を実行し、次に `git commit -m "f3a: add updateUser method"` を実行します。

素晴らしい!wishlistService.js への変更をコミットしましょう。`git add wishlistService.js` を実行し、`git commit -m "f3b: add addItems method".` を実行してください。

ログをもう一度見てみましょう。

まさにこれで望みどおりですが、f4、f5、f6 がまだありません。これはまだリベース処理の途中であり、git にリベースを続行するように指示する必要があるためです。続行するには、次のコマンドを使用してください:`git rebase --continue`。

もう一度ログを確認してみましょう。

これで完了です。これで望み通りの履歴ができました。以前のコミット f3 は f3a と f3b の2つのコミットに分割されました。残る作業は、f3a コミットをメインブランチにチェリーピックするだけです。

最初のステップを完了するには、まずmasterブランチに切り替えます。`git checkout master`を使用します。これで、`cherry-pick`コマンドを使用して`f3a`コミットを取得できます。この例では、SHA値`bd47ee1`を使用して参照できます。

これでコミット f3a がメインブランチの一番上に配置されました。まさにこれこそが私たちが求めていたものです!

この記事は長くて多くの作業を必要とするように思われるかもしれませんが、上級の Git ユーザーにとっては短時間で完了します。

注:Christophは現在、Pascal Prechtと共同でGitのリベースに関する書籍を執筆中です。leanpubで購読すると、出版準備が整った際に通知が届きます。

[[122012]]

この記事の著者であるChristoph Burgdorfは、10歳からプログラマーとして活動しています。HannoverJS Meetupウェブサイトの創設者であり、AngularJSコミュニティでも積極的に活動しています。また、GTIにも精通しており、初心者が技術を習得できるようThoughttramというワークショップを運営しています。

Ben のチュートリアルはもともと彼のブログで公開されました。


経由: https://www.codementor.io/git-tutorial/git-rebase-split-old-commit-master

著者: cburgdorf 翻訳者: geekpi 校正者: wxy

この記事は元々 LCTT によって翻訳され、Linux China によって誇らしげに紹介されました。