web-dev-qa-db-ja.com

Subversion作業コピーでディレクトリの名前を変更するための適切な方法

VCS(通常のsvn、git、git-svnユーザー)にある程度精通している間は、この独特なSVNの動作に頭を悩ませることはできません。

SVN作業コピーのディレクトリの名前を「クリーン」な状態から変更する必要があるときはいつでも、つまりsvn statusは何も返さず、他のすべての変更がコミットされています-そうです(svn docが示唆しているとおりです):

svn mv foo bar
svn commit

SVNは大声で文句を言います:

Adding         bar
Adding         bar/toto
Deleting       foo
svn: Commit failed (details follow):
svn: Item '/test/foo' is out of date

あなたの好きなように:

svn update

与えるもの:

   C foo
At revision 46.
Summary of conflicts:
  Tree conflicts: 1

ツリーの競合がありますサードパーティの変更は発生していません。明らかに、このツリーの競合の混乱から抜け出すための唯一の方法は一般的です(svn red bookから):

svn resolve --accept working -R .
svn commit

リポジトリでリモートで名前を変更し、作業コピーを更新するのは非常に頭が痛いようです:

url=$(svn info | grep -e '^URL:' | sed 's/^URL: //') svn mv $url/foo $url/bar
svn update

不足しているフォルダの名前を変更するための、認可された、より合理的な方法はありますか?特に驚くべきツリーの競合状態の背後にある根本原因は何ですか?

67
Lloeki

svn mvは私のために働く:

C:\svn\co>svn mv my_dir new_dir
A         new_dir
D         my_dir\New Text Document.txt
D         my_dir


C:\svn\co>svn commit -m foo
Raderar             my_dir
Lägger till         new_dir

Arkiverade revision 2.

C:\svn\co>

スウェーデン語のsvnの出力でごめんなさい。

あなたの場合は間違っている何か他のものがあるはずです。

編集:
Lloekiのコメントで指摘されているように

動作を再現するには、フォルダーに含まれるファイルを更新してコミットする必要がありますが、フォルダー自体は更新しません。

ファイルコミットはリポジトリに新しいrev nを作成しますが、ローカルメタデータは更新されないため(常にそうであるように、コミット後にsvnログを参照してください)、dirメタデータはrev n-1にあります。メタデータの差分のためにsvnはコミットせず、実際にはdirに競合があるため更新しません:メタデータの更新と削除。

動作は「予期される」ものであり、「解決策」は、svn renameコマンドを発行する前に作業コピーを更新することです。

68
Albin Sunnanbo

