在Windows的Bash和Windows命令行中,Git的情况有所不同。

6
我在系统中有一个git仓库。 当我在windows PowerShell中输入git status时,会得到一个结果;而当我在windows bash中输入时,则会得到另一个结果。 更多详情请见图片。

enter image description here

如您所见,在Windows PowerShell中,git status显示Nothing to commit,而在Windows Bash中,相同的git status显示您有未暂存的更改。

以下是两种操作下git version的输出结果:
Windows Powershell: git version 2.18.0.windows.1
Windows Bash: git version 2.7.4

这里是一个git diff .idea/gradle.xml的输出结果:
Powershell:
Bash:

diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 7ac24c7..15dda04 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,18 +1,18 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="GradleSettings">
-    <option name="linkedExternalProjectsSettings">
-      <GradleProjectSettings>
-        <option name="distributionType" value="DEFAULT_WRAPPED" />
-        <option name="externalProjectPath" value="$PROJECT_DIR$" />
-        <option name="modules">
-          <set>
-            <option value="$PROJECT_DIR$" />
-            <option value="$PROJECT_DIR$/app" />
-          </set>
-        </option>
-        <option name="resolveModulePerSourceSet" value="false" />
-      </GradleProjectSettings>
-    </option>
-  </component>
+<?xml version="1.0" encoding="UTF-8"?>^M
+<project version="4">^M
+  <component name="GradleSettings">^M
+    <option name="linkedExternalProjectsSettings">^M
+      <GradleProjectSettings>^M
+        <option name="distributionType" value="DEFAULT_WRAPPED" />^M
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />^M
+        <option name="modules">^M
+          <set>^M
+            <option value="$PROJECT_DIR$" />^M
+            <option value="$PROJECT_DIR$/app" />^M
+          </set>^M
+        </option>^M
+        <option name="resolveModulePerSourceSet" value="false" />^M
+      </GradleProjectSettings>^M
+    </option>^M
+  </component>^M
 </project>
\ No newline at end of file
:
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 7ac24c7..15dda04 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,18 +1,18 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="GradleSettings">
-    <option name="linkedExternalProjectsSettings">
-      <GradleProjectSettings>
-        <option name="distributionType" value="DEFAULT_WRAPPED" />
-        <option name="externalProjectPath" value="$PROJECT_DIR$" />
-        <option name="modules">
-          <set>
-            <option value="$PROJECT_DIR$" />
-            <option value="$PROJECT_DIR$/app" />
-          </set>
-        </option>
-        <option name="resolveModulePerSourceSet" value="false" />
-      </GradleProjectSettings>
-    </option>
-  </component>
+<?xml version="1.0" encoding="UTF-8"?>^M
+<project version="4">^M
+  <component name="GradleSettings">^M
+    <option name="linkedExternalProjectsSettings">^M
+      <GradleProjectSettings>^M
+        <option name="distributionType" value="DEFAULT_WRAPPED" />^M
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />^M
+        <option name="modules">^M
+          <set>^M
+            <option value="$PROJECT_DIR$" />^M
+            <option value="$PROJECT_DIR$/app" />^M
+          </set>^M
+        </option>^M
+        <option name="resolveModulePerSourceSet" value="false" />^M
+      </GradleProjectSettings>^M
+    </option>^M
+  </component>^M
 </project>
\ No newline at end of file
:...skipping...
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 7ac24c7..15dda04 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,18 +1,18 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="GradleSettings">
-    <option name="linkedExternalProjectsSettings">
-      <GradleProjectSettings>
-        <option name="distributionType" value="DEFAULT_WRAPPED" />
-        <option name="externalProjectPath" value="$PROJECT_DIR$" />
-        <option name="modules">
-          <set>
-            <option value="$PROJECT_DIR$" />
-            <option value="$PROJECT_DIR$/app" />
-          </set>
-        </option>
-        <option name="resolveModulePerSourceSet" value="false" />
-      </GradleProjectSettings>
-    </option>
-  </component>
+<?xml version="1.0" encoding="UTF-8"?>^M
+<project version="4">^M
+  <component name="GradleSettings">^M
+    <option name="linkedExternalProjectsSettings">^M
+      <GradleProjectSettings>^M
+        <option name="distributionType" value="DEFAULT_WRAPPED" />^M
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />^M
+        <option name="modules">^M
+          <set>^M
+            <option value="$PROJECT_DIR$" />^M
+            <option value="$PROJECT_DIR$/app" />^M
+          </set>^M
+        </option>^M
+        <option name="resolveModulePerSourceSet" value="false" />^M
+      </GradleProjectSettings>^M
+    </option>^M
+  </component>^M
 </project>
