2012-10-17 37 views
14

Tôi đang cố gắng sử dụng svn2git để di chuyển dự án SVN sang git. Tuy nhiên tôi có vấn đề bảo tồn tất cả lịch sử. Lý do có vẻ là vì thân cây đã được di chuyển trong quá khứ. Lệnh tôi đang sử dụng là:Làm thế nào để giữ lịch sử SVN trong Git khi thân cây đã di chuyển?

$ svn2git http://mysvnserver.com/myproject/iPhone/ --no-minimize-url --authors ../authors.txt 

Nhưng điều này chỉ mang lại cho tôi lịch sử sẽ trở lại năm 2011. Các dự án thực sự bắt đầu vào năm 2010. Dự kiến ​​bắt đầu bằng cách nhìn như thế này:

myproject 
    trunk 
    branches 
    tags 

Nhưng trong năm 2011 nó đã được thay đổi thành:

myproject 
    iPhone 
    trunk 
    branches 
    tags 
    Android 
     trunk 
     branches 
     tags 

Thân cây và chi nhánh cũ đã nằm trong thư mục iPhone. Lịch sử tôi bắt đầu từ khi động thái này được thực hiện. Nếu tôi làm svn log trong thư mục iPhone, tôi sẽ nhận được lịch sử rút gọn. Nhưng nếu tôi cd trunk; svn log thì tôi sẽ có được toàn bộ lịch sử.

Tôi không biết làm thế nào để có được lịch sử này. Ý tưởng của tôi là bằng cách nào đó tạo ra một kho lưu trữ git chỉ với lịch sử của thân cây đi tất cả các con đường trở lại năm 2010. Sau đó, tôi sau đó sẽ kéo này như là một chi nhánh trong repo chính của tôi, và làm một rebase để có được lịch sử chính xác. Nhưng tôi đã không có may mắn tạo repo này chỉ cho thân cây. Tôi đã thử:

$ svn2git http://mysvnserver.com/myproject/ --rootistrunk --authors ../authors.txt 

$ svn2git http://mysvnserver.com/myproject/ --rootistrunk -no-minimize-url --authors ../authors.txt 

mà không cần bất kỳ sự thành công.

Trả lời

10

Tôi chỉ gặp vấn đề tương tự. Đây là cách tôi giải quyết nó.

Sao chép cả hai repos riêng biệt.

git svn clone -s [original-svn-location] [original-clone-directory] 
git svn clone -s [new-svn-location] [new-clone-directory] 

Thêm dữ liệu nhân bản cũ vào repo mới.

cd [new-clone-directory] 
git remote add oldstuff ../[original-clone-directory] 
git fetch oldstuff 

Bây giờ là phần khó khăn ... Do git log của masteroldstuff/master (hoặc có thể trunkolstuff/trunk - tuy nhiên bạn thiết lập nó) và viết ra những sha đầu tiên cam kết từ các bản sao mới và cuối cùng cam kết sha từ bản sao cũ (ngay trước khi di chuyển).

git replace [first-commit-sha-from-new-clone] [last-commit-sha-from-old-clone] 

Và để viết lại SHA băm để mọi thứ đều hoàn hảo và bạn không còn cần thay thế ref ...

git filter-branch 

Và bây giờ để làm sạch các tài liệu tham khảo cần thiết không còn.

git remote rm oldstuff 
rm -rf .git/refs/replace 

Bạn sẽ mất phần đầu tiên cam kết từ lịch sử của bạn, nhưng kể từ đó phải là động thái ban đầu (ví dụ: không có nội dung tập tin thực tế đã thay đổi) thì có lẽ nó sẽ không quan trọng với bạn.

Bây giờ tất cả lịch sử sẽ vẫn được duy trì và git blame báo cáo nhớ lịch sử cũ của repo, cung cấp cho bạn thông tin chính xác một lần nữa.

