2008-12-24 32 views
51

Tôi có một kho lưu trữ có đã được nhân bản từ SVN. Tôi đã làm một số công việc trong kho lưu trữ này dưới dạng Git của nó và tôi ghét phải mất cấu trúc đó bằng cách sao chép lại. Tuy nhiên, khi tôi nhân bản kho lưu trữ ban đầu, tôi đã không chỉ định chính xác thuộc tính svn.authors (hoặc tùy chọn ngữ nghĩa tương tự). Có cách nào tôi có thể xác định ánh xạ tác giả SVN bây giờ mà kho lưu trữ là hoàn toàn Git-ified? Tốt hơn là, tôi muốn sửa tất cả các tác giả cam kết cũ để đại diện cho tác giả Git hơn là tên người dùng SVN thô.Tác giả chính xác có hiệu lực với Git SVN?

Trả lời

55

Bắt đầu ra bằng cách nhìn thấy những gì bạn đã có để làm sạch:

git shortlog -s 

Đối với mỗi một trong những cái tên đó, tạo ra một mục trong một kịch bản mà trông như thế này (giả sử bạn muốn tất cả các tác giả và committers là giống nhau):

#!/bin/sh 

git filter-branch --env-filter ' 

n=$GIT_AUTHOR_NAME 
m=$GIT_AUTHOR_EMAIL 

case ${GIT_AUTHOR_NAME} in 
     user1) n="User One" ; m="[email protected]" ;; 
     "User Two") n="User Two" ; m="[email protected]" ;; 
esac 

export GIT_AUTHOR_NAME="$n" 
export GIT_AUTHOR_EMAIL="$m" 
export GIT_COMMITTER_NAME="$n" 
export GIT_COMMITTER_EMAIL="$m" 
' 

đó là về cơ bản là kịch bản tôi sử dụng cho một large rewrite thời gian gần đây đó là rất nhiều như bạn mô tả (trừ tôi đã một số lượng lớn các tác giả).

chỉnh sửa Sử dụng π đã chỉ ra vấn đề trích dẫn trong tập lệnh của tôi. Cảm ơn!

+1

Nên xuất GIT_AUTHOR_NAME = "$ n" hoặc chỉ tên tác giả sẽ kết thúc trong chỉ mục! –

+4

Tập lệnh này hoạt động tốt. Tuy nhiên, sau khi tôi đã áp dụng nó, một cuộc gọi đến "git svn rebase" gây ra thông báo lỗi: "Không thể xác định thông tin SVN ngược dòng từ lịch sử cây đang hoạt động". – olenz

+0

Làm thế nào để bạn sau đó đi và đẩy các tác giả đã chỉnh sửa/sửa lại về điều khiển từ xa? – user1027169

2

Bạn có thể muốn xem xét git-filter-branch, cụ thể là tùy chọn --commit-filter. Lệnh này là một cưa mạnh mẽ có thể viết lại toàn bộ lịch sử kho lưu trữ của bạn, thay đổi bất cứ điều gì bạn có thể muốn thay đổi.

Lưu ý rằng khi bạn thực hiện việc này, bạn nên kéo các bản sao mới từ kho lưu trữ được cập nhật vì băm SHA1 của mọi cam kết có thể đã thay đổi.

10

git filter-branch có thể được sử dụng để ghi lại các phần lớn lịch sử.

Trong trường hợp này, có thể bạn sẽ làm điều gì đó tương tự (hoàn toàn chưa được kiểm tra):

git filter-branch --env-filter ' 
    GIT_AUTHOR_NAME=`echo "${GIT_AUTHOR_NAME}" | sed -e "s/svnname1/Right Name/; s/svnname2/Correct Name/"` 
    GIT_COMMITTER_NAME=`echo "${GIT_COMMITTER_NAME}" | sed -e "s/svnname1/Right Name/; s/svnname2/Correct Name/"` 
    GIT_AUTHOR_EMAIL=`echo "${GIT_AUTHOR_EMAIL}" | sed -e "s/svnname1/[email protected]/; s/svnname2/[email protected]/"` 
    GIT_COMMITTER_EMAIL=`echo "${GIT_COMMITTER_EMAIL}" | sed -e "s/svnname1/[email protected]/; s/svnname2/[email protected]/"` 
' 

Như thường lệ, sau đây áp dụng: để viết lại lịch sử, bạn cần một conspiracy.

+0

Được bầu chọn cho: "Như mọi khi, những điều sau đây được áp dụng: để viết lại lịch sử, bạn cần một âm mưu." Rất tốt nói. (Mặc dù liên kết không tải nữa) –

+0

Cảm ơn! Tôi đã sửa các liên kết. –

+0

Bạn sẽ gặp phải các vấn đề với các regex đã cho nếu bạn có một tên svn là một tập hợp con của một tên svn khác ... Đây là lý do tại sao thần đã cho chúng ta '^' và '$'. – Dan

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