\ No newline at end of file
~

我可以看到这完全不同。

这是 git config -l 命令的输出结果:Powershell

core.symlinks=true
core.autocrlf=true
core.fscache=true
color.diff=auto
color.status=auto
color.branch=auto
color.interactive=true
help.format=html
rebase.autosquash=true
http.sslcainfo=D:/Apps/Git/mingw64/ssl/certs/ca-bundle.crt
http.sslbackend=openssl
diff.astextplain.textconv=astextplain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
credential.helper=manager
user.name=Mahdi
user.email=mahdi.malvandi@pushe.co
core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
remote.origin.url=git@github.com:mahdi-malv/shahpari_market.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
branch.setMainActivity.remote=origin
branch.setMainActivity.merge=refs/heads/setMainActivity
branch.networkSetup.remote=origin
branch.networkSetup.merge=refs/heads/networkSetup
branch.compNav.remote=origin
branch.compNav.merge=refs/heads/compNav
branch.presenter.remote=origin
branch.presenter.merge=refs/heads/presenter
branch.mainUi.remote=origin
branch.mainUi.merge=refs/heads/mainUi
branch.downloadManager.remote=origin
branch.downloadManager.merge=refs/heads/downloadManager
branch.category.remote=origin
branch.category.merge=refs/heads/category
:

Bash

core.repositoryformatversion=0
core.filemode=false
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
remote.origin.url=git@github.com:mahdi-malv/shahpari_market.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
branch.setMainActivity.remote=origin
branch.setMainActivity.merge=refs/heads/setMainActivity
branch.networkSetup.remote=origin
branch.networkSetup.merge=refs/heads/networkSetup
branch.compNav.remote=origin
branch.compNav.merge=refs/heads/compNav
branch.presenter.remote=origin
branch.presenter.merge=refs/heads/presenter
branch.mainUi.remote=origin
branch.mainUi.merge=refs/heads/mainUi
branch.downloadManager.remote=origin
branch.downloadManager.merge=refs/heads/downloadManager
branch.category.remote=origin
branch.category.merge=refs/heads/category
branch.setCategory.remote=origin
branch.setCategory.merge=refs/heads/setCategory
branch.searchFix.remote=origin
branch.searchFix.merge=refs/heads/searchFix
branch.homeMoreAPI.remote=origin
branch.homeMoreAPI.merge=refs/heads/homeMoreAPI
branch.userApp.remote=origin
branch.userApp.merge=refs/heads/userApp
branch.allApps.remote=origin
branch.allApps.merge=refs/heads/allApps
branch.settings.remote=origin
branch.settings.merge=refs/heads/settings
branch.autoUpdate.remote=origin
branch.autoUpdate.merge=refs/heads/autoUpdate
branch.tempStore.remote=origin
branch.tempStore.merge=refs/heads/tempStore
branch.fixIcon.remote=origin
branch.fixIcon.merge=refs/heads/fixIcon
branch.changeAd.remote=origin
branch.changeAd.merge=refs/heads/changeAd
branch.updateAndAnal.remote=origin
branch.updateAndAnal.merge=refs/heads/updateAndAnal
branch.merge1.remote=origin
branch.merge1.merge=refs/heads/merge1
branch.fixV1beta.remote=origin
branch.fixV1beta.merge=refs/heads/fixV1beta
branch.sendDevice.remote=origin
branch.sendDevice.merge=refs/heads/sendDevice
branch.newIcon.remote=origin
branch.newIcon.merge=refs/heads/newIcon