Bạn sẽ có thể lặp lại điều này thường xuyên nếu cần (tùy thuộc vào số lần dự án của bạn thay đổi vị trí gốc và/hoặc có bao nhiêu nhánh đã cam kết trên cả hai mặt di chuyển).

PS - giải pháp này tôi thích ứng với nhu cầu của mình từ một trong những tôi tìm thấy here (Tôi không thể có được cách tiếp cận ghép của mình để làm việc cho kho của tôi - nhưng sử dụng thay thế dường như làm việc đẹp).

+0

Tôi không thể nhớ vấn đề này nữa, nhưng tôi đã đặt câu trả lời này là vì câu trả lời dường như gần nhất với cách tôi thực sự đã giải quyết được vấn đề. Tôi tin rằng tôi đã thực hiện một loạt các nhánh riêng biệt và sau đó khâu chúng lại với nhau bằng cách nhìn vào lịch sử như bạn mô tả. –

2

Bạn có thể sử dụng SubGit để chuyển đổi kho lưu trữ SVN của mình.

Rất tiếc, phiên bản 1.0 không hỗ trợ bố cục phức tạp như bố cục mà bạn có. Nhưng có 1.1 EAP version xử lý tốt. Cả hai phiên bản 1.0 và 1.1 đều làm việc với kho SVN cục bộ, vì vậy bạn phải có quyền truy cập quản trị vào kho SVN.

hãy làm như sau để chuyển đổi kho SVN để Git:

  1. Tạo cấu hình ban đầu.

    $ subgit configure SVN_REPO 
    
  2. Có thể, SubGit sẽ phát hiện hai dự án bên trong kho lưu trữ này. AFAIU, bạn chỉ cần một kho lưu trữ Git. Vì vậy, bạn phải giữ chỉ một phần 'git' trong tệp cấu hình. Chỉ định tất cả các nhánh bạn cần chuyển đổi ở đó.

    $ EDITOR SVN_REPO/conf/subgit.conf 
    [core] 
        ... 
    [git "default"] 
        repository = .git 
        ... 
        trunk = trunk:refs/heads/master 
        branches = branches/*:refs/heads/* 
        tags = tags/*:refs/tags/* 
        shelves = shelves/*:refs/shelves/* 
        branches = iPhone/trunk:refs/heads/iPhone/master 
        branches = iPhone/branches/*:refs/heads/iPhone/* 
        tags = iPhone/tags/*:refs/tags/iPhone/* 
        branches = Android/trunk:refs/heads/Android/master 
        branches = Android/branches/*:refs/heads/Android/* 
        tags = Android/tags/*:refs/tags/Android/* 
        ... 
    [daemon] 
        ... 
    
  3. Chuyển đổi SVN thành Git.

    $ subgit install SVN_REPO 
    
  4. Tại thời điểm này SubGit chuyển đổi tất cả các bản sửa đổi từ SVN sang Git. Bạn có thể tìm kho lưu trữ Git đã được chuyển đổi tại SVN_REPO/.git. Ngoài ra SubGit giữ SVN và Git kho được đồng bộ, nó cài đặt móc đặc biệt để đạt được điều đó. Nếu cần loại bỏ các móc này.

    $ subgit uninstall --purge SVN_REPO 
    

Đó là tất cả. Bây giờ bạn đã chuyển đổi kho Git với toàn bộ lịch sử được lưu giữ.

Lưu ý rằng SubGit là một sản phẩm thương mại, nhưng loại chuyển đổi một lần này là miễn phí. Hy vọng, nó hoạt động tốt cho bạn.

+0

Điều này trông giống như một giải pháp tốt, nhưng vì nó là một thời gian dài tôi đã làm điều này tôi không thể xác minh các giải pháp và đặt nó như là câu trả lời. Nhưng nếu ai đó có thể xác minh rằng điều này hoạt động, tôi rất vui khi làm cho câu trả lời này đúng. –

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