2

私は Git に比較的慣れていませんが、試してみたいと思います (vs SVN と Bazaar)。

次のような状況のワークフローを誰かに勧めてもらえますか:

  • 複数のプロジェクトを含む 1 つの SVN リポジトリ
  • 1つの作業コピー「src」

アイデアは、「src」でプロジェクトAまたはプロジェクトBをチェックアウトする必要があるということです。両方のプロジェクトにはいくつかのブランチがあります。

今のところ、各プロジェクトに 1 つずつ、SVN リポジトリの 2 つの git クローンを作成しました。(私は --bare repos を好みましたが、それは動作しませんgit svn clone

次に、「src」に git リポジトリを作成し、git remote add projA ..a_repo_gitgit remote add projB ..b_repo_git.

これで、「git remote」を使用して「src」から両方を見ることができ、「git remote show projA」でそれらのブランチを見ることができます

そして今、トラブル..

  • projA/projB のいずれかのブランチを「src」に入れるにはどうすればよいですか?
  • それらを変更してから、それらをプッシュバックできるようにするにはどうすればよいですか (最初に git_repos に、または直接 SVN リポジトリに)。
  • この「ワークフロー」は大丈夫ですか、それとももっと良いアイデアがありますか?

私は src:git checkout --track -b work_branch projA branch_in_A で試しましたが、「フェッチ」をいじった後、何とか取得できました。しかし、その後、それを に戻しa_repo_git、次に SVN に戻すのに問題がありました。ほとんど試行錯誤でした。

認めざるを得ませんが、リモート ブランチにはまだ問題があります。origin local_branch:origin_branch(そして、" " または " origin origin_branch:local_branch"、または " origin origin_branch" または" "を使用しなければならないときに迷子になりますorigin/origin_branch! もう少し読むために Git マニュアルに戻ります。)

4

2 に答える 2

3

過去数日間、新しいレポの助けを借りて本当にうまく簡単に作業できたので、質問を更新していません:)

これが私が最終的にやったことです:

