Observe os finais de linha de git diff
:
- IP_ADDR: 'http://1.2.3.4:143'
+ IP_ADDR: 'http://2.4.6.8:143'^M
Editei este arquivo colocando o cursor 1
e pressionando ct:
e inserindo o novo endereço IP. Nenhuma linha completa foi adicionada ou removida do arquivo. Percebo, porém, que o arquivo aparece como tipo dos
no VIM.
Por que o VIM alteraria o final da linha se eu não editasse explicitamente essa parte do documento? Além disso, vendo como diff
mostra que não havia nenhum ^M
na linha original, de que outra forma o VIM poderia ter decidido que se trata de um dos
arquivo?
Responder1
O Vim detectará o formato de arquivo original (entre aqueles configurados em 'fileformats'
) e escreverá com o mesmo. A única maneira de o Vim mudar (por exemplo, do estilo Unix para o estilo Windows) é através de um arquivo :setlocal fileformat=dos
. É improvável que você tenha isso em sua configuração; :verbose setl ff?
poderia te contar.
Eu não ficaria muito preocupado com o diff do Git (contanto que nãotodoslinhas aparecem como alteradas, então você realmente tem uma mudança de finais de linha), mas sim que o que é confirmado está certo.
Observe que com a configuração do Git autocrlf = true
, o Git converterá novas linhas para o padrão do sistema ao fazer check-out de arquivos e para novas linhas LF ao confirmar. Então tudo pode estar bem, apenas a saída diff do Git está confundindo você.
Responder2
Esta é uma evidência de que todos vivemos na Matrix. Se este fosse realmente o século 21, não estaríamos ainda lutando contra diferentes finais de linha.
O Vim faz um ótimo trabalho ao fazer a coisa certa com finais de linha. Os detalhes são explicados em :help 'ffs'
. Claro, o vim não pode ler sua mente: se o seu arquivo tiverinconsistentefinais de linha, então o vim pode não fazer o que você deseja.
Sugiro abrir o arquivo no vim e depois
:e! ++ff=unix
Isso irá recarregar o arquivo do disco, forçando o vim a usar finais de linha no estilo unix. Então você deverá ver exatamente quais linhas têm terminações CRLF, porque elas terminarão com ^M
caracteres brutos.
Embora eu ame o git, não o conheço e confio nele tão bem quanto no vim. Acho que algumas pessoas recomendam configurações do tipo "configure e esqueça" para crlf
as configurações do git que podem causar confusão. Prefiro evitar a configuração que @Ingo Karkat mencionou em sua resposta. Quero que o git verifique o mesmo arquivo que foi verificado e deixe que eu (e o vim) cuide dos finais de linha.
Responder3
git diff
mostra apenas retornos de carro ( ^M
) em linhas adicionadas, mas não em linhas removidas ou inalteradas. Você pode ver isso se usar o -R
sinalizador, que mostra a diferença ao contrário.
$ git diff -R
:
- IP_ADDR: 'http://2.4.6.8:143'
+ IP_ADDR: 'http://1.2.3.4:143'^M
Então o vim não está adicionando nada; especialmente não para apenas uma linha. O Vim usa os finais de linha que encontra no arquivo ao abri-lo.
Responder4
O Vim é baseado no valor da opção fileformat para determinar se o arquivo atualmente aberto é DOS ou Unix, ou um arquivo Mac. O valor da opção fileformat é determinado pelo valor da opção fileformats.
Quando o vim abre um arquivo, o vim determinará um valor de opção de formato de arquivo válido para o buffer atual com base no valor da opção de formato de arquivo atual. A seguir está a descrição do manual do vim sobre como o vim determina o valor da opção fileformat do buffer atual pelo valor da opção fileformats:
'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.
Voltando à sua pergunta, seu arquivo é identificado como um arquivo dos no vim, então quando você salva o arquivo e sai do vim, o vim substituirá automaticamente o caractere de nova linha pelo estilo dos newline: .
Na árvore de diretórios de trabalho do git, este arquivo é um arquivo dos, mas como esse arquivo é um arquivo unix na árvore de índice do git, então, usando git diff
, você verá que o arquivo foi alterado. Para um arquivo no formato Unix, o extra será exibido como caractere ^M.