レガシーストーリーをツリーに注ぐ:最適な分岐点を見つける

私のサービスの結果として、私は15年以上の歴史を持つ特定のシステムを継承し、さまざまな組織で数十件のインストールを行いました。 システム自体は比較的小さい(〜25K行のコード、〜1Kコミット)が、問題はリリース管理にあった:





もちろん、実際には、このシステムを感謝しているお客様は、サポート、バグ修正、さらにはシステムコアのグローバルな改善を希望する場合があります。



短い協議の後、svnでこのような分散システムをサポートし続けることは不適切と見なされ、gitに移行することが決定されました。



問題1-マスターツリーをsvnからgitにドラッグすることは、一般的にgit-svnの標準的な手段によって簡単に決定されました。



問題セット2-さまざまなインストールの多数のフォークをこのツリーに注ぎ込む方法-「到着したとき」に分解することが決定されました。 次の組織が目覚めたとき、それは必要でした:



  1. それらをフォークする
  2. 一度にフォークされた場所と、最後にどこに移動されたかを理解します(これがsvn checkoutの場合)
  3. このフォークの新しいブランチを作成します
  4. 行われた変更を多かれ少なかれ意味的に関連する小さな断片に分割し、すべてをこのブランチにコミットしようとします


次のインストールがどこから偽造されたかを理解するために、メインプラグが突然ステップ2に現れました。 svn checkoutの場合、少なくとも作業コピーの現在の状態を見ることができます。svnexportの場合、推測は簡単ではありません。 コードの状態に関する半熟考古学的な調査に何度か出会ったので、私は疲れて検索を自動化することに決めました。 既成のソリューションはありませんでした(残念ながら、git bisectはここでは適切ではありません)。次のスクリプトが判明しました。



#!/bin/sh -ef if [ $# -ne 2 ]; then echo "Usage: $0 <git-repo-dir> <candidate-checkout-dir>" exit 1 fi GIT_REPO="$1" CANDIDATE_DIR=$(cd "$2" && pwd) TAB=$(printf '\t') cd "$GIT_REPO" COMMITS=$(git log --all --format=format:%H) # Remember current commit CURRENT_COMMIT=$(git rev-parse HEAD) for C in $COMMITS; do git checkout --quiet $C echo -n "$C$TAB" diff -urN --exclude=.git --exclude=.svn "$CANDIDATE_DIR" . | wc -l done | sort -t"$TAB" -k2,2n # Restore current commit git checkout --quiet "$CURRENT_COMMIT"
      
      





スクリプトは2つのパラメーターを取ります。(1)gitリポジトリーへのパス、(2)次の分岐候補へのパス。プロジェクト開発の一般的なツリーへの「挿入」の場所を見つける必要があります。 このスクリプトは、リポジトリの各チェックアウトとカットイン候補の間の差分ボリューム(行単位)を簡単に計算します。 高い確率で-コミットは、差異の量が最小であり-ブランチの基になる最適な場所があります。 作業の結果は次のようになります。



 3810315aaa238e32a7106312f9973f1d1f0ea097 651
 19b595d87eecc43933ea60d89882319c7ac3f512 835
 989cee69664733b773a4a81cc49e2a1a0cdff38a 872
 9026dae1154f98018c808b73c7f1c6cd09310dc7 885
 802943edf287ad28d5e71a57510400afacb49176 894
 c5bd4050fce754e16664e6e1eeb57a4ff3ed06c6 894
 dcb70c4a2e9fc0431ceb6154ecd1688189362622 908
 ...




これは、問題が次のように何らかの形で解決される可能性が高いことを意味します。

 $ git branch new-organization 3810315aaa238e32a7106312f9973f1d1f0ea097 $ git checkout new-organization $ cp -r ../new-organization-fork/* .
      
      





...その後、すでに変更に対処できるので、それらを部分に分割してコミットしてみてください(おそらく、-dateや--authorを使用しても、理解できる場合は)。



上記のソリューションが他の誰かに役立つなら、私はうれしいです。 改善方法に関するコメントとヒントを歓迎します。



All Articles