[英]git-diff to ignore ^M
在某些文件包含 ^M 作為換行符分隔符的項目中。 區分這些文件顯然是不可能的,因為 git-diff 將其視為整個文件只是一行。
與以前的版本有何不同?
有沒有像“差異時將 ^M 視為換行符”這樣的選項?
prompt> git-diff "HEAD^" -- MyFile.as
diff --git a/myproject/MyFile.as b/myproject/MyFile.as
index be78321..a393ba3 100644
--- a/myproject/MyFile.cpp
+++ b/myproject/MyFile.cpp
@@ -1 +1 @@
-<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
+<U+FEFF>import flash.events.MouseEvent;^Mimport mx.controls.*;^Mimport mx.utils.Delegate
\ No newline at end of file
prompt>
更新:
現在我已經編寫了一個 Ruby 腳本來檢查最新的 10 個修訂並將 CR 轉換為 LF。
require 'fileutils'
if ARGV.size != 3
puts "a git-path must be provided"
puts "a filename must be provided"
puts "a result-dir must be provided"
puts "example:"
puts "ruby gitcrdiff.rb project/dir1/dir2/dir3/ SomeFile.cpp tmp_somefile"
exit(1)
end
gitpath = ARGV[0]
filename = ARGV[1]
resultdir = ARGV[2]
unless FileTest.exist?(".git")
puts "this command must be run in the same dir as where .git resides"
exit(1)
end
if FileTest.exist?(resultdir)
puts "the result dir must not exist"
exit(1)
end
FileUtils.mkdir(resultdir)
10.times do |i|
revision = "^" * i
cmd = "git show HEAD#{revision}:#{gitpath}#{filename} | tr '\\r' '\\n' > #{resultdir}/#{filename}_rev#{i}"
puts cmd
system cmd
end
GitHub 建議您應該確保在 git 處理的存儲庫中僅使用 \n 作為換行符。 有一個自動轉換的選項:
$ git config --global core.autocrlf true
當然,這里說的是把crlf轉成lf,而你想把cr轉成lf。 我希望這仍然有效……
然后轉換您的文件:
# Remove everything from the index
$ git rm --cached -r .
# Re-add all the deleted files to the index
# You should get lots of messages like: "warning: CRLF will be replaced by LF in <file>."
$ git diff --cached --name-only -z | xargs -0 git add
# Commit
$ git commit -m "Fix CRLF"
core.autocrlf在手冊頁上有描述。
在 Windows 上開發,我在使用git tfs
時遇到了這個問題。 我是這樣解決的:
git config --global core.whitespace cr-at-eol
這基本上告訴 Git 行尾 CR 不是錯誤。 結果,那些煩人的^M
字符不再出現在git diff
、 git show
等的行尾。
它似乎保持其他設置不變; 例如,行尾的額外空格仍然在差異中顯示為錯誤(以紅色突出顯示)。
(其他答案已經提到了這一點,但上面正是如何設置設置。要為一個項目設置設置,請省略--global
。)
編輯:
在經歷了許多行結束的痛苦之后,在 .NET 團隊工作時,我遇到了最好的運氣,使用以下設置:
如果您需要使用空白設置,如果您需要與 TFS 交互,您可能應該僅在每個項目的基礎上啟用它。 只需省略--global
:
git config core.whitespace cr-at-eol
如果您需要刪除一些 core.* 設置,最簡單的方法是運行以下命令:
git config --global -e
這將在文本編輯器中打開您的全局 .gitconfig 文件,您可以輕松刪除要刪除的行。 (或者你可以在它們前面加上'#'來注釋掉它們。)
嘗試git diff --ignore-space-at-eol
或git diff --ignore-space-change
或git diff --ignore-all-space
。
另見:
core.whitespace = cr-at-eol
或等效地,
[core]
whitespace = cr-at-eol
其中whitespace
前面有一個制表符。
git diff
中得到這些^M
? 就我而言,我正在從事一個在 Windows 中開發的項目,我使用的是 Linux。 當我更改一些代碼時,我在git diff
中添加的行的末尾看到了^M
。 我認為^M
出現是因為它們的行尾與文件的其余部分不同。 因為文件的其余部分是在 Windows 中開發的,所以它使用CRLF
行結尾,而在 Linux 中它使用LF
行結尾。
顯然,Windows 開發人員在安裝 Git 期間沒有使用“ Checkout Windows-style, commit Unix-style line endings ”選項。
您可以讓 Windows 用戶重新安裝 git 並使用“ Checkout Windows-style, commit Unix-style line endings ”選項。 這是我更喜歡的,因為我認為 Windows 在其行尾字符中是一個例外,並且 Windows 以這種方式解決了它自己的問題。
如果您選擇此選項,則應該修復當前文件(因為它們仍在使用CRLF
行尾)。 我按照以下步驟做到了這一點:
從存儲庫中刪除所有文件,但不要從您的文件系統中刪除。
git rm --cached -r .
添加一個.gitattributes
文件,強制某些文件使用LF
作為行尾。 把它放在文件中:
* text=auto eol=lf
再次添加所有文件。
git add .
這將顯示如下消息:
warning: CRLF will be replaced by LF in <filename>. The file will have its original line endings in your working directory.
您可以刪除.gitattributes
文件,除非您有頑固的 Windows 用戶不想使用“ Checkout Windows-style, commit Unix-style line endings ”選項。
承諾並推動這一切。
刪除並簽出所有使用它們的系統上的適用文件。 在 Windows 系統上,確保它們現在使用“ Checkout Windows-style, commit Unix-style line endings ”選項。 您還應該在執行這些任務的系統上執行此操作,因為當您添加文件時 git 說:
The file will have its original line endings in your working directory.
您可以執行以下操作來刪除文件:
git ls | grep ".ext$" | xargs rm -f
然后讓它們以正確的行結尾返回:
git ls | grep ".ext$" | xargs git checkout
將.ext
替換為您要匹配的文件擴展名。
現在您的項目只使用LF
字符作為行尾,討厭的CR
字符將永遠不會回來:)。
另一種選擇是強制執行 windows 樣式的行尾。 您也可以為此使用.gitattributes
文件。
更多信息: https ://help.github.com/articles/dealing-with-line-endings/#platform-all
有沒有像“差異時將 ^M 視為換行符”這樣的選項?
Git 2.16(2018 年第一季度)將會有一個,因為“ diff
”系列命令學會了忽略行尾回車的差異。
請參閱Junio C Hamano ( gitster
)的提交 e9282f0 (2017 年 10 月 26 日)。
幫助者: Johannes Schindelin ( dscho
) 。
(由Junio C Hamano -- gitster
--在提交 10f65c2中合並,2017 年 11 月 27 日)
差異:
--ignore-cr-at-eol
一個新選項
--ignore-cr-at-eol
告訴 diff 機器將(完整)行末尾的回車視為不存在。就像其他忽略各種空白差異的“
--ignore-*
”選項一樣,這將有助於查看您所做的實際更改,而不會被編輯器程序進行的虛假CRLF<->LF
轉換分心。
TL;博士
將core.pager
更改為"tr -d '\r' | less -REX"
,而不是源代碼
這就是為什么
顯示的那些討厭的 ^M 是着色和尋呼機的產物。 這是由默認的 git 尋呼機選項
less -R
引起的。 (git 的默認尋呼機是less -REX
)
首先要注意的是git diff -b
不會顯示空白的變化(例如 \r\n vs \n)
設置:
git clone https://github.com/CipherShed/CipherShed
cd CipherShed
創建 unix 文件並更改行尾的快速測試將顯示git diff -b
沒有更改:
echo -e 'The quick brown fox\njumped over the lazy\ndogs.' > test.txt
git add test.txt
unix2dos.exe test.txt
git diff -b test.txt
我們注意到,強制管道更少不會顯示 ^M,但啟用顏色和less -R
會:
git diff origin/v0.7.4.0 origin/v0.7.4.1 | less
git -c color.ui=always diff origin/v0.7.4.0 origin/v0.7.4.1 | less -R
通過使用管道從輸出中去除 \r (^M) 來顯示修復:
git diff origin/v0.7.4.0 origin/v0.7.4.1
git -c core.pager="tr -d '\r' | less -REX" diff origin/v0.7.4.0 origin/v0.7.4.1
一個不明智的選擇是使用less -r
,因為它將通過所有控制代碼,而不僅僅是顏色代碼。
如果您只想直接編輯您的 git 配置文件,這是更新/添加的條目:
[core]
pager = tr -d '\\r' | less -REX
就我而言,它是什么命令:
git config core.whitespace cr-at-eol
來源: https ://public-inbox.org/git/8d7e4807-9a79-e357-8265-95f22ab716e0@web.de/T/
我為這個問題苦苦掙扎了很長時間。 到目前為止,最簡單的解決方案是不用擔心 ^M 字符,只需使用可以處理它們的視覺差異工具。
而不是鍵入:
git diff <commitHash> <filename>
嘗試:
git difftool <commitHash> <filename>
正如 VonC 所指出的,這已經包含在 git 2.16+ 中。 不幸的是,選項的名稱( --ignore-cr-at-eol
)與我習慣的 GNU diff 使用的名稱( --strip-trailing-cr
)不同。
當我遇到這個問題時,我的解決方案是調用 GNU diff 而不是 git 的內置 diff,因為我的 git 比 2.16 舊。 我使用這個命令行做到了:
GIT_EXTERNAL_DIFF='diff -u --strip-trailing-cr "$2" "$5";true;#' git diff --ext-diff
這允許使用--strip-trailing-cr
和任何其他 GNU diff 選項。
還有這種方式:
git difftool -y -x 'diff -u --strip-trailing-cr'
但它不使用配置的尋呼機設置,這就是我更喜歡前者的原因。
如果您只想要一條使git diff
但不顯示不同結尾(因此^M
)的快速行,請使用原始問題的第一條評論中的那個,它對我有用:
git diff -b
考慮到,從長遠來看,您應該正確配置行尾,正如所有其他答案所暗示的那樣。
如果 git 補丁已經在 Windows 機器中生成並且您正在使用它,您可以在 Linux 中使用 dos2unix 實用程序格式化補丁。
find -name "*.patch"| xargs dos2unix
這將解決 EOL 的 ^M 問題,您將能夠在您的 linux 機器中應用 git apply 補丁。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.