簡體   English   中英

git-diff 忽略 ^M

[英]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 diffgit show等的行尾。

它似乎保持其他設置不變; 例如,行尾的額外空格仍然在差異中顯示為錯誤(以紅色突出顯示)。

(其他答案已經提到了這一點,但上面正是如何設置設置。要為一個項目設置設置,請省略--global 。)

編輯

在經歷了許多行結束的痛苦之后,在 .NET 團隊工作時,我遇到了最好的運氣,使用以下設置:

  • 沒有 core.eol 設置
  • 沒有 core.whitespace 設置
  • 沒有 core.autocrlf 設置
  • 運行 Windows 的 Git 安裝程序時,您將獲得以下三個選項:
    • 簽出 Windows 風格,提交 Unix 風格的行尾<-- 選擇這個
    • 按原樣結帳,提交 Unix 風格的行尾
    • 按原樣結帳,按原樣提交

如果您需要使用空白設置,如果您需要與 TFS 交互,您可能應該僅在每個項目的基礎上啟用它。 只需省略--global

git config core.whitespace cr-at-eol

如果您需要刪除一些 core.* 設置,最簡單的方法是運行以下命令:

git config --global -e

這將在文本編輯器中打開您的全局 .gitconfig 文件,您可以輕松刪除要刪除的行。 (或者你可以在它們前面加上'#'來注釋掉它們。)

嘗試git diff --ignore-space-at-eolgit diff --ignore-space-changegit 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行尾)。 我按照以下步驟做到了這一點:

  1. 從存儲庫中刪除所有文件,但不要從您的文件系統中刪除。

     git rm --cached -r .
  2. 添加一個.gitattributes文件,強制某些文件使用LF作為行尾。 把它放在文件中:

     * text=auto eol=lf
  3. 再次添加所有文件。

     git add .

    這將顯示如下消息:

     warning: CRLF will be replaced by LF in <filename>. The file will have its original line endings in your working directory.
  4. 您可以刪除.gitattributes文件,除非您有頑固的 Windows 用戶不想使用“ Checkout Windows-style, commit Unix-style line endings ”選項。

  5. 承諾並推動這一切。

  6. 刪除並簽出所有使用它們的系統上的適用文件。 在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM