Git状态忽略行尾/相同的文件/ Windows和Linux环境/ Dropbox / mled


112

我怎么做

git状态

忽略行尾差异?

背景信息:

我随机使用Windows和Linux进行该项目。该项目在Dropbox中。

我发现了很多有关如何使git diff忽略行尾的内容。由于我使用git git diff,因此会为每个文件打开meld。并说“相同文件”。

因此,如何避免这种情况。Git应该只对已更改的文件打开融合。如果只有文件结尾不同,则git status不应报告文件已更改。

编辑:原因:

发生这种情况是因为Windows上有此设置

core.autocrlf是

因此,我在Linux上签出了工作副本,并在Windows上将core.autocrlf设置为false。

知道如何使git status忽略不同的新行还是很高兴的。


3
如果要在不同平台上使用Dropbox共享文件,除非您明确告诉git将所有文件都视为二进制文件,否则将发生这种情况。正确的解决方案是不要对git存储库使用dropbox
Petesh 2013年

提醒您:stackoverflow.com/questions/2825428/…-这可能有所帮助
Petesh

我发现它如何与Dropbox配合使用:通过设置core.autocrlf false
Thorsten Niehues 2013年

3
AFAIK告诉git将文件视为二进制文件也具有更改其差异文件方式的副作用。正确的解决方案是告诉git忽略行尾。我最不喜欢的事情中的2个:处理行结束问题和关于人们设置
回购书

哇,花了我一段时间,因为这个问题core.autocrlf是Windows上的根本原因,也是Linux上的解决方法。问题是,autocrlf在Windows上是全局的,仓库中没有该设置.git/config。通过运行本地,git config core.autocrlf true我摆脱了在Windows上克隆但在Linux上访问的NTFS工作副本上的虚假更改。(现在,符号链接只有虚假的更改-NTFS符号链接可以在保险丝支架上工作,但是Git认为它们已被修改...)
Tomasz Gandor

Answers:


103

尝试像这样设置core.autocrlf值:

git config --global core.autocrlf true

6
@ThorstenNiehues我在某些工作项目上使用了该设置。在工作中,我必须使用Windows,在家里我必须使用Mac和Linux。在此之前,我遇到了与您相同的问题,在此之后,一切正常。
SASAŠijak

1
这很奇怪,因为Windows上的结帐仅在Linux上有\ r \ n行尾\ n您在Dropbox中是否有两个工作副本(或类似副本)?
Thorsten Niehues 2013年

1
@ThorstenNiehues不,git存储库位于github上。嗯,也许保管箱在同步文件时以某种方式弄乱了行尾?对git使用dropbox看起来确实很奇怪。尝试使用bitbucket(它具有免费的私人存储库),仅制作一个小型存储库,并在2台计算机上使用一些小型文本文件进行测试。
SASAŠijak

1
1.工作副本和本地存储库位于Dropbox中(我不需要公共存储库),这可能有所不同
Thorsten Niehues 2013年

3
在Windows中:core.autocrlf true是CygWin中的有效设置。core.safecrlf false是git bash或mingw中的工作设置
DrumM

43

请使用.gitattributes进行以下设置:

# Ignore all differences in line endings
*        -crlf

.gitattributes与全局.gitconfig位于同一目录中。如果.gitattributes不存在,请将其添加到该目录。添加/更改.gitattributes后,您将必须对存储库进行硬重置,以便将更改成功应用到现有文件。


它在一个流中对我有用,但是当我尝试在同一项目的另一个流中创建它时,它仍然显示出换行符的差异。
pfernandom '16

1
@pfernandom,您的项目中是否可能有多个.gitattributes?它将首先查看最“本地”的版本,因此,如果在文件所在的本地目录中有一个版本,它将在整个项目范围内使用该版本。
Trashman '16

-crlf之前需要有8个空格吗?
Igonato

没关系
Trashman

这不仅仅是忽略的行尾git status。它实际上改变了将文件检入存储库的方式。参考:git-scm.com/docs/gitattributes#_code_text_code
Vince

30

因为OP提到了对多OS解决方案的需求,所以这个答案似乎很重要。这个Github 帮助文章详细介绍了跨OS处理行结尾的可用方法。存在用于管理跨操作系统行尾的全局和按存储库的方法。

全球方针

在Linux或OS X上配置Git线尾处理:

git config --global core.autocrlf input

在Windows上配置Git行尾处理:

git config --global core.autocrlf true

按回购方式:

在你的回购的根目录,创建一个.gitattributes文件,并为您的项目文件中定义的行结束设置,在格式如下一次一行:path_regex line-ending-settings这里line-ending-settings是以下情况之一:

  • 文本
  • 二进制文件(Git不应修改其行尾的文件)

