GitHubじゃ!Pythonじゃ!

GitHubからPython関係の優良リポジトリを探したかったのじゃー、でも英語は出来ないから日本語で読むのじゃー、英語社会世知辛いのじゃー

mhagger

git-imerge – gitのインクリメンタルマージ

投稿日:

gitのインクリメンタルマージ

git-imerge – gitのインクリメンタルマージとリベース

2つのブランチ間を段階的にマージします。 競合が発生した場合は、どの競合対が競合しているかを正確に把握し、解決のために一度に1対の競合をユーザに提示します。

git-imergeは2つの主要な設計目標があります:

  • 起こりうる最小の矛盾を見つけて提示することによって、マージ競合を避けることのできない最小限の問題を解決することの苦痛を軽減します。
  • マージが進行中に保存、テスト、中断、公開、およびコラボレーションされることを許可します。

インクリメンタルマージの概念を視覚的に理解するのが最も簡単だと思うので、GitMerge 2013カンファレンス (20分)の私のgit-imergeプレゼンテーションビデオをお勧めします。 この講演のスライドは、このレポジトリのdoc/presentations/GitMerge-2013ます。 同じカンファレンスで、 GitMinutes Podcast#12の Thomas Ferris Nicolaisenによるgit-imergeに関するインタビューを受けました。

git-imergeツール自体を使用する方法を学ぶために、ブログ記事git-imerge:A Practical Introductionと、 git-imerge --helpgit-imerge SUBCOMMAND --helpと入力することをgit-imerge SUBCOMMAND --help より多くの情報が必要な場合、インクリメンタルマージングの理論と利点は、一連のブログ記事[1]に詳細に記載されています。

複数のインクリメンタルマージを同時に実行することができます。 それぞれのインクリメンタルマージには名前があり、その進行状況はrefs/imerge/NAME参照としてGitリポジトリに記録されます。 インクリメンタルマージの現在の状態は、 diagramコマンドを使用して視覚化することができます。

インクリメンタルマージは中断され、任意に再開されたり、他の人がその上で作業できるようにサーバーにプッシュされることさえできます。

git-imergeは、Bash補完スクリプトが付属しています。 git-imerge.bashcompleteをシステムに通常完了スクリプトがインストールされている場所にコピーすることでインストールできます(例:/etc/bash_completion.d/)。

要件

git-imergeは次のものが必要です:

  • Pythonインタプリタ。 どちらか

    • Python 2.x、バージョン2.6以降 Python 2.6.xを使用している場合は、Python 2.7の標準ライブラリに追加されたため、 argparseモジュールを自分でインストールする必要があります。
    • Python 3.x、バージョン3.3以降。

    このスクリプトはあなたのPATH pythonというPythonインタプリタを使用しようとします。 Pythonインタプリタの名前が違うかPATHにない場合は、それに応じてスクリプトの最初の行を調整してください。

  • Gitの最近のバージョン。

Bash補完ではGitの補完が必要です。

指示

git-imergeを使用してマージまたはリベース操作を開始するには、対応するgitコマンドと同様のコマンドを使用します。

インクリメンタルマージまたはリベースの開始

git-imergeコマンド git analogue 効果
git-imerge merge BRANCH git merge BRANCH 現在のブランチにブランチをマージします。
git-imerge rebase BRANCH git rebase BRANCH ブランチの上に現在のブランチを再BRANCH
git-imerge revert COMMIT git revert COMMIT COMMITの効果を元に戻す新しいコミットを追加する
git-imerge revert COMMIT1..COMMIT2 git revert COMMIT1..COMMIT2 COMMIT1..COMMIT2の影響を取り消す新しいコミットを追加する
git-imerge drop COMMIT git rebase --onto COMMIT^ COMMIT 現在のブランチの履歴からCOMMITを完全に削除する
git-imerge drop COMMIT1..COMMIT2 git rebase --onto COMMIT1 COMMIT2 完全に削除すると、現在のブランチの履歴からCOMMIT1..COMMIT2がコミットされCOMMIT1..COMMIT2

git-imerge dropは、 git rebase --interactiveを実行してから、履歴から指定されたコミットを削除するのと同じです) dropコマンドとrevertサブコマンドの両方がgit-imergeに含まれています。インクリメンタルマージアプローチを使用することで両方とも恩恵を受けることができます)。

git imerge startを使ってインクリメンタルマージを開始すると、さらにいくつかのオプションが利用できます:

git-imerge start --name=NAME --goal=GOAL [--first-parent] BRANCH

どこで

NAME
このマージの名前(および結果が保存されるブランチのデフォルト名)です。
GOAL
結果を単純化する方法について説明します(次のセクションを参照)。

インクリメンタルマージが開始されると、解決しなければならない競合が表示されます。 基本的な手順はgitを使ってインクリメンタルマージを行うのと同じです:

while not done:
    <fix the conflict that is presented to you>
    <"git add" the files that you changed>
    git-imerge continue

すべての競合を解決したら、次のように入力して増分マージを完了します。

git-imerge finish

それはあなたを動かすのに十分なはずです。 これらのすべてのサブコマンドには追加オプションがあります。 それらについて学ぶために:

git-imerge --help
git-imerge SUBCMD --help

結果を簡略化する

