5

新しい 1.8 サブバージョン クライアントに問題があります (TortoiseSVN 1.8.5 と SlikSVN 1.8.5 を使用しています)。再統合後も機能ブランチを使用し続けることができるという SVN 1.8 の新しい機能が機能しない場合があるようです。

トランクにローカルの mergeinfo (ファイルまたはサブツリーの Mergeinfo) が含まれている場合は機能しません。これにより、再統合後のブランチの再利用で問題が発生する可能性があります。これは、ブランチの再利用が「キープ アライブ ダンス」(記録のみのオプションを使用) を使用して行われた場合、1.7 クライアントでは問題ではありませんでした。

この問題をゼロから説明するスクリプトを作成しました。1.8 クライアントを使用して、空のリポジトリに対して実行できます。

以下のスクリプトには 10 のステップがあります。手順 1 ~ 5 は、トランクにローカルの mergeinfo を持つ開始状況を作成するために使用されます。手順 6 ~ 9 は、機能ブランチの有効期間中にトランクに加えられる変更をシミュレートします2。ステップ 10 は、再統合後の機能ブランチの再利用の最初のステップをシミュレートする失敗ステップです。

これはステップ 10 のエラーです。

svn: E195016: Reintegrate can only be used if revisions 8 through 11 were pre
viously merged from svn://svn2010/practice/branches/featurebranch2 to the reinte
grate source, but this is not the case:
  trunk/file1.txt
    Missing ranges: /trunk/file1.txt:9

これは (Windows) スクリプトです。

@ECHO OFF
ECHO ------------------------------------------------------------------
ECHO STEP 0: Create a repository
ECHO ------------------------------------------------------------------
if exist repo rmdir repo /S/Q
if exist trunk rmdir trunk /S/Q
if exist featurebranch1 rmdir featurebranch1 /S/Q
if exist featurebranch2 rmdir featurebranch2 /S/Q
svnadmin create repo --compatible-version 1.8
REM Make url based on current directory and replace backslashes by forward slashes
set url="file:///%cd:\=/%/repo"
ECHO url=%url%

ECHO ------------------------------------------------------------------
ECHO STEP 1: Create a trunk with 2 files
ECHO ------------------------------------------------------------------
svn mkdir -m "Create trunk" %url%/trunk
svn checkout %url%/trunk
echo Original file contents created in the trunk. > trunk\file1.txt
echo Original file contents created in the trunk. > trunk\file2.txt
svn add trunk\file1.txt
svn add trunk\file2.txt
svn -m "Added 2 files" commit trunk

ECHO ------------------------------------------------------------------
ECHO STEP 2: Create a copy (feature branch) from the trunk
ECHO ------------------------------------------------------------------
svn mkdir -m "Create branches dir" %url%/branches
svn copy -m "Create featurebranch1" %url%/trunk %url%/branches/featurebranch1

ECHO ------------------------------------------------------------------
ECHO STEP 3: Modify both files in the feature branch
ECHO ------------------------------------------------------------------
svn checkout %url%/branches/featurebranch1
echo Additional file contents created in featurebranch1. >> featurebranch1\file1.txt
echo Additional file contents created in featurebranch1. >> featurebranch1\file2.txt
svn -m "Modified 2 files in featurebranch1" commit featurebranch1

ECHO ------------------------------------------------------------------
ECHO STEP 4: Merge both files from featurebranch1 to the trunk to 
ECHO         create local mergeinfo on both files
ECHO ------------------------------------------------------------------
svn update trunk
svn merge %url%/branches/featurebranch1/file1.txt trunk/file1.txt
svn merge %url%/branches/featurebranch1/file2.txt trunk/file2.txt
svn -m "Merged 2 files from featurebranch1 to trunk" commit trunk

ECHO ------------------------------------------------------------------
ECHO STEP 5: Delete featurebranch2, we only needed it for the
ECHO         initial setup
ECHO ------------------------------------------------------------------
svn delete -m "Delete featurebranch1" %url%/branches/featurebranch1

ECHO ------------------------------------------------------------------
ECHO STEP 6: This is the start of the problematic scenario
ECHO         Create a new featurebranch2 from the trunk and a wc for it
ECHO ------------------------------------------------------------------
svn copy -m "Create featurebranch2" %url%/trunk %url%/branches/featurebranch2
svn checkout %url%/branches/featurebranch2

ECHO ------------------------------------------------------------------
ECHO STEP 7: Modify the contents of file1.txt in the trunk and leave
ECHO         the contents of file2.txt unchanged (this is important)
ECHO ------------------------------------------------------------------
echo Additional file contents created in the trunk. >> trunk\file1.txt
svn -m "Modified file1.txt in the trunk" commit trunk

