9

あるトピックブランチから別のトピックブランチにリビジョンのサブセットをマージするという問題に直面しています。私は git-svn を使用しているので、これにチェリーピッキングを使用できるかどうかを知りたいと思っていました。Subversion を使用すると、次のようになります。

svn merge -c A
svn merge -c B
svn merge -c C
...
svn commit ...

これをやろうとするとどうなりますか?

git checkout branch1
git cherry-pick A
git cherry-pick B
git cherry-pick C
git svn dcommit

git svn のマンページを読んだ場合、答えは「それをしないでください」ですが、その git svn をグーグルで検索すると、この種の問題ではるかに優れた仕事をするという印象を受けます。

4

3 に答える 3

9

git-svnには、cherry-picked コミットに関連する深刻な問題がありました。

すでに svn リポジトリにコミットされているコミットa1b2c3f9があるとします。

  $ git show a1b2c3f9
  commit a1b2c3f9...
  Author: Happy Dev <happyd@43fe5c0-...>
  Date:   Mon Nov 14 13:01:38 2011 +0000

  Commit message

  git-svn-id: https://host/svn/branches/some-branch@1000 43fe5c0-...

このgit-svn-id行を参照してください。これは、git-svnがコミットが Subversion リポジトリのどこにあるかを理解する方法です。

ここで、現在使用しているマスターブランチにこのコミットをチェリー ピックします。

  $ git cherry-pick a1b2c3f9

マージの競合がなければ、git は新しいコミット、たとえば9f3c2b1aを作成します。

  $ git show 9f3c2b1a
  commit 9f3c2b1a...
  Author: Happy Dev <happyd@43fe5c0-...>
  Date:   Mon Nov 14 13:01:39 2011 +0000

  Commit message

  git-svn-id: https://host/svn/branches/some-branch@1000 43fe5c0-...

そのため、Git はまったく同じメッセージでコミットを作成しました。これは深刻な問題を引き起こしました。以前のバージョンのgit-svnは、そのようなコミットを間違ったブランチ( ^/trunk/ではなく^/branches/some-branch ) に送信していました。

この問題は、Git の最新バージョンでは既に修正されています。しかし、まだ存在する別のものがあります:

git-svnは、Subversion のマージ追跡メカニズムを尊重しません。

Subversion トラックは、実行されたチェリー ピックに関する情報をマージするため、コマンド

  $ svn merge -c 1000 ^/branches/some-branch trunk-working-copy

次のように、 trunk-working-copyのsvn:mergeinfoプロパティを調整します。

  + /branches/some-branch: 1000

このようにして Subversion は、この特定のリビジョンが既に^/trunk/ブランチにマージされていることを理解し、それ以降のマージでこの変更をスキップします。

実行するgit cherry-pickと、 Subversion リポジトリはsvn:mergeinfo のgit svn dcommit変更を取得しません。


免責事項は次のとおりです。現在、私はSmartGit
に取り組ん でいませんが、SmartGit 開発者と緊密に連携して働いています。

Syntevo社は、 git-svnの優れた代替品であるSmartGitを開発しました。この Git クライアントは、上で説明したすべての問題を解決します。

したがって、a1b2c3f9コミットをチェリーピックします。

  $ git cherry-pick a1b2c3f9

その結果、9f3c2b1aコミットを取得し、それを Subversion リポジトリにプッシュします。SmartGit はマージ追跡情報を保持するためにあらゆることを行うため、^/trunk/ブランチはsvn:mergeinfoプロパティの必要な変更を取得します。

  + /branches/some-branch: 1000

SmartGit 自体から、または Git コマンド ライン インターフェイスを使用して、Git のチェリー ピックを実行できます。2 番目のケースでは、コミット メッセージに、cherry-pick ソースのgit-svn-id行が含まれている必要があります。

SmartGit はプロプライエタリ ソフトウェアですが、非商用の場合は無料です。多くの優れた機能があります。詳細については、 SmartGit のドキュメントを参照してください 。

git-svnに関する特定の問題を解決する別の興味深いプロジェクト— SubGit があります。基本的に、これは Subversion リポジトリと Git リポジトリの間で変更を同期するためのサーバー側のソリューションです。git-svnよりはるかに優れており、問題はありません。

svn-via-git ユーザーとして、あなたもそれに興味があるかもしれません。

于 2011-12-06T22:59:20.983 に答える
8

を実行すると、svn 追跡ブランチと git 内のものとの間で、for each git commitgit svn dcommitが順次実行されます。あなたの例では、変更をすぐにコミットするため、それは 3 つのコミット (A、B、および C ごとに 1 つ)です。確かに、これらのコミットを実行して svn にプッシュする前に、これらのコミットを 1 つのリビジョンにまとめるために使用できます。svn commitHEADgit cherry-pickgit rebase -igit svn dcommit

実行すると、すべてのプロパティgit-svnが完全に無視されます。マニュアルページsvn:mergeinfoから:git-svn

svn:executable を除くすべての SVN プロパティを無視します。未処理のプロパティはすべてログに記録されます$GIT_DIR/svn/<refname>/unhandled.log

于 2010-12-13T22:49:09.553 に答える
1

これにはまったく問題はありません。これまで仕事で何度もやっていました。さらに、過去に TortoiseSVN でブランチ全体をマージするのに問題があったとき、私はトピック ブランチをトランクの上にリベースし、すべてのコミットを 1 つのコミットにまとめました。これは本質的にチェリー ピックに似ています。それはうまくいきました。

于 2010-12-13T13:10:25.277 に答える