2009-10-13 3 views
11

Tình huống là tôi đã dành một chút thời gian để giải quyết một số mã thử nghiệm. Bây giờ tôi muốn di chuyển một phần của đoạn mã đó - khoảng 500 dòng - vào một tệp khác, nhưng tôi không muốn mất lịch sử, như tôi sẽ làm nếu tôi cắt và dán một trình soạn thảo văn bản đơn giản.Sử dụng Subversion, làm cách nào tôi có thể cắt từ một tệp và dán vào một lịch sử bảo tồn khác

Gần như tôi biết cách nhận được là tách mã ra khỏi tệp gốc - svn copy, sau đó xóa nội dung không mong muốn khỏi cả hai bản sao. Nhưng tôi không biết làm thế nào để sau đó nối thêm một phần sao chép vào một tập tin hiện có, giữ lịch sử từ cả hai.

Lý do điều này quan trọng về cơ bản là mã chỉ là những thứ khá chuyên biệt, để giúp thực hiện một số chức năng cấp cao hơn. Tôi không muốn nó gây ô nhiễm không gian tên toàn cầu, vì vậy tôi muốn tất cả trong một tập tin mà nó sẽ được sử dụng và bọc trong một không gian tên vô danh.

Tôi nhận ra điều này nghe có vẻ giống như sáp nhập một chi nhánh trở lại vào thân cây. Vấn đề là, không có chi nhánh. Mã thử nghiệm không bắt đầu như một bản sao của bất cứ thứ gì - nó chỉ là một loạt mã bắt đầu-từ-đầu. Tệp tôi muốn cắt và tệp tôi muốn dán vào là các tệp hoàn toàn độc lập.

Tôi chủ yếu sử dụng TortoiseSVN, nhưng cũng đã cài đặt phiên bản lật đổ dòng lệnh.

Trả lời

16

Bạn có thể kết hợp tất cả các phiên bản (hoặc các phiên bản cụ thể) của một tập tin vào một như thế này

svn merge sourcefile targetfile -r 0:HEAD 

Lúc đầu, tôi nghĩ rằng người ta sẽ phải sử dụng tùy chọn --ignore-ancestry (vì cả hai tập tin không chia sẻ bất kỳ thông thường lịch sử) nhưng rõ ràng điều này là không cần thiết. Tôi đã thử nghiệm với svn 1.6.3.

Bạn tất nhiên rất có khả năng nhận được rất nhiều điểm đánh dấu xung đột trong kết quả hợp nhất. Nó có thể dễ dàng hơn để làm việc hợp nhất bằng tay (một bản sao và dán sáp nhập như bạn nói), và sau đó chạy lệnh hợp nhất ở trên với --record-only để nói với subversion về nó.

Sau khi hợp nhất, số targetfile sẽ có thuộc tính svn:mergeinfo cho biết cam kết nào từ số sourcefile trong đó hợp nhất vào đó. Khi bạn kiểm tra nhật ký của targetfile, bạn có thể xem lịch sử của cả hai tệp bằng cách sử dụng tùy chọn --use-merge-history. TortoiseSVN có cùng tính năng dưới dạng một hộp kiểm trong biểu mẫu đăng nhập.

+0

Điều đó khá thông minh. –

+0

Tôi nghi ngờ rằng điều này sẽ không hoàn toàn làm những gì tôi muốn, nhưng tôi tin rằng nó là tốt nhất tôi sẽ nhận được (ngắn của hack hacking dump), vì vậy tôi chấp nhận. Cảm ơn. – Steve314

+0

Bạn sẽ có nhật ký cam kết, nhưng tất cả các dòng trong các thay đổi của bạn sẽ có cùng điểm đánh dấu sửa đổi trong 'đổ lỗi'. –

1

Nếu bạn muốn sao chép trong một file mới và xóa các tập tin cũ:

svn mv 

Nếu bạn muốn nhân bản trong một tập tin mới:

svn copy 

Nếu cả hai tập tin đã tồn tại:

# copy/paste with a text editor 

Bạn có thể xóa tệp để giữ lịch sử với:

svn del 

Với SVN bạn không thể theo dõi lịch sử kết hợp hai tệp. Bạn có thể hợp nhất nó bằng tay và giữ một dấu vết trong thông điệp cam kết.

+0

Không ai trong số những cung cấp cho tôi một tập tin chứa văn bản (và lịch sử) từ hai tập tin nguồn. Sao chép/dán trình soạn thảo văn bản giữ lại lịch sử từ cả hai trong kho lưu trữ, đúng - không có gì bị xóa - nhưng lịch sử từ tệp bạn cắt ra được tách ra khỏi tệp mà bạn đã dán. Trong các điều khoản của TortoiseSVN, Blame sẽ đổ lỗi cho mọi thứ về việc cắt giảm và mở rộng, chứ không phải trên những người đưa ra quyết định mã hóa. – Steve314

+0

Tất cả các công cụ mà Subversion cung cấp cho bạn. Bạn có lẽ nên sử dụng một số DVCS. TortoiseMercurial tồn tại cho người dùng Windows. – Natim

+0

Bằng cách này tôi không hiểu chính xác những gì bạn mong đợi bằng cách hợp nhất lịch sử của hai tập tin. nó không có ý nghĩa. Bạn nghĩ gì về loại rollback nào? Bạn có thể thêm nhận xét ở đầu tệp của mình để nói rằng đó là sự hợp nhất của tệp này và một tệp khác trong bản sửa đổi rXXXX – Natim

4

Tôi không nghĩ rằng bạn có thể giữ lại lịch sử theo cách bạn mô tả. SVN theo dõi lịch sử trên cơ sở từng tệp, và nó sẽ không theo dõi hai tệp riêng biệt được kết hợp với nhau trên cùng một dòng mã.

Nếu bạn bắt đầu với hai tệp riêng biệt và sau đó kết hợp chúng lại với nhau thành một phần ba, thì lịch sử của cả hai sẽ được giữ nguyên. Nếu bạn kết hợp một với nhau, thì lịch sử của một trong số họ sẽ bị "mất" theo nghĩa là bạn sẽ không thể liên kết ngược lại với lịch sử của tệp "đã xóa" chỉ từ việc xem lịch sử.

Tôi đoán những gì bạn có thể làm là trong thông điệp cam kết chỉ cần lưu ý rằng nội dung từ tệp khác đã được kết hợp và sau đó cam kết xóa trong cùng một cam kết.

+0

Tôi có cảm giác đó là câu trả lời. Chưa được chấp nhận vào lúc không có cơ hội - tôi sẽ có một cái nhìn khác vào ngày mai trong trường hợp. – Steve314

-1

Bạn không thể để lại mã trong tập tin riêng của mình (sau khi cắt các phần bạn không muốn giữ) và đưa tệp này vào tệp nguồn 'thực' của bạn?

// file foo.cpp: 
... 
namespace { 
# include "util_code.inc" 
} 

Không thực sự chính thống, nhưng nên làm việc ...

+0

Tôi không thích kiểu #include sử dụng. Đã quen với điều này-là-the-spec, đó là-the-cơ hội ước trong các ngôn ngữ khác một thời gian dài trước đây. Đó có lẽ là lý do tại sao ý tưởng đó thậm chí không xảy ra với tôi - nhưng nó không tệ đến thế, tôi cho rằng, với một loạt các lựa chọn không hoàn hảo. Quá muộn thời gian này - nhưng luôn luôn có một thời gian tiếp theo. – Steve314

+0

Cảm ơn. Tất nhiên tôi sẽ không khuyên bạn nên sử dụng chung các chỉ thị #include như vậy. Nhưng tôi đã sử dụng chúng để bao gồm mã được tạo: #define THE_CLASS MyClass #include method_bodies.inc với method_bodies.inc tìm kiếm như thế này: trống THE_CLASS :: generatedMethod() { ... } Do đó, tôi có thể tạo ra một số, nhưng không phải tất cả, các phương thức của một lớp mà không có máy phát biết tên của lớp. –