ECHO ------------------------------------------------------------------
ECHO STEP 8: Sync merge the trunk to featurebranch2
ECHO ------------------------------------------------------------------
svn update featurebranch2
svn merge %url%/trunk featurebranch2
svn -m "Sync merged the trunk into featurebranch2" commit featurebranch2

ECHO ------------------------------------------------------------------
ECHO STEP 9: Reintegrate featurebranch2 back into the trunk
ECHO ------------------------------------------------------------------
svn update trunk
svn merge %url%/branches/featurebranch2 trunk
svn -m "Reintegrated featurebranch2 back into the trunk" commit trunk

ECHO ------------------------------------------------------------------
ECHO STEP 10: Try to reuse featurebranch2 after it was reintegrated
ECHO          Sync merge it from the trunk. THIS FAILS with SVN 1.8 
ECHO ------------------------------------------------------------------
svn update featurebranch2
REM on SVN 1.7 we would use --record-only
svn merge %url%/trunk featurebranch2

:EOF

なぜこれが起こるのかわかりません。また、エラーはfile1.txtの範囲が欠落していると報告しますが、mergeinfoが欠落しているのはfile2.txtのようです。解決策ではありませんが、トランクの file2.txt にあるローカルの mergeinfo を削除すると、問題が解決するようです。これは、エラー メッセージが間違ったファイルについて何かを報告していることも示唆しています。

編集:@gbjbaanbへの応答エラーメッセージは同じですが、この問題はあなたが指摘しているものよりも微妙です。私の場合、失敗しているのはトランクへの再統合ではなく、その後のブランチの再利用です。

また、file1.txt と file2.txt の両方の mergeinfo を見ると、file2.txt に featurebranch2 の mergeinfo レコードが欠落しているように見えるため、エラーが示唆するように file1.txt ではなく file2.txt に問題があります。file1.txt は featurebranch2 の存続期間中にトランクで変更され、file2.txt はマージではなかったため、ステップ 8 のマージ中にトランクに関する情報が file2.txt に設定されませんでした。これが開始点であると思います。脱線する。これはトランクへの再統合には影響しませんが、その後のフィーチャー ブランチの再利用を妨げます。

編集: @David W への応答--record-only -c 11を試しましたが、これは Windows 側でも機能します。私はすでに-cなしでそれを試していました(通常はそうすべきではありませんが、この場合は他に変更はありません)、次のように報告されます:

svn: E200004: The required merge is reintegrate-like, and the record-only option
 cannot be used with this kind of merge

--record-only -c 1-11も試してみましたが、これは-cを使用しない場合と同じであると予想していました(11 は HEAD であるため)。私の最初の期待は、 -cを使用しない場合と同じように失敗することでしたが、そうではありませんでした。-c 11と同じ方法で成功しました。

しかし、私の投稿の要点は、SVN 1.8 ではキープアライブのトリックを行う必要がないということです。(ドラフト)ドキュメントには次のように書かれています:

