SourceTree应用程序即使对于新克隆的存储库也会显示未提交的更改 - 可能有什么问题?

40
一个远程的git仓库被使用Atlassian SourceTree克隆到本地。即使工作区没有真正被修改,Atlassian也会立即在“未提交的更改”下列出一堆文件。每个文件都显示相同的行数,既作为删除又作为添加,且此计数等于文件中的总行数。这可能暗示我们遇到了某种行结束符问题。
然而,仓库的.gitattribute包含:
# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto

根据 GitHub 文章 处理行尾,应该显式使 core.autocrlf 的值为 true。然而,~/.gitconfig 中也包含 autocrlf = true
如果试图将修改的文件“还原”到以前的提交,则不会有任何效果。相同的文件仍被视为未提交。
这个代码库已经克隆到多个位置,并确保没有文件位于相同的路径下,以确保 SourceTree 或 git 不会记住旧文件。
这个代码库与 Windows、Linux 和 OSX 相协作。这个问题只出现在 OSX 上。
SourceTree/仓库/git 设置中可能仍存在什么问题?

更新 #1,2013年4月20日

由于仍然存在问题,这里提供了git config --list的部分输出。

来自SourceTree控制台(OSX)

core.excludesfile=/Users/User/.gitignore_global
core.autocrlf=input
difftool.sourcetree.cmd=opendiff "$LOCAL" "$REMOTE"
difftool.sourcetree.path=
mergetool.sourcetree.cmd=/Applications/SourceTree.app/Contents/Resources/opendiff-w.sh "$LOCAL" "$REMOTE" -ancestor "$BASE" -merge "$MERGED"
mergetool.sourcetree.trustexitcode=true
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.autocrlf=true

这是来自Windows端的相应输出:
core.symlinks=false
core.autocrlf=false
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
pack.packsizelimit=2g
help.format=html
http.sslcainfo=/bin/curl-ca-bundle.crt
sendemail.smtpserver=/bin/msmtp.exe
diff.astextplain.textconv=astextplain
rebase.autosquash=true
http.proxy=
core.autocrlf=true
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.symlinks=false
core.ignorecase=true
core.hidedotfiles=dotGitOnly
core.eol=native
core.autocrlf=true

需要为相关存储库提供完整的.gitattributes

# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto

*.php    text
*.twig   text
*.js     text
*.html   text diff=html
*.css    text
*.xml    text
*.txt    text
*.sh     text eol=lf
console  text

*.png    binary
*.jpg    binary
*.gif    binary
*.ico    binary
*.xslx   binary

关于 autocrlf,你说它在 ~/.gitconfig 中设置,但如果它在你的仓库的 .gitconfig 中设置,那么它将覆盖全局配置。你尝试过在你的仓库 .gitconfig 中将 autocrlf 设置为 true 吗? - Kieran Senior
@KieranSenior 老实说,我还没有。现在正在审查输出,我可以看到在Mac和Win中都有两行autocrlf - 即使在同一台计算机上也完全不同。所以,我认为我们必须尝试将所有可能的autocrlf设置为true。但是 - 我认为.gitattribute在这里也应该起作用,不是吗?在第一行中,我们有* text=auto... - Ville Mattila
是的,根据我下面的回答,text=auto应该按照git文档中所述自动转换您的行尾。例如,如果您删除了该选项并再次检出存储库,则不应列出大量已修改的文件。 - Kieran Senior
只是补充一下,我希望我们不要偏离原始问题,就像你在评论中说的那样,“autocrlf”变量应该设置为true。最好将其设置在本地repo实例中。如果“text”设置为“auto”,则如checkin文档中所述,它将自动规范化行尾。我的下面的答案确实涵盖了这两种情况,因此我认为它是相关的,但可能没有完全解决您的问题。让我稍微编辑一下。 - Kieran Senior
似乎使用SourceTree嵌入式Git和系统Git之间存在差异 - 切换到系统版本由于行结尾问题不会报告更改的文件。注意:在我的情况下 => 嵌入式版本= 1.8.0,系统版本= 1.79。 - Keith
5个回答

39

我是 SourceTree 开发者之一(实际上我负责产品的 Mac 版本开发),希望能对您有所帮助。

Windows 计算机在提交时将 CRLF 转换为 LF,在检出时将 LF 转换为 CRLF。 autocrlf 确保存储库中的所有内容都是 LF 格式。但实际上我们要关注的选项是 text = auto,因为文档上说到:

当 text 设置为 "auto" 时,该路径标记为自动行尾标准化。如果 Git 决定内容是文本,则其行尾在签入时被规范化为 LF。

所以你可以看到,在签入时,Git 将会说:“嘿,我需要规范化这些行尾,因为它们不是 LF 格式,而是 CRLF 格式”,从而修改您的工作副本以执行预期的操作。通常在 Mac/Linux 上,您不需要进行规范化,因为所有内容都是 LF 格式,但是 Git 将检查,因为您可能已经从之前在 Windows 上开发的存储库中检出,或者使用了将 CRLF 而不是 LF 的编辑器。

因此,简而言之,您可能希望重新提交所有这些文件,因为它们应该是 LF 格式的,但还要确保在 Windows 存储库中 autocrlf = true (注:始终设置为 true!),因为文档中如下所述:

如果您只是想在工作目录中具有 CRLF 行尾,而不管您正在使用哪个存储库,则可以设置配置变量“core.autocrlf”而不更改任何属性。

尽管上面的引用是针对特定存储库设置 autocrlf 和全局设置时使用的。

希望这对您有所帮助,如果不是,请随时提出更多问题!