text可以进一步配置该值,以指导Git如何处理匹配文件的行尾:

  • text -将行尾更改为OS本机行尾。
  • text eol=crlf- CRLF在结帐时将行尾转换为。
  • text eol=lf- LF在结帐时将行尾转换为。
  • text=auto -明智的默认设置,让线句柄由Git自行决定。

这是一个示例.gitattributes文件的内容:

# Set the default behavior for all files.
* text=auto

# Normalized and converts to 
# native line endings on checkout.
*.c text
*.h text

# Convert to CRLF line endings on checkout.
*.sln text eol=crlf

# Convert to LF line endings on checkout.
*.sh text eol=lf

# Binary files.
*.png binary
*.jpg binary

更多有关在此处更改行尾设置后如何刷新仓库的信息。Tldr:

使用Git备份文件,删除存储库中的每个文件(.git目录除外),然后一次还原所有文件。将当前文件保存在Git中,这样就不会丢失任何工作。

git add . -u

git commit -m "Saving files before refreshing line endings"

删除索引并强制Git重新扫描工作目录。

rm .git/index

重写Git索引以拾取所有新行结尾。

git reset

显示重写的标准化文件。

在某些情况下,这就是所有要做的事情。其他人可能需要完成以下附加步骤:

git status

重新添加所有已更改的文件,并准备提交。这是您检查哪些文件(如果有)未更改的机会。

git add -u

可以很安全地在此处看到许多消息,上面写着“警告:文件中的LF将替换为CRLF”。

重写.gitattributes文件。

git add .gitattributes

将更改提交到存储库。

git commit -m "Normalize all the line endings"


18

与Windows操作系统上的git命令相关的问题

$ git add --all

警告:在...中,LF将被CRLF替换。

该文件将在您的工作目录中具有其原始行结尾。

分辨率

$ git config --global core.autocrlf false     
$ git add --all 

没有任何警告消息出现。


您应该在所有正在使用的操作系统中执行此操作,即:在Windows和Linux中。Rember每个操作系统都有其自己的全局.git / config文件,因此您需要使这些设置相似。这就是为什么@Thorsten您遇到问题的原因。但是我将标志设置为true而不是false。
伊曼纽尔·马哈尼

此解决方案在linux中也有效(@SašaŠijak的答案对我不起作用)
不起作用 juliocesar

4

我创建了一个脚本来忽略行尾的差异:

它将显示未添加到提交列表中并被修改的文件(忽略行尾的差异之后)。您可以添加参数“ add”以将这些文件添加到提交中。

#!/usr/bin/perl

# Usage: ./gitdiff.pl [add]
#    add : add modified files to git

use warnings;
use strict;

my ($auto_add) = @ARGV;
if(!defined $auto_add) {
    $auto_add = "";
}

my @mods = `git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-`;
chomp(@mods);
for my $mod (@mods) {
    my $diff = `git diff -b $mod 2>/dev/null`;
    if($diff) {
        print $mod."\n";
        if($auto_add eq "add") {
            `git add $mod 2>/dev/null`;
        }
    }
}

源代码:https : //github.com/lepe/scripts/blob/master/gitdiff.pl

更新内容

  • 通过evandro777修复:文件名或目录中有空格时

谢谢!那是我获得真正差异的唯一途径。仅仅出现了一个问题,打印了3行,显示了此错误:sh:1:语法错误:引号未
终止的

1
脚本问题的解决方案:问题:当文件在文件名ou目录中有空间时,git将使用“”,因此脚本将中断。解决方法是更改​​此行:my @mods = git status --porcelain 2>/dev/null | grep '^ M ' | awk '{ print \$2 }'; 对此:我的@mods = git status --porcelain 2>/dev/null | grep '^ M ' | cut -c4-;
evandro777

@ evandro777:谢谢!我已经更新了答案和git代码。
lepe

3

我同时使用Windows和Linux,但是该解决方案core.autocrlf true并没有帮助我。之后我什至没有任何改变git checkout <filename>

所以我用替代方法来替代 git status -gitstatus.sh

#!/bin/bash

git status | grep modified | cut -d' ' -f 4 | while read x; do
 x1="$(git show HEAD:$x | md5sum | cut -d' ' -f 1 )"
 x2="$(cat $x | md5sum | cut -d' ' -f 1 )"

 if [ "$x1" != "$x2" ]; then
    echo "$x NOT IDENTICAL"
 fi
done

我只是比较md5sum一个文件及其在存储库中的兄弟。

输出示例:

$ ./gitstatus.sh
application/script.php NOT IDENTICAL
application/storage/logs/laravel.log NOT IDENTICAL

2
也许您可以对每个文件使用“ git diff -b”来检查excel空格更改的更改
Ivan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.