2012-07-06 15 views
19

Tôi đã sử dụng lệnh sau để sao chép svn repo vào git và sau khi thực hiện nó, tôi thấy một số nhánh giả.bản sao git-svn | chi nhánh giả

git svn clone [SVN repo URL] --no-metadata -A authors-transform.txt --stdlayout ~/temp

git branch -a

*(no branch) 
    master 
    remotes/abc-1.3.x 
    remotes/[email protected] 
    remotes/[email protected] 
    remotes/branch_test_script 
    remotes/tags/modules-1.2 
    remotes/tags/[email protected] 
    remotes/tags/[email protected] 
    remotes/tags/release-1.1 
    remotes/tags/[email protected] 
    remotes/tags/[email protected] 
    remotes/trunk 

chi nhánh thực tế tạo ra trong svn là abc, branch_test_script, module và phát hành. Ai đó có thể giúp hiểu được '[email protected]', '[email protected]' ... '[email protected]' vv nào không?

Làm cách nào để loại bỏ các nhánh giả mạo này/chúng có ý nghĩa gì?

Cảm ơn,
Gayathri

+0

Tôi có một thời gian thực sự khó khăn khi tìm kiếm tên này, nhưng có vẻ như các nhánh này được tạo từ các cam kết SVN đã được tìm thấy không được tham chiếu nữa bởi nhánh (hoặc thẻ) svn mà chúng được tạo ban đầu. Giống như các cam kết không được tham chiếu trong Git, ngoại trừ việc có thể khôi phục tên chi nhánh cho cam kết. – fork0

+0

@ fork0: Cảm ơn bạn đã trả lời. Nhưng tôi không hiểu rõ ràng như thế nào cam kết không được tham chiếu có thể có mặt trong svn. Các tham chiếu có thể bị mất như thế nào? Bạn có thể chia sẻ suy nghĩ của bạn về điều này? – crankparty

+0

Tôi không biết. Có lẽ người duy trì kho SVN không bao giờ làm sạch chúng (hoặc SVN không có khả năng nào cả?). Tôi không có ý nói rằng các tài liệu tham khảo đã bị mất, thay vào đó ai đó mới bắt đầu cam kết từ một điểm trước đó trong lịch sử – fork0

Trả lời

15

tl; dr:

git svn tạo ra những "@" - chi nhánh nếu chi nhánh (hoặc thẻ) được tạo ra cho một thư mục con (hoặc cho một thư mục mà không được theo dõi bởi git-svn). Sẽ luôn có một nhánh "thông thường" có cùng tên, nhưng không có hậu tố "@". "@" - chi nhánh chỉ tồn tại như một điểm phân nhánh cho nhánh thông thường.


Lưu ý: Tôi đã gửi bản vá cho việc này; phiên bản chỉnh sửa của lời giải thích này hiện là một phần của trang chính thức git svn, như một phần mới "XỬ LÝ CÁC CHI NHÁNH SVN" (kể từ Git 1.8.1).


Trong Subversion, ngành và các thẻ chỉ là bản sao của một cây thư mục, vì vậy nó có thể (mặc dù thường nản chí) để tạo ra một chi nhánh từ một thư mục mà bản thân nó không một chi nhánh (hoặc thân) là. Ví dụ, bằng cách sao chép/trunk/foo vào/branch/bar, thay vì sao chép/trunk (một "thư mục con", để nói), hoặc bằng cách sao chép một thư mục nằm bên ngoài cấu trúc trunk/tags/branch (đó là có thể trong SVN).

Trong git, tuy nhiên, nhánh luôn dành cho toàn bộ repo, các thư mục con không tồn tại. git svn do đó sử dụng giải pháp thay thế. Nếu nó phát hiện một chi nhánh đã được sao chép từ một thư mục không phải là chính nó được theo dõi như là một chi nhánh của git-svn, nó sẽ tạo ra một lịch sử mới. Ví dụ, đối với một chi nhánh thư mục con ở đâu/trunk/foo được sao chép vào/chi nhánh/bar trong r1234, nó sẽ tạo ra:

  • Một git mới cam kết cho mỗi phiên bản SVN từ r1233 trên ngược (lưu ý số lượng là bản sửa đổi cuối cùng trước khi chi nhánh được tạo). Các cây của các cam kết này sẽ chỉ chứa thư mục con được phân nhánh. Vì vậy, đối với mỗi sửa đổi từ r1233 trở đi, thường sẽ có hai cam kết git, một với toàn bộ cây (được tạo ra khi git-svn xử lý lịch sử của trunk), và những cái mới.
  • Chi nhánh giả gọi là "bar @ 1233" (tên chi nhánh @ bản sửa đổi), có sẵn cho cam kết được tạo từ r1233 ở trên.
  • Cam kết từ r1234, cam kết đã tạo chi nhánh. Cam kết này sẽ có nhánh trên là tổ tiên (chỉ) của nó.
  • Chi nhánh được gọi là "thanh", trỏ đến cam kết thứ hai.