インクリメンタルマージが完了したら、 finishまたはsimplifyコマンドを使用して、プロジェクトの永久履歴に記録する前にさまざまな方法で結果を単純化できます。 インクリメンタルマージの「目標」は、次のいずれかになります。

merge

第2ブランチを第1ブランチに単純にマージし、すべての中間マージを破棄します。 最終的な結果は、あなたが得るものと似ています

git checkout BRANCH1
git merge BRANCH2
rebase

第2ブランチからのコミットのバージョンを第1ブランチにリベースします。 最終的な結果は、あなたが得るものと似ています

git checkout BRANCH2
git rebase BRANCH1
rebase-with-history

歴史の中でリベースされたコミットの古いバージョンを保持していることを除けば、 rebaseようなものです。 これは、 BRANCH2のコミットをBRANCH1にマージすることと同じBRANCH1 (一度に1つコミットします)。 言い換えると、これは次のように変換します。

o---o---o---o          BRANCH1
     \
      A---B---C---D    BRANCH2

これに:

o---o---o---o---A'--B'--C'--D'   NEW_BRANCH
     \         /   /   /   /
      --------A---B---C---D

この方法を使用して、すでに公開されているブランチをリベースすることは安全です。 詳細は、 [2]を参照してください。

full
インクリメンタルマージを単純化しないでください。すべての中間マージを行い、永続的な履歴にそれらをすべて保持します。

テクニカルノート

一時停止/再開

git-imergeは、ユーザに手動でマージを依頼する必要がある場合、一時的なブランチrefs/heads/imerge/NAMEを作成して結果を保持します。 継続する前にインクリメンタルマージを一時停止したい場合は、 git merge --abortを使用して保留中のマージを中止し、他のブランチに切り替えます。 インクリメンタルマージを再開する準備ができたら、 git imerge continueます。

進行中のインクリメンタルマージを完全に中止する必要がある場合は、最初にgit-imergeを使用して作成した一時ブランチをgit-imerge removegit checkout ORIGINAL_BRANCHインクリメンタルマージを開始する前のブランチをチェックアウトします。

ストレージ

git-imergeは、 refs/imerge/NAME下にある参照の束として、Gitオブジェクトデータベースのインクリメンタルマージに関する中間状態のすべてを記録します。ここで、 NAMEはimergeの名前です。

  • refs/imerge/NAME/state stateは、imergeの現在の状態をJSON形式で記述するBLOBを指します。 例えば、
    • マージされている2つのブランチのヒント
    • 現在の「ブロッカー」がマージ(ユーザーが手動で行う必要があります)
    • 簡素化の目標
    • 結果が書き込まれるブランチの名前。
  • refs/imerge/NAME/manual/IJrefs/imerge/NAME/auto/IJは、インクリメンタルマージの一部として実行された手動マージコミットと自動マージコミットをそれぞれ参照します。 IJは、インクリメンタルマージ図のマージの位置(I,J)を示す整数です。

リポジトリ間で進行中のイメージを転送する

進行中のインクリメンタルマージを1つのGitリポジトリから別のGitリポジトリに転送すると便利な場合があります。 たとえば、現在の状態のバックアップを作成したり、仕事中に開始した自宅でimergeを続行したり、同僚にペアワイズマージを依頼したりすることができます。 imerge状態はすべてGitオブジェクトデータベースに格納されているので、前のセクションで指定した参照をプッシュ/フェッチすることでこれを行うことができます。 例えば、

git push --prune origin +refs/imerge/NAME/*:refs/imerge/NAME/*

または

git fetch --prune origin +refs/imerge/NAME/*:refs/imerge/NAME/*

これらのコマンドは、宛先リポジトリにすでに存在していた状態を上書きすることに注意してください。 現時点では、増分マージで2人の作業が並行して実行されるように組み合わせることはできません。今のところ、交代する必要があります。

git rerere

git rerereは、マージの競合をどのように解決するかを記録する素晴らしいツールです。同じ競合を再び見た場合、同じ解像度を自動的に再利用しようとします。

git-imergeは非常に多くの同様のテストマージを試みているので、混乱することは容易に想像することができます。 さらに、 git-imergeは、複数回実行されると一貫して解決する(または解決しない)マージに依存します。 背後に余分な情報をrerereことは、 git-imerge混乱させる可能性があります。

実際、テストでは、インクリメンタルマージ中に、 git-imergererereが、時々、マージの競合が間違って解決されるようになったようです。 したがって、 git-imergeはgitを呼び出すたびに明示的にrerereを一時的にオフにします。

ペアごとのマージコミットのログメッセージ

git imerge continuegit imerge recordが作業ツリーで解決されたマージを見つけgit imerge record 、そのマージをコミットしてインクリメンタルマージに組み込みます。 通常は、Gitの自動生成されたコミットメッセージをそのコミットに使用します。 このようなコミットメッセージの編集を求めるプロンプトが表示されるようにするには、コマンドラインで--editを指定するか、設定のデフォルトを変更します。

git config --global imerge.editmergemessages true

ライセンス

git-imergeは、GNU General Public License(GPL)バージョン2以降でオープンソースソフトウェアとしてリリースされています。 詳細については、 COPYINGファイルを参照してください。

参考文献

[1]
[2] 1,2







-mhagger
-, ,

執筆者: