- Subversionにはメインツリーがあり(もちろん最初はcvs)、「パーティーのメインコース」が開催されました-いくつかの大規模な変更が行われ、新しい機能が追加され、グローバルエラーが修正されました。
- 特定のインストールは以下によって行われました:
- せいぜいsvn checkoutで、その後svn updateで更新されました。 ほとんどすべてのインストールで、ローカルの改善は「ライブ」で行われ(少なくとも構成ファイルは修正されました)、これらの変更はどこにもコミットされませんでした。 次のsvn更新でアップストリームの変更が競合を作成した場合-競合は、変更を追跡することなく、更新を行ったプログラマーによって「その場で」解決されました
- 最悪の場合、svnエクスポートは、もちろん、まったく更新されず、エクスポート日の開発レベルで一度だけ(または少なくとも当局が意識を変えるまで)残ります。 特に無視された場合(1990年代後半から2000年代初頭)には、チェックアウトを行う物理的な機会がなかったため、これも行われました。
もちろん、実際には、このシステムを感謝しているお客様は、サポート、バグ修正、さらにはシステムコアのグローバルな改善を希望する場合があります。
短い協議の後、svnでこのような分散システムをサポートし続けることは不適切と見なされ、gitに移行することが決定されました。
問題1-マスターツリーをsvnからgitにドラッグすることは、一般的にgit-svnの標準的な手段によって簡単に決定されました。
問題セット2-さまざまなインストールの多数のフォークをこのツリーに注ぎ込む方法-「到着したとき」に分解することが決定されました。 次の組織が目覚めたとき、それは必要でした:
- それらをフォークする
- 一度にフォークされた場所と、最後にどこに移動されたかを理解します(これがsvn checkoutの場合)
- このフォークの新しいブランチを作成します
- 行われた変更を多かれ少なかれ意味的に関連する小さな断片に分割し、すべてをこのブランチにコミットしようとします
次のインストールがどこから偽造されたかを理解するために、メインプラグが突然ステップ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を使用しても、理解できる場合は)。
上記のソリューションが他の誰かに役立つなら、私はうれしいです。 改善方法に関するコメントとヒントを歓迎します。