2009-01-19 25 views
9

Đây là vấn đề của tôi:hồi tố svn nhập khẩu vào git

  1. tôi đã sử dụng Subversion một thời gian, cho đến khi tôi chuyển sang Git. Một thời gian nữa đã trôi qua.
  2. Không có nhập lịch sử từ Subversion vào Git. Đó là một thanh toán nghiêm ngặt, xóa của .svn dirs, sau đó git init. Không phải là một động thái thông minh.
  3. Bây giờ, hàng nghìn git cam kết sau đó, tôi tìm thấy bản sao lưu của repo Subversion được thực hiện tại thời điểm cam kết git đầu tiên xảy ra. Aha!

Tôi muốn quay trở lại repo git thành ngày 0, nhập đúng svn repo, sau đó áp dụng lại tất cả thay đổi git, do đó sửa những gì không được thực hiện lần đầu tiên.

Có ai đã thử điều này không? Tôi sẽ đi đâu để tới đó? Nó giống như mẹ của tất cả các rebases.

Trả lời

14

Âm thanh như một công việc cho ghép git. Tài liệu hướng dẫn này hơi sơ sài, nhưng về cơ bản những gì bạn muốn làm là:

  1. Nhận bản sao git-svn của svn trong kho lưu trữ của bạn. Cách dễ nhất để làm điều này là để git svn nhân bản vào, sau đó lấy bản sao svn trong kho lưu trữ hiện tại của bạn
  2. Tìm ra cam kết cơ sở nào sẽ tuân theo cam kết svn. Vì vậy, bạn có thể có một gốc git một nơi nào đó ("Phiên bản SVN cuối cùng") mà nên làm theo phiên bản SVN thực tế cuối cùng. Đây là người đứng đầu bản sao git-svn bạn vừa tìm nạp
  3. Tạo một tệp .git/info/grafts và đặt hai sha trên một dòng duy nhất tại đó. Đầu tiên là commit đầu tiên, sau đó là một dấu cách, sau đó là commit svn cuối cùng. Điều này nói với git rằng git commit không phải là không có cha mẹ, nhưng trên thực tế svn cam kết cuối cùng là cha mẹ.
  4. Bây giờ bạn có thể kiểm tra với gitk/gitx/bất cứ điều gì mà hai kho được kết nối
  5. Để thực hiện thay đổi vĩnh viễn, hãy chạy git filter-branch. Có thể bạn sẽ muốn đọc manpage của nó trước.

Bạn cũng có thể thực hiện bước 3 cho tất cả các nhánh của mình. Vấn đề với cách tiếp cận của jpalecek là việc rebase sẽ làm phẳng lịch sử của bạn, vì vậy nếu bạn có bất kỳ sự hợp nhất nào, việc rebase sẽ mất chúng. Cách tiếp cận nhánh lọc giữ nguyên lịch sử của bạn.

+1

Đây chính xác là những gì tôi đã làm cho memcached: http://groups.google.com/group/memcached/browse_thread/thread/a7b153bc087244b1/4023dbe7168ea5fa – Dustin

+0

Viết đẹp, Pieter. Bạn đã thực hiện ghép git đơn giản. +1 – Paul

+0

Cảm ơn Pieter, +1 từ tôi. Quá trình tương tự với một vài hình ảnh cũng có thể được tìm thấy tại http://blog.experimentalworks.net/2009/07/git-voodoo/ –

1

Tôi chưa bao giờ thử những gì bạn muốn, nhưng tôi đang làm điều gì đó tương tự với CVS.

Về cơ bản, tôi muốn đề nghị:

  1. Tạo một kho git mới với lịch sử từ svn
  2. Trong kho lưu trữ mới này, git fetch tất cả mọi thứ từ các kho git (sẽ không có cam kết chung)
  3. Sau đó, git branch remote/branch branch-lastgit rebase --onto svn-last remote/branch-first branch-last, nơi remote/branch-first là lần đầu tiên cam kết của kho git nhập khẩu của bạn, vv

Nếu bạn có nhiều chi nhánh, mọi thứ phức tạp hơn. Tôi nghĩ rằng lặp lại bước 3 có thể làm, nhưng bạn tốt hơn nên thử bản thân. Nếu bạn đã hợp nhất trong lịch sử git của mình, bạn có thể cần git rebase -i -p .... Hãy nhớ rằng, lợi thế của git là bạn về cơ bản không thể vít lên bất cứ điều gì (đặc biệt là nếu bạn đang làm việc trong một kho lưu trữ riêng biệt).