OK、私はこれにぶつかりました-そして、最終的に簡単なターミナルセッションで問題を再構築できます:ファイルをsvn mv(移動/名前変更)すると問題が発生します。その後、その変更をコミットします。次に(withoutsvn updateを最初に実行)、svn mv移動/名前変更が以前にコミットされたファイルの親ディレクトリ-そして最後に、ディレクトリ名の変更に対してsvn commitを実行します-または 受け入れられた答え のように:(ファイルの更新とコミットも必要ですフォルダーに含まれていますが、フォルダー自体は更新されません ";ただし、これらはすべて親(または祖先)ディレクトリで実行されます。問題を示すコマンドラインログを次に示します。

$ cd /tmp
$ svnadmin create myrepo
$ svn co file:///tmp/myrepo myrepo-wc
Checked out revision 0.

$ cd myrepo-wc/
$ mkdir -p dir1/dir2/dir3
$ svn add dir1/
A         dir1
A         dir1/dir2
A         dir1/dir2/dir3

$ svn ci -m 'add dir1/'
Adding         dir1
Adding         dir1/dir2
Adding         dir1/dir2/dir3

Committed revision 1.

$ echo test1 >> dir1/dir2/dir3/test1.txt
$ echo test2 >> dir1/dir2/dir3/test2.txt
$ svn add dir1/
svn: warning: 'dir1' is already under version control
$ svn add dir1/*
svn: warning: 'dir1/dir2' is already under version control
$ svn add dir1/dir2/dir3/*
A         dir1/dir2/dir3/test1.txt
A         dir1/dir2/dir3/test2.txt
$ svn status
A       dir1/dir2/dir3/test2.txt
A       dir1/dir2/dir3/test1.txt
$ svn ci -m 'add dir1/dir2/dir3/*'
Adding         dir1/dir2/dir3/test1.txt
Adding         dir1/dir2/dir3/test2.txt
Transmitting file data ..
Committed revision 2.

$ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
A         dir1/dir2/dir3/test2X.txt
D         dir1/dir2/dir3/test2.txt
$ svn status
D       dir1/dir2/dir3/test2.txt
A  +    dir1/dir2/dir3/test2X.txt
$ svn ci -m 'mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt'
Deleting       dir1/dir2/dir3/test2.txt
Adding         dir1/dir2/dir3/test2X.txt

Committed revision 3.

$ svn status
$ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
A         dir1/dir2/dir3X
D         dir1/dir2/dir3/test2X.txt
D         dir1/dir2/dir3/test1.txt
D         dir1/dir2/dir3
$ svn status
D       dir1/dir2/dir3
D       dir1/dir2/dir3/test2X.txt
D       dir1/dir2/dir3/test1.txt
A  +    dir1/dir2/dir3X
D  +    dir1/dir2/dir3X/test2.txt
$ svn ci -m 'mv dir1/dir2/dir3 dir1/dir2/dir3X'
Deleting       dir1/dir2/dir3
svn: Commit failed (details follow):
svn: Directory '/dir1/dir2/dir3' is out of date
$ svn status
D       dir1/dir2/dir3
D       dir1/dir2/dir3/test2X.txt
D       dir1/dir2/dir3/test1.txt
A  +    dir1/dir2/dir3X
D  +    dir1/dir2/dir3X/test2.txt
$ svn up
   C dir1/dir2/dir3
At revision 3.
Summary of conflicts:
  Tree conflicts: 1

これは、ファイルの移動/名前変更がコミットされた後にsvn upを実行する方法です。 svn status -vコマンドの後にsvn updateによって報告されるバージョン番号がどのように変化するかに注意してください。

$ cd /tmp
$ rm -rf myrepo*

$ svnadmin create myrepo
$ svn co file:///tmp/myrepo myrepo-wc
Checked out revision 0.

$ cd myrepo-wc/
$ mkdir -p dir1/dir2/dir3
$ svn add dir1/
A         dir1
A         dir1/dir2
A         dir1/dir2/dir3
$ svn ci -m 'add dir1/'
Adding         dir1
Adding         dir1/dir2
Adding         dir1/dir2/dir3

Committed revision 1.

$ echo test1 >> dir1/dir2/dir3/test1.txt
$ echo test2 >> dir1/dir2/dir3/test2.txt
$ svn add dir1/dir2/dir3/*
A         dir1/dir2/dir3/test1.txt
A         dir1/dir2/dir3/test2.txt
$ svn status
A       dir1/dir2/dir3/test2.txt
A       dir1/dir2/dir3/test1.txt
$ svn ci -m 'add dir1/dir2/dir3/*'
Adding         dir1/dir2/dir3/test1.txt
Adding         dir1/dir2/dir3/test2.txt
Transmitting file data ..
Committed revision 2.

$ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
A         dir1/dir2/dir3/test2X.txt
D         dir1/dir2/dir3/test2.txt
$ svn status
D       dir1/dir2/dir3/test2.txt
A  +    dir1/dir2/dir3/test2X.txt
$ svn ci -m 'mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt'
Deleting       dir1/dir2/dir3/test2.txt
Adding         dir1/dir2/dir3/test2X.txt

Committed revision 3.

$ svn status
$ svn status -v
                 0        0  ?           .
                 1        1 username dir1
                 1        1 username dir1/dir2
                 1        1 username dir1/dir2/dir3
                 3        3 username dir1/dir2/dir3/test2X.txt
                 2        2 username dir1/dir2/dir3/test1.txt
$ svn up
At revision 3.
$ svn status -v
                 3        3 username .
                 3        3 username dir1
                 3        3 username dir1/dir2
                 3        3 username dir1/dir2/dir3
                 3        3 username dir1/dir2/dir3/test2X.txt
                 3        2 username dir1/dir2/dir3/test1.txt
$ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
A         dir1/dir2/dir3X
D         dir1/dir2/dir3/test2X.txt
D         dir1/dir2/dir3/test1.txt
D         dir1/dir2/dir3
$ svn status
D       dir1/dir2/dir3
D       dir1/dir2/dir3/test2X.txt
D       dir1/dir2/dir3/test1.txt
A  +    dir1/dir2/dir3X
$ svn ci -m 'mv dir1/dir2/dir3 dir1/dir2/dir3X'
Deleting       dir1/dir2/dir3
Adding         dir1/dir2/dir3X

Committed revision 4.

$ svn status
$ svn status -v
                 3        3 username .
                 3        3 username dir1
                 3        3 username dir1/dir2
                 4        4 username dir1/dir2/dir3X
                 4        4 username dir1/dir2/dir3X/test2X.txt
                 4        4 username dir1/dir2/dir3X/test1.txt
$ svn up
At revision 4.
$ svn status -v
                 4        4 username .
                 4        4 username dir1
                 4        4 username dir1/dir2
                 4        4 username dir1/dir2/dir3X
                 4        4 username dir1/dir2/dir3X/test2X.txt
                 4        4 username dir1/dir2/dir3X/test1.txt

そしてOPが言ったように-新しい移動/名前変更+コミットの前にsvn updateを実行することを忘れて、「コミットに失敗しました」が発生したら-svn resolve --accept working -R .を使用してコミットアクションを完了できます。

8
sdaau

これは私のために働いた:

vi someotherfile
...various changes to the other file
svn mv olddir newdir
svn commit -m"Moved olddir out of the way" olddir
svn commit -m"New location of olddir" newdir
svn update
svn commit -m"Changed someotherfile" someotherfile

他にもさまざまな方法が考えられ、svn mvを実行する前に作業ディレクトリがクリーンであることを確認することで、このトリックも実行できたと思います。

1
xgretsch

他のユーザーによってリポジトリ内のディレクトリが変更されたシナリオを考えることができます。作業コピーの同じフォルダーの名前を変更すると、コミット中にツリーの競合が発生する場合があります。

競合の解決 は、Subversionで「ツリーの競合」を解決する方法を示しています。

0
zellus