2013-08-02 34 views
7

Tôi có một git repo địa phương mà tôi tạo ra từ một repo svn:Làm thế nào để sao chép một repo git với tất cả các chi nhánh và thẻ từ refs/điều khiển từ xa?

$ git svn clone -s svn:... 

Sau đó tôi tạo một bản sao lưu từ xa và đẩy tất cả mọi thứ với nó:

$ git remote add backup [email protected]:mybackup.git 
$ git push --mirror backup 

Bây giờ, khi tôi cố gắng sao chép từ sao lưu của tôi, nó thiếu tất cả các thẻ và các nhánh svn.

$ git clone [email protected]:mybackup.git 
$ cd mybackup 
$ git branch -a 
* master 
    origin 
    remotes/origin/HEAD -> origin/master 
    remotes/origin/master 

Làm cách nào để sao chép bản ghi nhớ bằng tất cả các thẻ và chi nhánh?

Cách duy nhất tôi đã tìm thấy là phản ánh các repo:

$ git clone --mirror [email protected]:mybackup.git 

này tạo ra một mybackup.git thư mục địa phương, mà biết về tất cả các thẻ/cành (Tôi có thể sử dụng hoàn tab để có được toàn bộ danh sách) nhưng nó không phải là một repo có thể sử dụng hợp lệ:

$ git checkout mytag 
fatal: This operation must be run in a work tree 

Phải có tùy chọn dòng lệnh để thực sự sao chép bản ghi nhớ với tất cả các chi nhánh/thẻ ???

Tôi đã tìm thấy một số câu hỏi liên quan ở đây nhưng không có câu trả lời nào phù hợp với tình huống này. Tôi giả sử sự khác biệt là bản sao của tôi đã được tạo ra với --mirror?

+0

Thông tin thêm: Tôi có thể thấy rằng các nhánh mà nhân bản mới của tôi biết nằm trong thư mục 'refs/heads' của bản sao lưu của tôi trong khi những cái tôi không tìm thấy trong' refs/remotes' (kỳ quặc, 'backup' cũng nằm trong 'refs/remotes' - tác dụng phụ của' --mirror' mà tôi giả định). –

Trả lời

7

Có hai cách để cải thiện lệnh của bạn git clone --mirror [email protected]:mybackup.git Tôi tìm thấy điều này, biết rằng lệnh của bạn đã tạo thư mục mybackup.git:

mkdir mybackup 
mv mybackup.git mybackup/.git 
cd mybackup 
git init 

Ở đó, bạn có một thư mục hoạt động đầy đủ.

Ngoài ra như bạn có thể đọc trên trang này: https://git.wiki.kernel.org/index.php/Git_FAQ#How_do_I_clone_a_repository_with_all_remotely_tracked_branches.3F

git clone --mirror [email protected]:mybackup.git mybackup/.git 
cd mybackup 
git config --bool core.bare false 

Tôi nghĩ cả hai đều tương đương lên đến dòng cuối cùng, và có lẽ là lệnh git config --bool core.bare false là sạch hơn làm một git init.

Tất cả đều tóm tắt thực tế là --mirror tạo kho lưu trữ trống và không phải là kho lưu trữ làm việc, vì vậy bạn cần chuyển đổi nó thành kho lưu trữ đang hoạt động.

+0

Cảm ơn. Nghỉ hưu giải pháp của tôi vì giải pháp này dường như hoạt động và đơn giản hơn. Sau đó bạn chỉ cần móc SVN vào repo mới và thực hiện. –

2

Sau nhiều tìm kiếm, cuối cùng tôi đã tìm thấy một câu trả lời ...

git clone [email protected]:mybackup.git newdirectory 
cd newdirectory 
git fetch origin refs/remotes/*:refs/remotes/* 
git init 

Bây giờ một git branch -a cho thấy tất cả các chi nhánh từ xa của tôi.

Tôi không chắc chắn nếu git init là cần thiết ở đây hoặc nếu nó chỉ là cần thiết trong biến thể git init --bare (xem dòng nhận xét trong kịch bản trình bao dưới đây), nhưng tôi chắc chắn rằng nó không có gì để lại nó trong nếu nó không cần thiết.

Lý do chính của tôi khi làm điều này là sao chép thẻ SVN của tôi thay vì chỉ có master trỏ tới SVN trunk và không phải phân tích toàn bộ lịch sử SVN (rất chậm đối với các dự án có nhiều lịch sử, thẻ và các chi nhánh). Vì vậy, để sao chép thông tin SVN của tôi:

git svn init -s "svn://mysvnhost/mysvnrepo/myproject" 
git svn fetch 
git checkout master 

Đẩy nhanh tiến độ quá trình này lên, tôi tạo ra một kịch bản shell:

#!/bin/sh 
# 
# git-clone-svn-based-repo.sh: 
# 
# clones a git-svn based repo including all SVN commits without pounding 
# the SVN server for hours (just a quick refresh taking seconds) 
# 

usage_exit() 
{ 
    echo "Usage: $0 <git-repo> <dest-directory> <svn-project>" 
    exit 1 
} 


if ! git ls-remote "$1" > /dev/null 2>&1 
then 
    echo "No git repo found at: $1" 
    usage_exit 
fi 

if [ -r "$2" ] 
then 
    echo "File or directory already exists: $2" 
    usage_exit 
fi 

if ! svn ls "$3" 2> /dev/null | grep -q trunk 
then 
    echo "No SVN project found at: $3" 
    usage_exit 
fi 

# create new bare git repo 
mkdir "$2" 
cd "$2" 
git init --bare .git 

# fetch everything from backup 
git remote add backup "$1" 
git fetch backup refs/remotes/*:refs/remotes/* 
git fetch backup refs/heads/*:refs/heads/* 
git fetch backup refs/tags/*:refs/tags/* 

# disable future fetching from backup 
# setup to push all remote refs to backup by default 
git config remote.backup.fetch do_not_fetch_from_backup 
git config remote.backup.push '+refs/remotes/*:refs/remotes/*' 

# initialize git repo to usable (non-bare) state 
git init 

# update SVN references 
git svn init -s "svn://svn.crc-corp.com/carsrepository/$3" 
git config svn.authorsfile $HOME/projects/authors.txt 
git svn fetch 

# update master to current SVN trunk 
git checkout master 
git svn rebase 
# update ignore properties from SVN 
git svn show-ignore >> .git/info/exclude 

Để tạo một bản sao lưu như vậy từ một repo git SVN hiện:

# create a bare backup repo at [email protected]:mybackup.git 
git remote add backup [email protected]:mybackup.git 
git config remote.backup.fetch do_not_fetch_from_backup 
git config remote.backup.push '+refs/remotes/*:refs/remotes/*' 
git push backup 
Các vấn đề liên quan