Table of Contents
通常コミットはプロジェクトに追加されるのみで、削除したり置き換えられる ことはありません。Git はこの仮定をもとにデザインされており、 この仮定を破ると git のマージ装置は(例えば)間違ったことをしてしまいます。
しかし、この仮定を破ると便利なシチュエーションもあります。
あなたが大きなプロジェクトのコントリビュータであったと仮定し、 複雑な変更を加えたとします。あなたはそれを他の開発者に公表する為、 その変更を読みやすい手順にし、それが正しいとわかることを証明し、 各変更を行なった理由がわかるようにしたいとします。
1つのパッチ(あるいはコミット)として変更全てを公表すると、 大き過ぎる為一度に全てを消化できません。
あなたの作業の完全な履歴を公表するとなると、間違いや訂正、意味無く終わったもの などが全て含まれ、冗長すぎてしまいます。
従って、通常は次のような一連のパッチを生成するのが理想的です:
これら作業の手助けをする幾つかのツールを紹介し、 それらの使い方を説明し、履歴を再編集することにより発生する問題の幾つかを 説明します
リモート追跡ブランチ "origin" の上にブランチ "mywork" を作成し、 幾つかコミットを作成したとします:
$ git checkout -b mywork origin
$ vi file.txt
$ git commit
$ vi otherfile.txt
$ git commit
...
mywork にマージをしていないので、変更は "origin" から単純に並行に 行なわれています。
o--o--o <-- origin \ o--o--o <-- mywork
プロジェクトの上流では他の興味深い変更が行なわれ、 "origin" は発展します:
o--o--O--o--o--o <-- origin \ a--b--c <-- mywork
この時点で、"pull" を使用して変更をマージさせることができます; 結果として新しいマージコミットが生成されます、次のようにです:
o--o--O--o--o--o <-- origin \ \ a--b--c--m <-- mywork
しかし、自分の履歴をマージ操作の無い、単純な一連のコミットの状態で 保ちたいのであれば、その代わりに git-rebase(1) を使用すると 良いでしょう。
$ git checkout mywork
$ git rebase origin
これは、mywork からあなたの各コミットを削除し、一時的に (".git/rebase-apply" という名前のディレクトリ内に)パッチとして保存し、 mywork を origin の最新バージョンの位置に更新し、その後で保存した 各パッチを新しい mywork ブランチに適用します。結果は次のようになります:
o--o--O--o--o--o <-- origin \ a'--b'--c' <-- mywork
この作業中にコンフリクトが発生するかもしれません。その場合は
コンフリクトを解決してください;コンフリクトを解消した後に
git add
を使用してそれらの内容で索引を更新し、
git commit
を実行する代わりに、
$ git rebase --continue
を実行します。すると、残りのパッチを適用する作業が続けられます。
どの時点でも —abort
オプションを使用すると、この作業を取り消し、
rebase を開始する前の mywork の状態に戻ることができます:
$ git rebase --abort