請注意以下行結尾git diff
:
- IP_ADDR: 'http://1.2.3.4:143'
+ IP_ADDR: 'http://2.4.6.8:143'^M
我透過將遊標放在 上1
然後按ct:
並輸入新的 IP 位址來編輯此文件。文件中沒有新增或刪除完整的行。我確實注意到該文件dos
在 VIM 中顯示為類型。
如果我沒有明確編輯文件的該部分,為什麼 VIM 會更改行結尾?另外,看看如何diff
顯示原始行中沒有^M
,否則 VIM 可能如何確定這是一個dos
檔案?
答案1
Vim 將偵測原始檔案格式(在 中配置的檔案格式中'fileformats'
),並使用相同的格式進行寫入。 Vim 切換(例如從 Unix 到 Windows 風格)的唯一方法是透過顯式:setlocal fileformat=dos
.你的配置中不太可能有這個;:verbose setl ff?
可以告訴你。
我不會太在意 Git diff ifself (只要不全部行顯示為已更改,那麼您確實可以切換行結尾),但提交的內容是可以的。
請注意,使用 Git 設置autocrlf = true
,Git 將在簽出文件時將換行符號轉換為系統標準,並在提交時將換行符轉換為 LF 換行符。所以一切可能都很好,只是 Git diff 輸出讓你感到困惑。
答案2
這是我們都活在矩陣中的證據。如果這真的是21世紀,那麼我們就不會還在為不同的結局而奮鬥了。
Vim 在使用行結尾做正確的事情方面做得非常好。詳細資訊解釋如下:help 'ffs'
。當然,vim 無法讀懂你的想法:如果你的檔案有不一致的行結尾,那麼 vim 可能不會做你想要的事情。
我建議在 vim 中開啟文件,然後
:e! ++ff=unix
這將從磁碟重新載入文件,強制 vim 使用 unix 樣式的行結尾。然後您應該準確地看到哪些行具有 CRLF 結尾,因為它們將以原始^M
字元結尾。
雖然我喜歡 git,但我並不像 vim 那樣了解並信任它。我認為有些人建議對 git 的crlf
設定進行「設定後就忘記它」的配置,這可能會導致混亂。我更喜歡避免@Ingo Karkat 在他的回答中提到的設定。我希望 git 簽出已簽入的同一文件,並讓我(和 vim)處理行結尾。
答案3
git diff
僅在新增的行中顯示回車符 ( ^M
),但在刪除或未變更的行中不顯示回車符 ( )。如果您使用該-R
標誌,您可以看到這一點,該標誌以相反的方式顯示差異。
$ git diff -R
:
- IP_ADDR: 'http://2.4.6.8:143'
+ IP_ADDR: 'http://1.2.3.4:143'^M
所以 vim 沒有加任何東西;特別是不僅適用於一根線。 Vim 在開啟檔案時使用它在檔案中找到的行尾。
答案4
Vim 是根據 fileformat 選項的值來判斷目前開啟的檔案是 dos 還是 unix,還是 mac 檔案。
當 vim 開啟檔案時,vim 會根據目前 fileformats 選項的值決定目前緩衝區的有效 fileformat 選項值。以下是 vim 手冊關於 vim 如何透過 fileformats 選項的值來決定目前緩衝區的 fileformat 選項的值的說明:
'fileformats' 'ffs' string (default:
Vim+Vi MS-DOS, MS-Windows OS/2: "dos,unix",
Vim Unix: "unix,dos",
Vim Mac: "mac,unix,dos",
Vi Cygwin: "unix,dos",
Vi others: "")
global
{not in Vi}
This gives the end-of-line (<EOL>) formats that will be tried when
starting to edit a new buffer and when reading a file into an existing
buffer:
- When empty, the format defined with 'fileformat' will be used
always. It is not set automatically.
- When set to one name, that format will be used whenever a new buffer
is opened. 'fileformat' is set accordingly for that buffer. The
'fileformats' name will be used when a file is read into an existing
buffer, no matter what 'fileformat' for that buffer is set to.
- When more than one name is present, separated by commas, automatic
<EOL> detection will be done when reading a file. When starting to
edit a file, a check is done for the <EOL>:
1. If all lines end in <CR><NL>, and 'fileformats' includes "dos",
'fileformat' is set to "dos".
2. If a <NL> is found and 'fileformats' includes "unix", 'fileformat'
is set to "unix". Note that when a <NL> is found without a
preceding <CR>, "unix" is preferred over "dos".
3. If 'fileformat' has not yet been set, and if a <CR> is found, and
if 'fileformats' includes "mac", 'fileformat' is set to "mac".
This means that "mac" is only chosen when:
"unix" is not present or no <NL> is found in the file, and
"dos" is not present or no <CR><NL> is found in the file.
Except: if "unix" was chosen, but there is a <CR> before
the first <NL>, and there appear to be more <CR>s than <NL>s in
the first few lines, "mac" is used.
4. If 'fileformat' is still not set, the first name from
'fileformats' is used.
When reading a file into an existing buffer, the same is done, but
this happens like 'fileformat' has been set appropriately for that
file only, the option is not changed.
When 'binary' is set, the value of 'fileformats' is not used.
When Vim starts up with an empty buffer the first item is used. You
can overrule this by setting 'fileformat' in your .vimrc.
For systems with a Dos-like <EOL> (<CR><NL>), when reading files that
are ":source"ed and for vimrc files, automatic <EOL> detection may be
done:
- When 'fileformats' is empty, there is no automatic detection. Dos
format will be used.
- When 'fileformats' is set to one or more names, automatic detection
is done. This is based on the first <NL> in the file: If there is a
<CR> in front of it, Dos format is used, otherwise Unix format is
used.
Also see |file-formats|.
For backwards compatibility: When this option is set to an empty
string or one format (no comma is included), 'textauto' is reset,
otherwise 'textauto' is set.
NOTE: This option is set to the Vi default value when 'compatible' is
set and to the Vim default value when 'compatible' is reset.
回到你的問題,你的文件在 vim 中被識別為 dos 文件,所以當你保存文件並退出 vim 時,vim 會自動將換行符替換為 dos 風格的 newline: 。
在你的 git 工作目錄樹中,這個文件是一個 dos 文件,但是由於這個文件在 git 索引樹中是一個 unix 文件,所以,透過使用git diff
,你會看到該文件已經改變。對於Unix格式的文件,多餘的部分將顯示為^M字元。