ブランチをトランクに再統合した後にブランチを削除しないことを選択した場合は、引き続きトランクから同期マージを実行してからブランチを再統合することができます[37]。これを行うと、最初の再統合後にブランチに加えられた変更のみがトランクにマージされます。( http://svnbook.red-bean.com )。

また、Subversion 1.8 リリース ノートから:

自動再統合マージを使用すると、任意の順序で 2 つのブランチ間を行ったり来たりするマージが可能です (「キープアライブ ダンス」は不要になりました)。最良の結果を得るには、適格なすべてのリビジョンを常にマージすることをお勧めします。つまり、svn merge の -r または -c オプションを使用しないでください。適格なリビジョンのサブセットだけをマージすると、将来のマージ中に問題が発生する可能性が高くなります。( https://subversion.apache.org/docs/release-notes/1.8.html )

したがって、私のポイントは、キープアライブのトリックを使用しないこのブランチの再利用は、ローカルのmergeinfoに直面して明らかに機能しないということであり、私のスクリプトはそれを示しているようです。

報告された範囲の数値を除いて、不足している範囲に関する警告が正しい可能性があると思われる場合は、スクリプトのどこで範囲が不足している可能性があるかを教えてください。私のスクリプトは、トランクとブランチの間を簡単に行き来するだけで、両方で並行して作業する必要はありません。

また、次のように追加して file2.txt を変更する理由を説明してください: "echo トランクで作成された追加のファイルの内容。 >> トランク\file2.txt" を手順 7 に追加すると、手順 10 でエラーが発生しなくなります。追加ファイルの変更トランク上では、範囲の欠落の問題を解決できません。

4

2 に答える 2

1

バージョン 1.8 がブランチの再利用の問題を解決するとは思えません。この問題は、リビジョンの番号付けと、Subversion がどのリビジョンがどこにあるかを追跡する方法に関係しています。

リビジョン 100 から始めましょう。トランクに変更を加えました。これらの変更をすべてブランチにマージしたいと考えています。標準のマージを実行し、リビジョン 101 を作成します (私のブランチで)。私のブランチでは、svn:mergeinfoリビジョン 100 までのトランクのすべての変更が私のブランチにあることを示しています。これまでのところ、私の最後のトランク リビジョンはリビジョン 100 です。すべて問題なく良好です。

ここで、変更をトランクに再統合したいと考えています。双方向マージを行う再統合マージを行うので、マージ後、トランクはブランチのように見えます。これはリビジョン 102 で、私のトランクにあります。これまでのところ、リビジョン 100 をブランチにマージしました。リビジョン 101 はトランクにはありませんが、トランクにはリビジョン 102 があります。

ここで、トランクに別の変更を加えます。これはリビジョン 103 です。これは私のブランチでも必要であると判断しました。

私のブランチは、リビジョン 100 までのトランク上のすべてのリビジョンが私のブランチにマージされたと言っています。ここまでは順調ですね。ここで別のマージを行います。トランクには、リビジョン 102 とリビジョン 103 の 2 つの新しいリビジョンがあります。 によるとsvn:mergeinfo、これらの両方のリビジョンの変更をブランチにマージする必要があります。

ちょっと待って!リビジョン 102 は、ブランチからトランクへの再統合マージでした。この情報はすでにブランチにあります。リビジョン 102 を再度マージすると、ブランチが台無しになります。おそらく大量のマージ競合が発生するでしょう。

Subversion がこの問題を検出する実際の方法はありません。この問題を解決するには、次の 2 つの方法があります。

  1. ブランチを再利用したり、
  2. asvn merge --record-only -r102を実行して、リビジョン 102 がすでにブランチにあることを記録します。これにより、ファイルは変更されません (プロパティの値を除くsvn:mergeinfo)。

svn:mergeinfo#2 を行った場合、リビジョン 102 までのトランクのすべての変更がブランチにあることが示されるため、トランクからブランチに変更をマージできるようになりました。リビジョン 103 の変更のみをブランチに配置する必要があります。

それで、あなたの問題は何ですか?

Subversion は、通常の (3 方向) マージと再統合(2 方向) マージを実行する必要があるかどうかを検出できるようになりました。--reintegrationパラメータを使用する必要はなくなりました。

ただし、トランクにあるすべての変更をブランチに以前にマージしていない限り、再統合マージを行うことはできません。

リビジョン 95 を除くすべてのリビジョンをトランクからブランチにマージしたとします。トランクにはリビジョン 95 の変更が含まれていますが、ブランチにはこの変更がありません。reintegration mergeを実行すると、双方向のマージが実行されます。トランクをブランチと一致させるつもりです - リビジョン 95 で行った変更がない私のブランチです。

ブランチをトランクにマージすると、トランクで行ったリビジョン 95 の変更が失われます。

あなたはそれが起こることを望んでいません。したがって、再統合マージを行っているが、すべてのトランクの変更をブランチにマージしていない場合、Subversion は警告します。

あなたのメッセージをもう一度見てみましょう:

svn: E195016: Reintegrate can only be used if revisions 8 through 11 were previously merged from svn://svn2010/practice/branches/featurebranch2 to the reintegrate source, but this is not the case:  
    trunk/file1.txt
        Missing ranges: /trunk/file1.txt:9

これは、リビジョン 11 までのすべての変更をトランクに再統合する必要があることを示しています。ただし、リビジョン #9 はブランチにマージされませんでした。再統合マージを行うと、トランクでこの変更が失われます。

続行するには、--force(悪い考えです) を使用するか、トランクからブランチに別のマージを実行して、リビジョン 9 の変更をブランチに取得する必要があります。

これが完了したら、ブランチからトランクへのマージを実行できます。

これで状況が明確になることを願っています。


スクリプトの Unix バージョン

これが私のバージョンのスクリプトです。Windows Batch から Bash シェルに多かれ少なかれ変換されました。主な違いは次のとおりです。

  • ステップ 9.5: トランクの最後の変更を見つけました。これは、機能ブランチを再利用するために記録する必要があるリビジョンです。
  • ステップ 10:--record-only機能ブランチ-cを再利用する必要があるため、機能ブランチで使用します。Subversion 1.8 では問題なく動作します。これは、Mac OS X Mavericks と RHEL 6 の両方で問題なく動作します。6.5 では試していません。

このシナリオにおける SVN 1.7 と SVN 1.8 の主な違いは、SVN 1.8 が問題について警告しようとするのに対し、SVN 1.7 は警告なしでマージを実行することです。リビジョン 9 が報告された理由はわかりません。これは、このブランチからトランクへの最後のマージでした。メッセージには、再統合されたリビジョンであるリビジョン 11 が示されているはずです。このエラーは、あらゆる種類のエラーよりも、エンジニアリング言語のスキルによるものだと思います。

ちなみに、実行する代わりに:

svn merge  --record-only -c$last_changed $URL/trunk featurebranch2

私がこれを実行した場合:

svn merge  --force $URL/trunk featurebranch2

マージは、Subversion 1.7 の場合と同様に行われます。この場合、マージは正しく行われますが、最終的なマージを行う前にトランクまたはブランチのファイルを変更しなかったことが原因です。ただの運だった

#! /bin/bash
# svnscript.sh
#
# ECHO STEP 0: Create a repository
echo "Create Repository"
[[ -d "repo" ]] && rm -rf repo
[[ -d "trunk" ]] && rm -rf trunk
[[ -d "featurebranch1" ]] && rm -rf featurebranch1
[[ -d "featurebranch2" ]] && rm -rf featurebranch2
svnadmin create repo --compatible-version 1.8
URL="file://$PWD/repo"
echo "URL=$URL"
########################################################################
# STEP 1: Create a trunk with 2 files
########################################################################
echo "Step 1: Create a trunk with 2 files"
svn mkdir -m"Create trunk" $URL/trunk
svn checkout $URL/trunk
echo Original file contents created in the trunk. > trunk/file1.txt
echo Original file contents created in the trunk. > trunk/file2.txt
svn add trunk/file1.txt
svn add trunk/file2.txt
svn -m "Added 2 files" commit trunk

########################################################################
# STEP 2: Create co copy (feature branch) from the trunk
########################################################################

echo "STEP 2: Create a feature branch from the trunk"
svn mkdir -m "Create branches dir" $URL/branches
svn copy -m "Create featurebranch1" $URL/trunk $URL/branches/featurebranch1

########################################################################
# STEP 3: Modify both files in the feature branch
########################################################################

echo "STEP 3: Modify both files in the feature branch"
svn checkout $URL/branches/featurebranch1
echo "Additional file contents created in featurebranch1." >> featurebranch1/file1.txt
echo "Additional file contents created in featurebranch1." >> featurebranch1/file2.txt
svn -m "Modified 2 files in featurebranch1" commit featurebranch1

########################################################################
# STEP 4: Merge both files from featurebranch1 to the trunk
########################################################################

echo "STEP 4: Merge both files from featurebranch1 to the trunk to "
echo "        create local mergeinfo on both files"

svn update trunk
svn merge $URL/branches/featurebranch1/file1.txt trunk/file1.txt
svn merge $URL/branches/featurebranch1/file2.txt trunk/file2.txt
svn -m "Merged 2 files from featurebranch1 to trunk" commit trunk

########################################################################
# STEP 5: Delete Feature1 branch: No longer needed
########################################################################

echo "STEP 5: Delete featurebranch2, we only needed it for the"
echo "        initial setup"
svn delete -m "Delete featurebranch1" $URL/branches/featurebranch1

########################################################################
# STEP 6: This is the start of the problematic scenario
########################################################################
echo "STEP 6: This is the start of the problematic scenario"
echo "        Create a featurebranch2"
svn copy -m "Create featurebranch2" $URL/trunk $URL/branches/featurebranch2
svn checkout $URL/branches/featurebranch2

########################################################################
# STEP 7: Modify the contents of file1.txt. in trunk
########################################################################

echo "STEP 7: Modify the contents of file1.txt in the trunk and leave"
echo "        the contents of file2.txt unchanged (this is important)"

echo "Additional file contents created in the trunk." >> trunk/file1.txt
svn -m "Modified file1.txt in the trunk" commit trunk

########################################################################
# STEP 8:Sync merge the trunk to featurebranch2
########################################################################

echo "STEP 8: Sync merge the trunk to featurebranch2"
svn update featurebranch2
svn merge $URL/trunk featurebranch2
svn -m "Sync merged the trunk into featurebranch2" commit featurebranch2

########################################################################
# STEP 9: Reintegrate featurebranch2 back into the trunk
########################################################################

echo "STEP 9: Reintegrate featurebranch2 back into the trunk"
svn update trunk
svn merge $URL/branches/featurebranch2 trunk
svn -m "Reintegrated featurebranch2 back into the trunk" commit trunk

########################################################################
# STEP 9.5: Get the last change info on Trunk
########################################################################

svn update trunk
last_changed=$(svn  info  $URL/trunk | sed -n '/Last Changed Rev/s/.*: //p')

########################################################################
# STEP 10: Try to reuse featurebranch2 after it was reintegrated
#          This time, we'll use the --record-only with the change on trunk
########################################################################
echo " STEP 10: Try to reuse featurebranch2 after it was reintegrated"
echo "          Sync merge it from the trunk. THIS FAILS with SVN 1.8 "

svn update featurebranch2
svn merge  --record-only -c$last_changed $URL/trunk featurebranch2
svn commit -m"It works on MY machine!" featurebranch2
于 2014-03-19T18:39:45.717 に答える