这里有一个关于换行符的很好的SO帖子:为什么我应该在Git中使用core.autocrlf=true?


编辑

根据上面的答案,我们需要确保以下几点:

  • 你已经在你的.git/config中设置了相关的git选项
  • 如果你想保留CRLF行结束符,请设置autocrlf=true
  • 如果,在检出存储库时,你不想自动转换行结束符(导致所有文件立即处于"修改"状态),则将text选项设置为unset。如果全局git配置设置了一个你不想要的值,请添加此选项。
  • 如果你同时在Windows和Mac上开展项目,则最好使用text=auto并确保LF遍及全局。这就是为什么像这样的问题会出现的原因;因为你的git配置不同或因为Windows上的初始项目/git设置假定CRLF当你的Mac假定LF时。

你好!感谢您的回复。不幸的是,即使我们查看了文档链接,我们仍然无法解决这个问题。我更新了我的问题,并附上了 git config --list 输出和 .gitattributes 文件,如果您或其他人能找出问题所在... - Ville Mattila
谢谢Ville,我会根据更新的信息再仔细研究一下。 - Kieran Senior
3
对我来说问题在于.gitattributes里有* text=auto。移除它可以解决问题。如果你选择完全删除该文件,请确保暂存更改,否则您将无法确定它是否已解决问题。 - Omar
我认为在1.3.3.0版本的Sourcetree中存在一些错误。因为core.autocrfl的优先级高于.gitattributes。 - rofrol
@rofrol SourceTree只是调用Git,因此在这种情况下,应由Git确定优先级。 Git配置越本地,它在链中的优先级就越高,因此在本地.git / config中设置core.autocrlf可能会取代依赖于其位置的.gitattributes。 - Kieran Senior
@KieranSenior 所以看看这个:http://stackoverflow.com/questions/22833183/how-to-prevent-client-commiting-crlf-line-endings-without-changing-client-config - rofrol

11
我还没有完全理解,但对我们来说问题在于仓库中的 .gitattribute 文件中的 * text=auto。我检查了,在 Windows PC 上为我的用户设置了 core.autocrlf=true。我知道这不是 SourceTree 的问题,因为 TortoiseGit 和 Windows Git (msysgit) 都对该仓库具有相同的“问题”。这真是奇怪的行为 - 我会克隆一次仓库,立即看到 11 个“不同”的文件,然后我会删除并重新开始,下一个克隆将有 14 个“不同”的文件。
注释掉仓库中的 .gitattribute 文件中的 * text=auto 可以修复所有问题。这就像如果在 .gitattribute 文件中设置了 text=auto,那么它可能与 autocrlf=true 的行为不同,并且如果设置了前者,则禁用了后者。但这并不是在线指南所指示的。

1
注释掉文本=自动修复了我的问题。+1 奇怪。 - Cairo
也为我解决了问题 :o) - phuzi
我在Mac上,以下方法适用于我:创建一个名为**.gitattribute的文件,在其中写入* text=auto,并将其保存到与我的.gitconfig.gitignore_global**相同的目录中(很可能是您的用户根目录)。 - leymannx
我也试过了,谢谢。 - GEMI

1

我在配置文件中添加了以下两行。我还点击了“暂存文件”复选框,然后取消了它,所有内容都得到了刷新。祝好运。

text = auto 
autocrlf = true

当你回来发现自己的答案和解决方案时,这是一种讽刺。 - vr_driver

0
刚遇到这个问题。一个新克隆会拉取几个文件,这些文件不仅未提交,而且还有很多真正的新代码行。git reflog 没有显示任何信息,它也不是一个实际的提交,因此不能使用分离的HEAD。
经过大约一个小时的调查,我们找到了原因。我们的其中一位*nix开发人员可能错误地将文件添加到一个与目标文件夹同名但大小写不同的文件夹中。*nix环境可以轻松处理这个新文件夹,但由于Windows不区分大小写,它合并了这两个文件夹。
例如,如果您有两个文件夹,test和Test,每个文件夹里面都有一个file.txt文件,并且这两个file.txt文件不相同,那么Windows实际上会复制/替换其中一个文件(不确定克隆文件夹的顺序),从而“更改”文件并在新安装后直接在“Test/file.txt”上创建未提交的更改。
示例:
test/
--file.txt (with contents of "This is a commit")

Test/
--file.txt (with contents of "This is a commit with some changes")

当在 Windows 机器上克隆时,这将始终显示新的未提交更改,其中包括将“with some changes”添加到 Test/file.txt,而*nix基 ​​机器则不会有问题。

这并不一定解决 OP 的问题,但直接涉及标题中的问题。希望能帮助到某个人。


0

通常在 .gitattribute 文件中会有这样一行:

* text=auto

自动确保Git认为是文本的所有文件在存储库中都具有规范化(LF)行尾,即使设置了git config core.autocrlffalse(默认值)。因此,Git会根据这些规则自动更改文件。

因此,您有以下几种可能性:

  • 假设规范化更改是正确的(只要它们应用于文本文件),并简单地提交它们,例如:

    $ git diff
    $ git commit -m "引入行尾规范化" -a
    
  • .gitattribute文件中删除/禁用自动规范化,并重置文件,

  • 删除索引并重新扫描文件,例如:

    $ rm -v .git/index # 或:git rm --cached -r .
    $ git reset --hard # 重写Git索引。或:git add -u
    
  • 或者,无论您做什么,都要尝试使用强制选项(-f),例如:git pull origin -fgit checkout master -f等,

  • 使用git命令行,因为这可能是SourceTree应用程序本身的问题。
参见 GitHub 文档上的 处理行尾

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接