2012-03-28 40 views
31

Tôi khá hài lòng với cách Git tự xử lý các kết thúc dòng, thông qua core.autocrlf, core.eol + gitattributes (Tim's post is excellent).Làm thế nào để kết thúc dòng lệnh git-svn?

Tôi có một repo Windows Git có autocrlf được đặt thành true. Vì vậy, tất cả các tập tin văn bản được lưu trữ trong repo như LF và sống trong thư mục làm việc như CRLF. Repo này được nhân bản từ một repo SVN, mà chúng ta vẫn sử dụng để đẩy từ/pull đến (repo SVN là trung tâm của chúng ta, may mắn repo để kích hoạt CI vv).

Nhưng tôi không biết cách git-svn xử lý các kết thúc dòng trong các hoạt động đẩy/kéo.

Bất cứ ai có thể giải thích những gì git-svn trong trường hợp này?

Trả lời

15

Tôi cũng quan tâm đến điều này. Giả sử bạn có một repo đã được tạo ra thông qua git svn clone, tôi nghĩ bạn có thể phá vỡ nó xuống thành ba câu hỏi khác nhau:

  1. Có bất kỳ git xuống dòng bình thường/thay đổi xảy ra tại git svn lấy thời gian, trong việc di chuyển các cam kết từ svn để git repo?
  2. Có bất kỳ sự chuẩn hóa/sửa đổi dòng mới nào của git xảy ra tại thời gian cam kết không (tức là trong một git địa phương bình thường cam kết một repo với điều khiển từ xa svn]? Làm thế nào về thời gian hợp nhất/rebase?
  3. Có bất kỳ sự chuẩn hóa/sửa đổi dòng mới git nào xảy ra tại thời điểm git svn dcommit hay không, trong việc đẩy/phát lại/bất kỳ lệnh git nào cam kết chống lại svn?

Tôi muốn nghe những gì về mặt lý thuyết cho là đúng đối với những câu hỏi này, nhưng bây giờ tôi đã làm một thí nghiệm nhỏ mà dường như để chứng minh rằng không có bình thường xuống dòng trong trường hợp # 1 ít nhất:

rem We'll make a svn repo with CRLF newlines, clone it into git with 
rem autocrlf enabled, and try to see if that results in LF-only newlines 
rem getting stored in the git repo 

cd c:\code 

rem Step 1. Prepare SVN repo with CRLF type newlines. 
rem The pre-1.4 flag is to prevent an error during git clone. 

svnadmin create --pre-1.4-compatible svnrepo 
svn checkout file:///C:/code/svnrepo svnworking 
cd svnworking 
echo "First line" > file.txt 
echo "Second line" >> file.txt 
echo "Third line" >> file.txt 
rem NOTE: At this point file.txt has CRLF newlines 
svn add file.txt 
svn commit -m "Add file.txt" 
rem NOTE: At this point file.txt still has CRLF newlines 
cd .. 

rem Step 2. Clone the svn repo into git and inspect work copy newline type 
git svn clone file:///C:/code/svnrepo gitrepo 
rem The following outputs true on my machine 
git config --get core.autocrlf 
cd gitrepo 
rem The following also outputs true on my machine 
git config --get core.autocrlf 
git svn fetch 
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines 

rem Step 3. Disable autocrlf to inspect repo's inner newline type 
rem Use the following and my editor to set core.autocrlf to false: 
git config --edit --local 
rem This now prints false: 
git config --get core.autocrlf 
git checkout . 
rem NOTE: At this point file.txt (git working dir copy) still has CRLF newlines 
del file.txt 
git checkout . 
rem NOTE: Even after explicitly deleting the old one and checking out again, 
rem file.txt still has CRLF newlines 

Nếu chuyển đổi dòng mới git đã diễn ra trong quá trình kéo git svn của tôi, ngược lại, sau đó tôi mong đợi file.txt có dòng mới LF ở cuối tất cả điều này.

Dưới đây là một kiểm tra sanity rằng bước 3 ở trên thực sự thực hiện một bài kiểm tra hợp lệ cho dù các repo có LF-only dòng mới:

rem We'll a git repo with core.autocrlf on, then switch it off to 
rem pull out a file 

rem The following outputs true 
git config --get core.autocrlf 
git init gitcrtest 
cd gitcrtest 
rem The following still outputs true 
git config --get core.autocrlf 
echo "First line" > file.txt 
echo "Second line" >> file.txt 
echo "Third line" >> file.txt 
git add file.txt 
git commit -m "Add file.txt" 
rem NOTE: At this point file.txt (git working dir copy) has CRLF newlines 
rem Use the following to set core.autocrlf to false 
git config --edit --local 
git checkout . 
rem NOTE: Now file.txt (git working dir copy) has LF-only newlines 

Nói tóm lại: Căn cứ vào ở trên, có vẻ như rằng khi git-svn kéo từ svn, các cam kết svn được thêm vào biểu đồ git commit mà không có bất kỳ bản dịch crlf nào, ngay cả khi autocrlf được kích hoạt. Đó là, bất kỳ loại dòng mới của bạn tập tin có trong repo svn của bạn, họ cũng sẽ có trong git clone của bạn. (Nhưng git bản sao làm việc của bạn có thể có các loại dòng mới khác nhau.)

Lưu ý rằng điều này khá phù hợp với thảo luận về chuẩn hóa cuối dòng trong "thuộc tính trợ giúp git"; có bình thường được trình bày dưới dạng lệnh xảy ra với lệnh kéo công cụ từ repo vào thư mục làm việc của bạn (ví dụ: thanh toán hoặc hợp nhất) hoặc với lệnh chuyển mọi thứ từ thư mục làm việc của bạn sang chỉ mục/repo (ví dụ: thêm hoặc cam kết). "Git svn fetch" dường như không làm một trong những điều đó, do đó, nó có ý nghĩa rằng không có bình thường cuối dòng sẽ xảy ra tại thời điểm đó. Tôi đang mờ về những gì dcommit không, vì vậy tôi không chắc chắn có nên mong đợi end-of-line bình thường tại thời điểm đó.

Lưu ý có một nếp nhăn bổ sung nếu thuộc tính svn: eol kiểu SVN được đặt trên máy repo/máy của bạn.Tôi nghĩ rằng mặc định SVN là không phải thực hiện chuyển đổi cuối cùng trên mạng, nhưng tôi không chắc chắn 100%.

Cập nhật: Đối với góc nhìn di chuyển thực tế trên dòng mới, xem thêm Tim Abell's description. Các dòng mới của CRLF không được chuyển đổi thành các dòng mới của LF chỉ bằng git-svn, với các kết quả không lý tưởng nếu việc chuẩn hóa cuối dòng tự động của git được để lại. Các giải pháp là bình thường hóa các kết thúc dòng trong git hoặc để vô hiệu hoá việc chuẩn hóa cuối dòng.

+1

"Tôi nghĩ mặc định SVN không thực hiện chuyển đổi cuối dòng trên đầu của nó" Đúng vậy, theo http://svnbook.red-bean.com/en/1.7/svn.advanced.props. file-portability.html "theo mặc định, Subversion không chú ý đến loại dấu đánh dấu cuối dòng (EOL) được sử dụng trong tệp của bạn." –

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