2010-10-15 60 views
56

Trong khi bằng cách nào đó thông thạo trong VCS (thường xuyên svn, git và git-svn người dùng) Tôi dường như không thể quấn đầu của tôi xung quanh hành vi SVN đặc biệt này.Một cách sane để đổi tên một thư mục trong bản sao làm việc lật đổ

Bất cứ khi nào tôi cần phải đổi tên một thư mục trong bản sao làm việc SVN của tôi từ một trường hợp 'sạch' nhà nước - tức là svn status lợi nhuận gì và tất cả các sửa đổi khác đã được cam kết - như vậy (đó là những gì các svn doc gợi ý):

svn mv foo bar 
svn commit 

SVN phàn nàn ầm ĩ:

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

Như bạn muốn:

svn update 

Mà cho:

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

Có một cuộc xung đột cây, trong khi không có sự thay đổi của bên thứ ba đã xảy ra. Rõ ràng, cách duy nhất để thoát ra khỏi mớ hỗn độn xung đột cây này là tổng quát (từ cuốn sách đỏ svn):

svn resolve --accept working -R . 
svn commit 

Đổi tên nó từ xa trên các repo sau đó cập nhật bản sao làm việc của tôi dường như khá braindead:

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

Có cách nào bị xử phạt, sắp xếp hợp lý hơn để đổi tên một thư mục mà tôi bị thiếu không? Nguyên nhân gốc rễ đằng sau tình trạng xung đột cây đặc biệt đáng ngạc nhiên là gì?

+0

Bạn có thể đăng thông điệp xung đột cây chính xác không? –

+0

Tôi đã thấy hành vi này trước đây, nhưng tôi không chắc chắn nguyên nhân gây ra nó. Là nó khi bạn thêm một dir và đổi tên nó trước khi cam kết có lẽ? –

+0

Tôi cũng trải nghiệm hành vi này và không thể tìm ra lý do. Tôi đã luôn viết nó lên "cách SVN hoạt động". Nó làm tôi điên. –

Trả lời

56

svn mv công trình cho tôi:

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> 

Xin lỗi vì đầu ra của Thụy Điển svn.

Phải có điều gì đó sai trong trường hợp của bạn.

Edit:
Như đã chỉ ra trong các ý kiến ​​của Lloeki

Để tái tạo các hành vi của bạn cũng cần phải cập nhật và cam kết một tập tin chứa trong thư mục, nhưng không cập nhật thư mục riêng của mình.

tập tin cam kết tạo ra một n rev mới trên repo, nhưng siêu dữ liệu địa phương không là cập nhật (như nó đã luôn luôn, xem svn log sau khi bất kỳ cam kết), do đó dir siêu dữ liệu là rev n 1. Nó theo sau rằng svn sẽ không cam kết vì khác biệt siêu dữ liệu và nó sẽ không cập nhật vì thực sự có xung đột trên dir: cập nhật siêu dữ liệu và xóa.

Hành vi này là "được mong đợi" và "giải pháp" là cập nhật bản sao làm việc trước khi cấp lệnh svn rename.

+2

Tìm rằng 'cái gì khác' thực sự là một phần của câu hỏi :) Bây giờ sửa đổi New Text Document.txt, cam kết nó, sau đó mv dir và cam kết một lần nữa. – Lloeki

+1

@Lloeki, có bằng cách sửa đổi tệp văn bản tái tạo xung đột cây. Nó thực sự trông giống như một lỗi đối với tôi, bạn đã tìm kiếm trình theo dõi vấn đề tại http://subversion.apache.org/ và/hoặc đã gửi báo cáo lỗi ở đó chưa? –

+2

Cuối cùng tôi đã tìm ra lý do, có ý nghĩa theo cách bị lật ngược: tệp cam kết tạo ra một rev * n * mới trên repo, nhưng siêu dữ liệu cục bộ không được cập nhật (vì nó luôn luôn là, xem 'svn log' sau bất kỳ commit nào) , do đó, siêu dữ liệu dir là rev * n-1 *. Nó sau đó svn sẽ không cam kết vì sự khác biệt siêu dữ liệu, và nó sẽ không cập nhật bởi vì có thực sự là một cuộc xung đột trên dir: cập nhật siêu dữ liệu vs xóa. – Lloeki

0

Người ta có thể nghĩ về một tình huống mà thư mục đã được thay đổi trong kho lưu trữ bởi một người dùng khác. Đổi tên cùng một thư mục trong bản sao làm việc của bạn có thể kích hoạt xung đột cây trong quá trình cam kết.

Resolving conflicts cho biết cách giải quyết 'xung đột cây' trong lật đổ.

+0

Tôi đang ở trong một kịch bản phát triển đơn lẻ mà không có thay đổi bên ngoài xảy ra. – Lloeki

1

này đã làm việc cho tôi:

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 

tôi nghi ngờ rằng có nhiều cách có thể ngược lại, và điều đó đảm bảo có được một thư mục làm việc sạch sẽ trước khi thực hiện mv svn sẽ cũng đã làm các trick.

7

OK, tôi đã gặp phải vấn đề này - và cuối cùng có thể xây dựng lại vấn đề với phiên đầu cuối đơn giản: sự cố xảy ra nếu bạn svn mv (di chuyển/đổi tên) tệp; sau đó cam kết thay đổi đó; sau đó (mà không cần trước tiên thực hiện svn update), svn mv thư mục mẹ của tệp đã di chuyển/đổi tên trước đó - và cuối cùng là svn commit về thay đổi tên thư mục - hoặc accepted answer đặt: "" để cập nhật và cam kết tệp chứa trong thư mục nhưng không tự cập nhật thư mục "; nhưng tất cả điều này được thực thi trong thư mục cha (hoặc đúng hơn là tổ tiên). Dưới đây là lệnh dòng nhật ký chứng minh vấn đề:

$ 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 

Và đây là cách nó cần phải có được - làm một svn up sau khi di chuyển tập tin/đổi tên đã được cam kết; lưu ý làm sao các số phiên bản báo cáo của svn status -v thay đổi sau khi lệnh 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 

Và như OP nói - ta nên quên để làm svn update trước một động thái mới/đổi tên + cam kết, và "cam kết không" xảy ra - sau đó người ta có thể sử dụng svn resolve --accept working -R . để có thể hoàn thành hành động cam kết.

Các vấn đề liên quan