当上游存在更改时,为什么 git 状态显示分支是最新的?
Why does git status show branch is up-to-date when changes exist upstream?
更改存在于跟踪分支的上游,但是当我键入 git status
时,它表明我的本地分支是最新的。这是新行为,我是否更改了配置设置,还是出了什么问题?
感谢您的帮助。
ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
1234567..abcdefg master -> origin/master
Updating 1234567..abcdefg
Fast-forward
file1 | 1 -
file2 | 43 +++++++++++++++++++++++++++++++++++++++++++
file3 | 21 ++++++++++++---------
file4 | 21 ++++++++++++---------
4 files changed, 67 insertions(+), 19 deletions(-)
create mode 100644 file5
这是因为您的本地存储库尚未与上游遥控器签入。要让这项工作如您所愿,请再次使用 git fetch
然后 运行 a git status
。
状态告诉您的是,您在名为 origin/master
的引用后面,它是您本地存储库中的本地引用 。在这种情况下,ref 恰好跟踪某个远程分支中的分支,称为 origin
,但状态不会告诉您有关远程分支的任何信息。它告诉您有关 ref 的信息,它只是存储在本地文件系统上的提交 ID(在这种情况下,它通常位于本地存储库中名为 .git/refs/remotes/origin/master
的文件中)。
git pull
做了两个操作;首先它执行 git fetch
来更新远程仓库中的提交(更新本地仓库中的 origin/master
ref),然后它执行 git merge
合并这些提交进入当前分支。
直到你执行 fetch
步骤(无论是自己还是通过 git pull
)你的本地仓库无法知道上游还有额外的提交,并且只有 git status
看看你当地的 origin/master
ref.
当 git status
表示最新时,它表示 "up-to-date with the branch that the current branch tracks",在这种情况下表示 "up-to-date with the local ref called origin/master
"。这仅等于 "up-to-date with the upstream status that was retrieved last time we did a fetch
" 与 "up-to-date with the latest live status of the upstream".
不同
为什么会这样?那么 fetch
步骤可能是一个缓慢且昂贵的网络操作。 Git(和其他 distributed version control systems)的设计是为了避免在不必要时进行网络操作,并且与许多人习惯的典型客户端-服务器系统完全不同(尽管如在下面的评论中,Git 的 "remote tracking branch" 概念在这里引起混淆,并非所有 DVCS 都共享)。完全可以离线使用 Git,无需连接到中央服务器,git status
的输出反映了这一点。
在 Git 中创建和切换分支(并检查它们的状态)应该是轻量级的,而不是对集中式系统执行缓慢的网络操作。设计 Git 和 git status
输出时的假设是用户理解这一点(如果您已经知道 Git 是如何工作的,那么太多 Git 功能才有意义)。随着许多不熟悉 DVCS 的用户采用 Git,此假设并不总是有效。
"origin/master"指的是指向分支"origin/master"的HEAD提交的引用。
引用是 Git 对象的人性化别名,通常是提交对象。
"origin/master" 参考仅在您 git push
到您的遥控器 (http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes) 时更新。
从项目的根目录中,运行:
cat .git/refs/remotes/origin/master
将显示的提交 ID 与:
进行比较
cat .git/refs/heads/master
它们应该是相同的,这就是为什么 Git 说 master
是最新的 origin/master
。
当你运行
git fetch origin master
这会在 .git/objects 文件夹下本地检索新的 Git 对象。
Git 更新 .git/FETCH_HEAD 现在,它指向获取分支的最新提交。
因此,要查看当前本地分支与从上游获取的分支之间的差异,您可以 运行
git diff HEAD FETCH_HEAD
让我们查看示例 git 存储库以验证 your branch (master)
是否为 up to date
和 origin/master
。
验证本地主控正在跟踪origin/master:
$ git branch -vv
* master a357df1eb [origin/master] This is a commit message
关于本地 master 分支的更多信息:
$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date: Tue Dec 11 14:25:52 2018 +0100
Another commit message
验证 origin/master 是否在同一提交上:
$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master
我们可以看到相同的散列,可以肯定地说分支与远程分支是一致的,至少在当前 git 存储库中是这样。
虽然这些都是可行的答案,但我决定给出我的方法来检查本地存储库是否与远程存储库一致,而无需获取或拉取。为了查看我的分支在哪里,我简单地使用:
git remote show origin
它的作用是 return 所有当前跟踪的分支,最重要的是 - 它们是最新的、领先于或落后于远程原始分支的信息。在上面的命令之后,这是 returned:
的一个例子
* remote origin
Fetch URL: https://github.com/xxxx/xxxx.git
Push URL: https://github.com/xxxx/xxxx.git
HEAD branch: master
Remote branches:
master tracked
no-payments tracked
Local branches configured for 'git pull':
master merges with remote master
no-payments merges with remote no-payments
Local refs configured for 'git push':
master pushes to master (local out of date)
no-payments pushes to no-payments (local out of date)
希望这对某人有所帮助。
一些琐碎的答案在某些情况下却很准确,比如把我带到这里的那个。
我在一个对我来说是新的回购协议中工作,我添加了一个文件,该文件在状态上并不被视为新文件。
最终文件与 .gitignore 文件中的模式匹配。
在这种情况下使用 git 添加并整合所有未决文件然后使用 git commit 然后 git push
git 添加 - 整合所有 pedent 文件
git 提交 - 保存提交
git 推 -
保存到存储库
我遇到过类似的问题,我在网上到处搜索解决方案,并尝试遵循它们。 None 对我有用。这些是我解决问题的步骤。
创建新的 repo 并将现有代码再次推送到新的 repo
git 如果您的存储库中已有 .git/ 文件夹,则 init 不会初始化。所以,对于你的情况,做 -
(1) rm -rf .git/
(2) git 初始化
(3) git 远程添加源 https://repository.remote.url
(4) git commit -m “提交消息”
(5) git push -f origin master
请注意,此存储库的所有 git 配置(如远程存储库)已在步骤 1 中清除。因此,您必须重新设置所有远程存储库 URL。
另外,注意第 5 步中的 -f:远程已经有一些包含 n 次提交的代码库,而您正试图将所有这些更改合并到一次提交中。因此,force-pushing 需要对远程进行更改。
更改存在于跟踪分支的上游,但是当我键入 git status
时,它表明我的本地分支是最新的。这是新行为,我是否更改了配置设置,还是出了什么问题?
感谢您的帮助。
ubuntu@host:/my/repo# git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
ubuntu@host:/my/repo# git pull
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 6), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From bitbucket.org:my/repo
1234567..abcdefg master -> origin/master
Updating 1234567..abcdefg
Fast-forward
file1 | 1 -
file2 | 43 +++++++++++++++++++++++++++++++++++++++++++
file3 | 21 ++++++++++++---------
file4 | 21 ++++++++++++---------
4 files changed, 67 insertions(+), 19 deletions(-)
create mode 100644 file5
这是因为您的本地存储库尚未与上游遥控器签入。要让这项工作如您所愿,请再次使用 git fetch
然后 运行 a git status
。
状态告诉您的是,您在名为 origin/master
的引用后面,它是您本地存储库中的本地引用 。在这种情况下,ref 恰好跟踪某个远程分支中的分支,称为 origin
,但状态不会告诉您有关远程分支的任何信息。它告诉您有关 ref 的信息,它只是存储在本地文件系统上的提交 ID(在这种情况下,它通常位于本地存储库中名为 .git/refs/remotes/origin/master
的文件中)。
git pull
做了两个操作;首先它执行 git fetch
来更新远程仓库中的提交(更新本地仓库中的 origin/master
ref),然后它执行 git merge
合并这些提交进入当前分支。
直到你执行 fetch
步骤(无论是自己还是通过 git pull
)你的本地仓库无法知道上游还有额外的提交,并且只有 git status
看看你当地的 origin/master
ref.
当 git status
表示最新时,它表示 "up-to-date with the branch that the current branch tracks",在这种情况下表示 "up-to-date with the local ref called origin/master
"。这仅等于 "up-to-date with the upstream status that was retrieved last time we did a fetch
" 与 "up-to-date with the latest live status of the upstream".
为什么会这样?那么 fetch
步骤可能是一个缓慢且昂贵的网络操作。 Git(和其他 distributed version control systems)的设计是为了避免在不必要时进行网络操作,并且与许多人习惯的典型客户端-服务器系统完全不同(尽管如在下面的评论中,Git 的 "remote tracking branch" 概念在这里引起混淆,并非所有 DVCS 都共享)。完全可以离线使用 Git,无需连接到中央服务器,git status
的输出反映了这一点。
在 Git 中创建和切换分支(并检查它们的状态)应该是轻量级的,而不是对集中式系统执行缓慢的网络操作。设计 Git 和 git status
输出时的假设是用户理解这一点(如果您已经知道 Git 是如何工作的,那么太多 Git 功能才有意义)。随着许多不熟悉 DVCS 的用户采用 Git,此假设并不总是有效。
"origin/master"指的是指向分支"origin/master"的HEAD提交的引用。
引用是 Git 对象的人性化别名,通常是提交对象。
"origin/master" 参考仅在您 git push
到您的遥控器 (http://git-scm.com/book/en/v2/Git-Internals-Git-References#Remotes) 时更新。
从项目的根目录中,运行:
cat .git/refs/remotes/origin/master
将显示的提交 ID 与:
进行比较cat .git/refs/heads/master
它们应该是相同的,这就是为什么 Git 说 master
是最新的 origin/master
。
当你运行
git fetch origin master
这会在 .git/objects 文件夹下本地检索新的 Git 对象。 Git 更新 .git/FETCH_HEAD 现在,它指向获取分支的最新提交。
因此,要查看当前本地分支与从上游获取的分支之间的差异,您可以 运行
git diff HEAD FETCH_HEAD
让我们查看示例 git 存储库以验证 your branch (master)
是否为 up to date
和 origin/master
。
验证本地主控正在跟踪origin/master:
$ git branch -vv
* master a357df1eb [origin/master] This is a commit message
关于本地 master 分支的更多信息:
$ git show --summary
commit a357df1eb941beb5cac3601153f063dae7faf5a8 (HEAD -> master, tag: 2.8.0, origin/master, origin/HEAD)
Author: ...
Date: Tue Dec 11 14:25:52 2018 +0100
Another commit message
验证 origin/master 是否在同一提交上:
$ cat .git/packed-refs | grep origin/master
a357df1eb941beb5cac3601153f063dae7faf5a8 refs/remotes/origin/master
我们可以看到相同的散列,可以肯定地说分支与远程分支是一致的,至少在当前 git 存储库中是这样。
虽然这些都是可行的答案,但我决定给出我的方法来检查本地存储库是否与远程存储库一致,而无需获取或拉取。为了查看我的分支在哪里,我简单地使用:
git remote show origin
它的作用是 return 所有当前跟踪的分支,最重要的是 - 它们是最新的、领先于或落后于远程原始分支的信息。在上面的命令之后,这是 returned:
的一个例子 * remote origin
Fetch URL: https://github.com/xxxx/xxxx.git
Push URL: https://github.com/xxxx/xxxx.git
HEAD branch: master
Remote branches:
master tracked
no-payments tracked
Local branches configured for 'git pull':
master merges with remote master
no-payments merges with remote no-payments
Local refs configured for 'git push':
master pushes to master (local out of date)
no-payments pushes to no-payments (local out of date)
希望这对某人有所帮助。
一些琐碎的答案在某些情况下却很准确,比如把我带到这里的那个。 我在一个对我来说是新的回购协议中工作,我添加了一个文件,该文件在状态上并不被视为新文件。
最终文件与 .gitignore 文件中的模式匹配。
在这种情况下使用 git 添加并整合所有未决文件然后使用 git commit 然后 git push
git 添加 - 整合所有 pedent 文件
git 提交 - 保存提交
git 推 - 保存到存储库
我遇到过类似的问题,我在网上到处搜索解决方案,并尝试遵循它们。 None 对我有用。这些是我解决问题的步骤。
创建新的 repo 并将现有代码再次推送到新的 repo
git 如果您的存储库中已有 .git/ 文件夹,则 init 不会初始化。所以,对于你的情况,做 -
(1) rm -rf .git/
(2) git 初始化
(3) git 远程添加源 https://repository.remote.url
(4) git commit -m “提交消息”
(5) git push -f origin master
请注意,此存储库的所有 git 配置(如远程存储库)已在步骤 1 中清除。因此,您必须重新设置所有远程存储库 URL。
另外,注意第 5 步中的 -f:远程已经有一些包含 n 次提交的代码库,而您正试图将所有这些更改合并到一次提交中。因此,force-pushing 需要对远程进行更改。