I ran into this issue today. In my case, the problem was because my text editor (Visual Studio) was adding a Unicode BOM to every file it touched. Meanwhile, the Perforce server was set up to strip the Unicode BOM from every file, preventing a Unicode BOM from appearing in Perforce. This ultimately caused my git p4 submit
to fail with the following message:
error: patch failed: path/to/file.csproj:1
error: path/to/file.csproj: patch does not apply
Final solution
I added the following filter definition in my ~/.gitconfig file:
[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/'
Then I applied the utf8-autobom
filter to the offending files by adding the following line in .gitattributes:
*.csproj filter=utf8-autobom
Then I forced Git to apply the filter to its index with:
rm .git/index
git reset
Then I committed the edited files to Git and submitted my commit to Perforce as usual:
git add .
git commit --amend
git p4 submit
How it works
The filter definition is based on the following sed
commands, where "abc" is a placeholder for the appropriate Unicode BOM byte sequence:
# 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/'
For a UTF-8 BOM, we use the byte sequence EF BB BF
instead of "abc".
The filter removes the BOM on commit by running the clean
command, and adds the BOM on checkout by running the smudge
command. This keeps the BOM in the working tree files, but prevents the BOM from being committed to Git, or submitted to Perforce.
(Refer to the gitattributes documentation for details on clean
and smudge
.)
Diagnosing the problem
I thought the error message was interesting:
error: patch failed: path/to/file.csproj:1
error: path/to/file.csproj: patch does not apply
It said the patch failed on line 1 even though my commit didn't edit line 1 of the file.
To see what was going on, I ran git diff p4/master HEAD
. The diff showed that my commit was adding a strange <U+FEFF>
character at the beginning of the file. I suspected it was related to file encoding, so I used Notepad++ to open the file in my Git working tree. Then I opened the corresponding file in my Perforce workspace. Notepad++ showed the encoding as "UTF-8-BOM" in my Git working tree, and "UTF-8" in my Perforce workspace. (Linux and Cygwin users: use the file <path-to-file>
command to show information about file encoding.)
Googling "UTF-8-BOM" got me on the right path.
Notice
Some Git operations will be slower with this filter installed.
Tip
You can remove the smudge
portion of the filter if you don't need the BOM in your working tree. This will speed up some Git operations (like git checkout
). With the smudge
line removed, the filter definition is:
[filter "utf8-autobom"]
clean = sed -b -e '1!b' -e 's/^\\xEF\\xBB\\xBF//'