这个问题是由什么引起的,我该如何解决?
提前致谢。
注意: 除了接受的答案外,考虑Ralf的答案,我发现让两个shell使用一个git是一个好主意。 - 使用sudo apt remove git从bash中删除Git。 - 在bash的$PATH中添加git.exe的路径。 - 为了简单起见,使用alias git='git.exe'可以像以前一样使用Git。 您可以对其他可能遇到此问题的内容(例如Python等)执行此操作。

我曾经在使用“Git for Windows”和“Cygwin中的Git”时遇到过这个问题。我猜测问题出在两个二进制文件如何看待文件的执行标志上。git diff .idea/gradle.xml的输出是什么?此外,对于两个环境,git version的输出是什么?你能把两者的输出都添加到原始问题中吗? - eftshift0
@TimBiegeleisen 什么?git versiongit diff .idea/gradle.xml?在哪里? - eftshift0
哦...没有看到diff在里面,是的,也很好看到。 - Tim Biegeleisen
@eftshift0 很有趣。对于Windows,git version返回:git version 2.18.0.windows.1。而对于Windows Bash,它将是git version 2.7.4 - Mahdi-Malv
差异是怎么样的?我敢打赌问题与文件的+x标志有关(尽管可能与配置相关,例如一个git正在使用auto.crlf而另一个则没有?各种疯狂的事情都可能发生)。也许检查git config -l对于两者都可以有所帮助。 - eftshift0
显示剩余14条评论
3个回答

2

除了有两个不同版本的Git之外,您还应该使用以下命令检查两个会话中的配置:

git config --list

这将列出当前会话中所有的Git配置。

注:Original Answer翻译成"最初的回答"

git config -l --show-origin

这可能不仅展示不同的配置,还包括不同的配置文件(例如当HOME在两者之间不同时,或者系统配置在不同的Git安装之间不同时)。
在您的设置中,第二个设置中存在 core.autocrlf=true 解释了 git diff 输出。 请确保在两个shell中键入:git config --global core.autocrlf false
无论如何,请尝试使用简化的PATH(使用PortableGit-2.20.1-64-bit.7z.exe Git未压缩到任何位置),然后在该CMD中调用 git bash 以使用该简化的PATH:结果应该相同。
set PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\
set GH=C:\path\to\git
set PATH=%GH%\bin;%GH%\usr\bin;%GH%\mingw64\bin;%PATH%

这些文件已经被跟踪,所以不是关于Git忽略它们的问题。 - eftshift0

2
简而言之:core.autocrlf在两个环境中是不同的,这就解释了为什么在powershell上它告诉你文件是完全不同的(删除所有内容并再次添加相同的内容...因为它改变了这些行的EOL)。避免这种情况发生的方法是在.gitattributes中使用* -text。如果通过这样做问题仍然存在,那么可能是文件已经在工作树上更改了EOL格式。尝试将其切换回HEAD上的内容,那么文件应该从git状态中消失。

通过比较 git diff 命令的现有输出和更改后的输出,您会发现唯一的区别是 ^M。因此,通过使用 .gitattributes* -text 忽略它,问题得到了解决。 - Mahdi-Malv
而且一开始也没起作用,因为它已经被修改过了。所以回到HEAD有帮助。感谢您的帮助。 - Mahdi-Malv

2
尽管被接受的答案展示了如何解决这个问题,但我想给出另一个建议:要么使用PowerShell上的git,要么使用Bash上的git。在管理同一工作副本时不要混用。
更新:
使用PowerShell上的git和其他基于Windows的git工具(您在评论中提到了gitKraken和Android Studio)是可以的(很可能)。
我的理解是bash和Bash上的git来自Windows子系统Linux。因此它们将假定不同的EOL样式。

我使用 gitKraken 和有时候用 Android Studio 的 git。我猜他们使用的是 Windows 版本的 Git。所以如果我在 bash 中使用 git,那将会是混合使用。更新两个 Git 或使用便携式 Git 应该可以解决问题,对吗? - Mahdi-Malv
@Malv 我不知道。 - Ralf

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