発生した問題は、「ローカルコピー」[1]自体が原因ではありません。問題は、リビジョン3で、混合リビジョンの作業コピーをコピーするという事実にあります(http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.basic.in-action .mixedrevs)。
'trunk'を'branches/ a'にコピーするまでスクリプトを実行すると、混合リビジョンの作業コピーがあることがわかります。
>svn st -v
0 0 ? .
1 1 pburba branches
1 1 pburba trunk
2 2 pburba trunk\colors
したがって、「trunk」を「branches / a」にコピーすると、実際にはtrunk@1とtrunk/colors@2がコピーされます。
>svn copy trunk branches\a
A branches\a
>svn st -v
0 0 ? .
1 1 pburba branches
A + - 1 pburba branches\a
A + - 2 pburba branches\a\colors
1 1 pburba trunk
2 2 pburba trunk\colors
>svn ci -m "Copy mixed-rev trunk"
Adding branches\a
Adding branches\a\colors
Committed revision 3.
r3の詳細ログを見ると、これが最も明確にわかります。
>svn log -v -r3
------------------------------------------------------------------------
r3 | pburba | 2013-03-11 15:31:23 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /branches/a (from /trunk:1)
A /branches/a/colors (from /trunk/colors:2)
Copy mixed-rev trunk
------------------------------------------------------------------------
問題のあるマージに進むと、混合リビジョンやローカル変更のない「クリーンな」作業コピーがあります。ここまでは順調ですね:
>svn st -v
5 5 pburba .
5 5 pburba branches
5 5 pburba branches\a
5 5 pburba branches\a\colors
5 4 pburba trunk
5 4 pburba trunk\colors
しかし、svn mergeinfoコマンドを使用して、マージされるリビジョンをプレビューすると、リビジョン2が適格であることがわかります。
>svn mergeinfo --show-revs eligible ^/trunk branches\a
r2
r4
しかし、待ってください、リビジョン2は「色」の追加です。
>svn log -v -r2
------------------------------------------------------------------------
r2 | pburba | 2013-03-11 15:43:52 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /trunk/colors
created trunk/colors with red inside
------------------------------------------------------------------------
リビジョン3でブランチを作成したときに、すでにそれをコピーしました。では、なぜSubversionはそれを再びマージしようとしているのでしょうか?その理由は、私たちが作成したWCからWCへの混合リビジョンのコピーにあります。マージターゲット「branch/a」は、「trunk/colors」を追加する前にtrunk@1からコピーされたことを認識しています。したがって、マージはリビジョン2がbranch / aにマージされていないと見なし、この変更をマージしようとします。同じ名前のファイルがすでに存在する「a」に「colors」を追加すると、ツリーの競合が発生します。
>svn merge ^/trunk branches\a
--- Merging r2 through r5 into 'branches\a':
C branches\a\colors
--- Recording mergeinfo for merge of r2 through r5 into 'branches\a':
U branches\a
Summary of conflicts:
Tree conflicts: 1
>svn st
M branches\a
C branches\a\colors
> local file obstruction, incoming file add upon merge
Summary of conflicts:
Tree conflicts: 1
そこで、混合リビジョンのWCからWCへのコピーでSubversionをだましました。これにより、コピー中にリビジョン2がブランチに効果的にもたらされました。では、なぜSubversionはこれを検出して、リビジョン2をスキップできないのでしょうか。この場合、おそらくそれを行うことができますが、リビジョン2に「トランク」への他の変更が含まれている場合はどうなりますか?例えば:
>svn log -v -r2
------------------------------------------------------------------------
r2 | pburba | 2013-03-11 15:43:52 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /trunk/colors
A /trunk/README
M /trunk
created trunk/colors with red inside, add a README file, and set the
svn:ignore property on trunk
------------------------------------------------------------------------
Subversionは、リビジョンの一部を特定のパスにマージすることをサポートしていません。オールオアナッシングのいずれかです。
~~~~~
では、この問題を回避する方法は?すでに発見したように、URLからURLへのコピーを実行すると解決します。なんで?コピーソースがURLである場合、それは定義上、一定のリビジョンであるためです。
>svn log -v -r3
------------------------------------------------------------------------
r3 | pburba | 2013-03-11 16:02:59 -0400 (Mon, 11 Mar 2013) | 1 line
Changed paths:
A /branches/a (from /trunk:2)
Create branch 'a' from 'trunk' with a URL-to-URL copy.
------------------------------------------------------------------------
ただし、URLからWCへのコピーを使用して同じことを実行することもできます。
svn commit trunk -m 'created trunk/colors with red inside'
-svn copy trunk branches/a
+svn copy ^/trunk branches/a
svn commit branches/a -m 'created branches/a'
または、元のスクリプトでWCからWCにコピーする前にWCを更新するだけです。
svn commit trunk -m 'created trunk/colors with red inside'
+svn update
svn copy trunk branches/a
svn commit branches/a -m 'created branches/a'
元のソリューションであるURLからURLへのコピーとそれに続く更新は、IMOの最良のオプションです。更新とWCからWCへのコピーとURLからWCへのコピーはどちらも、コミットされる前にコピーに追加の変更を加えることができる可能性を考慮に入れています。ブランチが作成されるリビジョンには、コピー以外のその他の変更。そうは言っても、これらのオプションはすべて正常に機能します[2]。
[1] Subversion-speakでは、これを通常、working-copy-to-working-copyコピー、または略してWC-to-WCコピーと呼びます。これをURLからURL、URLからWC、またはWCからURLのコピーと比較してください。WCからURLへのコピーも、上記の問題に対して脆弱です。'svncopy--help'も参照してください。
[2]もちろん、これら3つのオプションのいずれかを使用してもテキストの競合が発生しますが、ブランチの作成後にトランクとブランチの両方で「colors」ファイルに互換性のない変更を加えたため、これは予想されます。
>svn merge ^/trunk branches\a
--- Merging r3 through r5 into 'branches\a':
C branches\a\colors
--- Recording mergeinfo for merge of r3 through r5 into 'branches\a':
U branches\a
Summary of conflicts:
Text conflicts: 1
Conflict discovered in file 'branches\a\colors'.
Select: (p) postpone, (df) diff-full, (e) edit, (m) merge,
(mc) mine-conflict, (tc) theirs-conflict, (s) show all options: p
>svn st
M branches\a
C branches\a\colors
? branches\a\colors.merge-left.r2
? branches\a\colors.merge-right.r5
? branches\a\colors.working
Summary of conflicts:
Text conflicts: 1