2

2 つの異なるチームがあり、それぞれが独自の場所にあり、git を使用しており、それぞれの場所に参照リポジトリがあります。各場所は企業ネットワークにアクセスできますが、2 つのネットワークを直接接続することはできません (信頼してください、私たちは尋ねました)。ファイルを交換することしかできません。それぞれの参照リポジトリを通じて作業を共有できるように、2 つの場所を定期的に同期できるようにしたいと考えています。

要求事項:

  • 交換はどちらの方向でも許可する必要があります。
  • ほとんどの場合、別々のブランチで作業することを期待している場合でも、両側から同時にいくつかのブランチで作業するか、少なくともこれが発生した場合から回復できる必要があります。これは、分岐作業を処理するために統合ステップが必要になる可能性があることを意味します。
  • ほとんどの追跡は自動的に行われる必要があり、手動による介入と、それによる操作エラーのリスクが最小限に抑えられます (致命的ではありませんが、指差しを避けるのが最善です: 信頼は限られています)。特に、git-bundle の man ページで使用されている単一の移動するタグの例は、限られた数のブランチ (数十あります) にさえ拡張できないため、ばかげています。
  • 参照リポジトリは、リモート プッシュ/プルおよび必要に応じて簡単な管理操作によってのみ操作できます。これは、それらが IT の管理下にあり、常に一貫性を保つ必要があるためです。つまり、最初に統合が行われ、その後でのみ変更が行われます。反対側は、統合とともに、ローカル参照リポジトリで公開されました。
  • 毎回リポジトリ全体を送信することはできません (tar-gzip であっても): それ自体が少し大きいだけでなく、連続して送信されるすべてのパッケージが記録に保持されます。すぐに持続不可能になります。
  • 特定の開発者のローカル リポジトリに格納されている情報に依存せずに、すべての開発者が同期手順を実行できるように、必要なすべての情報をローカル参照リポジトリに格納する必要があります。
  • 少なくとも可能な限り、git に反対するのではなく、git と連携してください。ワークフローが奇妙であるほど、git の変更やその他の予期しない状況によって中断する可能性が高くなります。

非要件:

  • 2 つ以上の切断されたサイトの処理。2つはすでに十分に挑戦的です。
  • 夜間処理。交換は手動でトリガーされ、処理されます。
  • コマンドの数または複雑さが限られている。多くの複雑なコマンドが必要な場合でも、その複雑さを常にスクリプトに隠すことができます。
  • オフライン同期を越えます。ストリームと同じように、これは常に問題を意味します。したがって、オフライン同期操作は、方向に関係なく、必要に応じて交代で完全に順序付けられていると想定できます。
  • 支店管理の詳細など。それは私たちの社内業務です。
4

1 に答える 1

1

これまでの解決策は、コマンドを使用してgit bundle、リモート参照に依存して、他の場所が既に持っているものを追跡し、これらのリモート参照をプッシュ/プルで運ぶために思いついたいくつかの複雑な手順を実行することです。私たちの場所を site-a と呼び、リモートの場所を site-b と呼びます。

  • リモート ロケーションに送信するバンドルの生成:

    1. ~/work$> git clone $LOCAL_REF_URL --mirror bundler
    2. ~/work$> cd bundler
    3. ~/work/bundler$> git bundle create ../bundle-site-a-$(date +%Y-%m-%d) --branches --tags --not --remotes=site-b

    バンドラー作業リポジトリーが破棄されるようになりました。

  • リモート ロケーションからのバンドルの統合:

    1. ~/work$> git clone -n $LOCAL_REF_URL bundle-integration
    2. ~/work$> cd bundle-integration
    3. ~/work/bundle-integration$> git checkout --detach
    4. ~/work/bundle-integration$> git fetch origin 'refs/heads/*:refs/heads/*' 'refs/remotes/site-b/*:refs/remotes/site-b/*'
    5. ~/work/bundle-integration$> git remote add site-b ../bundle-site-b
    6. ~/work/bundle-integration$> git fetch --tags site-b 'refs/heads/*'
    7. この時点で、フェッチは、バンドルからの情報で更新されたリモートのサイト b ブランチを通知したので、ここに対応するブランチを持つブランチを統合するために必要な作業をここに挿入します。最初に、git fetch . 'refs/remotes/site-b/*:refs/heads/*'一挙にできるものを早送りし、次にgit checkout $BRANCH && git merge site-b/$BRANCH他のものを早送りします。歴史のどちらの側も書き換えることはできません。また、バンドルが考慮したが含まれなくなったブランチも削除します。
    8. git push --tags origin 'refs/heads/*:refs/heads/*' 'refs/remotes/site-b/*:refs/remotes/site-b/*' --prune完全に成功した場合は、戻ります。私たちは終わった
    9. ~/work/bundle-integration$> git fetch origin(通常のもの)
    10. 前の手順を実行するのに忙しい間に発生した、場所で行われた作業を考慮してください。git checkout $BRANCH && git merge origin/$BRANCH必要に応じてリベースできる独自のマージ作業を除いて、それはまだマージで行う必要があります(より一般的なイディオムですが)。
    11. 8に行く

    バンドル統合の作業リポジトリは破棄される可能性があります。

    注: ステップ 1 は単にミラー クローンにすることはできません。 --mirror は単に --bare を仮定するのではなく、それを強制するため、後で統合を実行する必要性と互換性がありません: 些細な (早送りの) git マージ操作でさえ、非裸のリポジトリ。ステップ 3 は、ブランチから離れて「パーク」するために必要HEADです。そうしないと、ブランチを直接更新しようとすると、ステップ 4 が失敗します。HEADを指しています。リモートバンドルには必ずしもすべてのブランチが含まれているとは限らないため (更新を提供しないものは省略されます)、必要なすべての参照を設定するため、ステップ 4 が必要です (コミットをフェッチしません)。自分の枝に基づいて原点から枝を刈り取るため、原点が持っているすべての枝から始めたいと思います。代わりに、このステップの refspec を -c オプションとして最初のクローンに指定しても機能しないようです。ステップ 5 は必要なので、gitrefs/remotes/site-b/*はステップ 6 で参照を更新する必要があります。

  • リモートの場所が送信されたバンドルのコンテンツを取得できたことを確認したときに、リモートの追跡参照を更新します。

    これは、「リモート ロケーションからのバンドルの統合」の手順に従って実行されますが、送信されたバンドルがリモート ロケーションからのものであるかのように扱われます。その場合、私たちの場所からのブランチはバンドルからの情報で必然的に最新であるため、明らかに統合作業は必要ありません。

于 2019-03-23T23:52:10.503 に答える