Bằng cách đó, cho thanh chi nhánh thư mục con, bạn sẽ có hai chi nhánh tại git

  • thanh @ 1233, đại diện cho nhà nước của các kho lưu trữ mà chi nhánh đã được tạo ra từ
  • thanh, đại diện cho chi nhánh

Tôi không chắc chắn lý do tại sao nhánh giả này được tạo. Tôi nghĩ rằng nó được thực hiện để đại diện cho thông tin về việc sửa đổi chi nhánh được phân nhánh từ, và để có một lịch sử hoàn chỉnh cho chi nhánh.


Lưu ý rằng toàn bộ cơ chế này có thể được tắt bằng cách sử dụng cờ --no-follow-parent. Trong trường hợp đó, mỗi nhánh SVN sẽ dẫn đến một nhánh git chỉ với các commit từ thư mục nhánh SVN. Mỗi nhánh sẽ không được kết nối với phần còn lại của lịch sử, và sẽ có cam kết gốc riêng của nó, tương ứng với cam kết đầu tiên trong nhánh.

3

tôi đã như vậy kỳ lạ gọi là cành quá khi tôi nhân bản repo SVN của tôi vào một repo Git.

Sau khi xem xét các ngành dự kiến ​​(trong trường hợp của bạn modules-1.2, abc-1.3.x, branch_test_scriptrelease-1.1) Tôi nhận thấy rằng @revisionnumber chi nhánh là không có gì khác hơn so với cam kết trong chi nhánh tiền tố của họ.

Nếu bạn muốn thực hiện thủ công, hãy mở gitk trên chi nhánh abc-1.3.x và xác minh rằng [email protected][email protected] hiển thị trong lịch sử của chi nhánh đó. Nếu có, bạn có thể xóa nhánh tương ứng.

Điều này có thể hơi cồng kềnh nếu bạn có nhiều nhánh hoặc nhiều cam kết duyệt qua.

cách tự động: hỏi git để làm điều đó cho bạn:

git branch -r --contains [email protected] 

sẽ echo (hoặc ít nhất nên)

abc-1.3.x 
[email protected] 
[email protected] 

Điều này có nghĩa rằng bạn có thể xóa một cách an toàn [email protected] bởi vì nó chứa trong abc-1.3.x:

git branch -r -d [email protected] 

Do lịch sử tuyến tính của SVN, tất nhiên nó cũng chứa nó là cam kết (mới hơn) 541512.


Side lưu ý:
Bạn có thể thấy rằng các thẻ SVN của bạn không thực sự chuyển đổi sang thẻ Git, ngành Git bản địa. Điều này có thể đạt được bằng cách sử dụng svn2git để sao chép SVN repo vào một repo Git.

+0

Làm thế nào để loại bỏ các chi nhánh này? Có bất kỳ tham số nào có thể được chuyển tới git để bỏ qua các cam kết đó và không tạo ra các nhánh không? – crankparty

+0

Như tôi đã viết: các nhánh có thể bị xóa bằng cách sử dụng 'git branch -r -d '. Tôi không nghĩ rằng có một lá cờ để đạt được rằng các chi nhánh không được tạo ra. – eckes

+1

'git-svn' có thể có thể tạo các nhánh" @ "này một cách không cần thiết, nhưng có một trường hợp quan trọng trong đó' abc @ 113346' là ** không ** tổ tiên của 'abc'. Điều đó xảy ra nếu chi nhánh bị xóa trong phiên bản phụ và được tạo lại bằng cách sao chép từ một điểm khác. Ngoài ra thực tế là 'abc @ 113346' là tổ tiên của' abc' không có nghĩa là điều này không xảy ra, nó có thể có nghĩa là 'abc' đã được hợp nhất thành thân cây, bị xóa (trong một số sửa đổi cao hơn 113346) và một cái được tạo ra ở vị trí của nó từ thân cây. –