Tôi đã gặp sự cố này ngày hôm nay. Trong trường hợp của tôi, vấn đề là do trình soạn thảo văn bản của tôi (Visual Studio) đã thêm một Unicode BOM vào mọi tệp mà nó đã chạm vào. Trong khi đó, máy chủ Perforce được thiết lập để tách Unicode BOM khỏi mọi tệp, ngăn không cho BOM Unicode xuất hiện trong Perforce. Điều này cuối cùng gây ra tôi git p4 submit
thất bại với thông báo sau:
error: patch failed: path/to/file.csproj:1
error: path/to/file.csproj: patch does not apply
giải pháp cuối cùng
tôi thêm định nghĩa bộ lọc sau trong ~/.gitconfig tập tin của tôi:
[filter "utf8-autobom"]
clean = sed -b -e '1!b' -e 's/^\\xEF\\xBB\\xBF//'
smudge = sed -b -e '1!b' -e 's/\\(^\\|^\\xEF\\xBB\\xBF\\)/\\xEF\\xBB\\xBF/'
Sau đó, tôi đã áp dụng bộ lọc utf8-autobom
cho các tệp vi phạm bằng cách thêm dòng sau vào .gitattributes:
*.csproj filter=utf8-autobom
Sau đó, tôi buộc phải Git để áp dụng các bộ lọc để chỉ số của nó với:
rm .git/index
git reset
Sau đó, tôi cam kết các tập tin đã chỉnh sửa vào Git và gửi tôi cam kết Perforce như thường lệ:
git add .
git commit --amend
git p4 submit
Cách hoạt động
Định nghĩa bộ lọc dựa trên các lệnh sed
sau đây, trong đó "abc" là một địa điểm giữ cho chuỗi byte Unicode BOM thích hợp:
# Remove 'abc' from beginning of file, if present
sed -b -e '1!b' -e 's/^abc//'
# Add 'abc' to beginning of file, if not present
sed -b -e '1!b' -e 's/\(^\|^abc\)/abc/'
Đối với một BOM UTF-8, chúng tôi sử dụng các chuỗi byte EF BB BF
thay vì "abc".
Bộ lọc loại bỏ BOM bằng cách chạy lệnh clean
và thêm BOM khi thanh toán bằng cách chạy lệnh smudge
.Điều này giữ cho BOM trong các tệp cây đang hoạt động, nhưng ngăn không cho BOM được cam kết với Git hoặc được gửi tới Perforce.
(Tham khảo gitattributes documentation biết chi tiết về clean
và smudge
.)
Chẩn đoán các vấn đề
tôi nghĩ được thông báo lỗi là thú vị:
error: patch failed: path/to/file.csproj:1
error: path/to/file.csproj: patch does not apply
Nó cho biết bản vá thất bại trên dòng 1 mặc dù cam kết của tôi không chỉnh sửa dòng 1 của tệp.
Để xem điều gì đang diễn ra, tôi chạy git diff p4/master HEAD
. Sự khác biệt cho thấy rằng cam kết của tôi đã thêm một ký tự lạ <U+FEFF>
ở đầu tệp. Tôi nghi ngờ nó có liên quan đến mã hóa tệp, vì vậy tôi đã sử dụng Notepad ++ để mở tệp trong cây làm việc Git của tôi. Sau đó, tôi mở tệp tương ứng trong không gian làm việc Perforce của tôi. Notepad ++ cho thấy mã hóa là "UTF-8-BOM" trong cây làm việc Git của tôi và "UTF-8" trong không gian làm việc Perforce của tôi. (người dùng Linux và Cygwin: sử dụng lệnh file <path-to-file>
để hiển thị thông tin về mã hóa tệp.)
Googling "UTF-8-BOM" đưa tôi đi đúng hướng.
Thông báo
Một số thao tác Git sẽ chậm hơn với bộ lọc này được cài đặt.
Mẹo
Bạn có thể loại bỏ các phần smudge
của bộ lọc nếu bạn không cần BOM trong cây làm việc của bạn. Điều này sẽ tăng tốc một số hoạt động Git (như git checkout
). Đã xóa dòng smudge
, định nghĩa bộ lọc là:
[filter "utf8-autobom"]
clean = sed -b -e '1!b' -e 's/^\\xEF\\xBB\\xBF//'
Một trong hai cách này có phù hợp với bạn không? http://stackoverflow.com/questions/9042865/git-p4-submit-fails-with-patch-does-not-apply http://stackoverflow.com/questions/15953609/git-p4-submit-fails – Philip