同じディレクトリで 2 つの SVN リポジトリを初期化します。(現時点では思い出すことはできませんが、以前に同じディレクトリで「git init」が行われた可能性があります:

mkdir src && cd src
(これについては不明です: git init)
git svn init --stdlayout --prefix=projA/ -RprojA file:///path/to/svn/repo/A
git svn init --stdlayout --prefix=projB/ -RprojB file:///path/to/svn/repo/B

「--stdlayout」は、SVN リポジトリが標準形式であり、トランク、ブランチ、およびタグが同じレベルであることを意味します。

ブランチ名には「--prefix」を使用します。「git branch -a」を実行すると、プロジェクト A のすべての SVN ブランチに「projA」というプレフィックスが付きます (例: projA/branch_name_of_A)。Bさんも同じです。

-R オプションは、git リポジトリ内の SVN リポジトリの名前を設定します (これは、SVN リポジトリ/プロジェクトを参照するときに git で使用する名前です)

file:///path は SVN リポジトリへのパスであり、この場合はリポジトリ内のプロジェクトへのパスです。サーバーなしでフラットファイルリポジトリを使用したため、「file://」を使用します。SVNサーバーの場合、http://でも問題なく動作すると確信しています。

このステップの後、好奇心から src/.git/config ファイルを調べました。上記の 2 つのコマンドにより、複数の「svn-remote」セクションが作成されました。各プロジェクトに 1 つ (-R オプション)、および「svn」と呼ばれる一般的なセクションです。エントリを変更したので、プロジェクトへの参照のみがあります。各参照には、リポジトリ パス (フェッチ) とタグ/ブランチ/トランクのエントリがありました。ファイルを見ると、何を変更する必要があるかがわかります。

この後、次を使用して各プロジェクトの内容を取得しました

git svn fetch projA #プロジェクトAの中身のリポジトリをダウンロード
git svn fetch projB #プロジェクト B リポジトリの内容をダウンロード

ここで、「git branch -a」を実行すると、2 つのリポジトリからのすべてのブランチと、マスター ブランチ (ローカル) が表示されます。「git branch -r」はブランチを表示しませんでした。おそらく、それらは「リモート」ではなく「svn-remote」であるためです

現在の「マスター」ブランチは、2 番目のプロジェクトのトランクを指していました。プロジェクトから別のプロジェクトに切り替えるときに問題が発生するため、削除することにしました。

各プロジェクトのトランクを指す 2 つの新しいブランチを作成し、「マスター」ブランチを削除しました。

git checkout -b master_project_A プロジェクト/トランク
git checkout -b master_project_B プロジェクト/トランク
git ブランチ -D マスター

それでは、「ワークフロー」についてです。プロジェクト A に取り組む:

git checkout master_project_A #プロジェクト A に切り替える
git svn rebase #SVN リポジトリの更新をチェック
git checkout -b work_on_A master_project_A #プロジェクト A のマスターから始まるブランチを作成

work_on_A で作業します。コミットなど

git checkout master_project_A #プロジェクト A のマスターに戻る
git svn rebase #SVN リポジトリの更新をもう一度確認します
git checkout work_on_A #work ブランチに戻る
git rebase master_project_A #プロジェクト A のマスターからの変更を含むブランチの更新
git checkout master_project_A #プロジェクト A のマスターに戻る
git merge work_on_A #プロジェクト A のマスターにマージ作業ブランチからの変更
git svn dcommit #master_project_A がそのトランクを指していたため、トランク内の SVN リポジトリへの変更をコミットします

SVN から既存のブランチをチェックアウトしたい場合は、次のように実行できます。

git checkout -b work_on_branch projA/branch_name

仕事、仕事、仕事

git svn rebase #projA/branch_name からの変更を更新します
git svn dcommit #commit 更新を SVN リポジトリのブランチに戻します

プロジェクトの場合、BI はまったく同じことを実行できます。最終的に、プロジェクト A または B のコンテンツを同じディレクトリ「src」に格納し、同じ git リポジトリから SVN リポジトリの両方のプロジェクトにアクセスできます。:D

ローカル ブランチを作成して SVN リポジトリにプッシュする方法がまだわかりません。

また、コマンド「リセット」(「git reset --hard projPrefix/branch」) を知っておくと便利かもしれませんが、それを使用していくつかのことを壊したので、これは別の機会に残しておく方がよいかもしれません。

これが誰かに役立つことを願っています!

乾杯、アレックス

于 2009-03-10T20:12:10.850 に答える
2

最初に、1つのリモートリポジトリと1つのローカルリポジトリのより単純なケースを考えてみましょう。

remoteローカルリポジトリのAは、他のリポジトリへの参照として「のみ」機能します。を使用fetchして、リモートオブジェクトをローカルストアに取得できます。

git remote add upstream git://...
git fetch upstream

これで、からのすべてのブランチをupstreamローカルで参照し、を使用して作業できるようになりましたupstream/branchname。リモートブランチで実際に作業するには、常にリモートブランチを追跡するローカルブランチを作成する必要があります。

git checkout -b new_local_branchname upstream/branchname

これで、ローカルで作業して、好きなだけコミット/マージできます。最後のステップとしてpush、中央リポジトリに変更を戻すことができます。重要な点は、AFAIKが実行pushできるのは早送りマージ、つまり変更をアップロードして新しいヘッドを設定することだけであるということです。したがって、ローカルブランチを準備して、ローカルブランチの先端でローカル変更が開始されるようにする必要があります。これを実現するために使用rebaseするか、ローカルで作業しているときに中央リポジトリを変更しないようにすることができます。

これは、2つのリポジトリ間の単純なワークフローについて説明しています。次に、SVNの特定のケースについて説明します。

git svn実行できる変更の種類をさらに制限することにより、全体像が複雑になります。リモートと同様に、svnブランチを直接変更することは絶対にしないでください。ただし、常にローカルブランチで作業してください。リモートとは異なりgit svn、必要なメタデータを追加するためにコミットがSVNリポジトリに入るときに、常にコミットを変更します。SVNブランチでのコミットは、ローカルブランチでの元のコミットとは常に異なるハッシュを持つため、この最後の事実がおそらく多くの問題の原因です。

最後に、同じリポジトリ内の複数のプロジェクトに関する質問です。

Gitは、同じリポジトリ内の複数のブランチの並列チェックアウトをサポートしていません。複数のリポジトリを統合するためにサブモジュールを調べることをお勧めします。

于 2009-03-04T10:08:47.403 に答える