简介
在这个实验中,你将学习如何检查 Git 远程仓库是否有尚未同步到本地仓库的新提交。这是协作开发中的一项关键技能,能让你及时了解他人所做的更改。
我们将首先模拟一个远程仓库,并将其添加到本地项目中。然后,我们将使用 git fetch
命令来获取远程分支和提交的信息,而不进行合并操作。最后,我们将探讨如何将本地分支与其上游分支进行比较,以识别远程仓库上的任何新提交。
在这个实验中,你将学习如何检查 Git 远程仓库是否有尚未同步到本地仓库的新提交。这是协作开发中的一项关键技能,能让你及时了解他人所做的更改。
我们将首先模拟一个远程仓库,并将其添加到本地项目中。然后,我们将使用 git fetch
命令来获取远程分支和提交的信息,而不进行合并操作。最后,我们将探讨如何将本地分支与其上游分支进行比较,以识别远程仓库上的任何新提交。
git fetch
获取远程仓库更新在这一步中,你将学习如何从远程仓库获取更改。假设你正在和其他人一起进行一个项目,他们已经做了一些更新。你需要将这些更新同步到本地机器上。git fetch
命令就是用来完成这个任务的。它会从远程仓库下载最新的更改,但不会将这些更改合并到你当前的分支中。
首先,让我们模拟一个远程仓库。我们将创建一个裸仓库(bare repository),然后将其作为远程仓库添加到现有的 my-time-machine
仓库中。
cd ~/project
mkdir remote-repo.git
cd remote-repo.git
git init --bare
这将创建一个裸 Git 仓库,通常用作开发者进行推送和拉取操作的中央仓库。
现在,让我们回到 my-time-machine
仓库,并将这个裸仓库添加为远程仓库。
cd ~/project/my-time-machine
git remote add origin ~/project/remote-repo.git
我们将远程仓库命名为 origin
,这是一种常见的命名约定。现在,让我们验证一下远程仓库是否已正确添加。
git remote -v
你应该会看到类似以下的输出,显示 origin
远程仓库的获取(fetch)和推送(push)URL:
origin /home/labex/project/remote-repo.git (fetch)
origin /home/labex/project/remote-repo.git (push)
现在,让我们模拟远程仓库中的一个更改。由于这是一个裸仓库,我们不能直接在其中进行提交。相反,我们将通过在裸仓库的目录中创建一个新文件来模拟更改。
cd ~/project/remote-repo.git
echo "This is a remote change" > remote_file.txt
现在,回到你的 my-time-machine
仓库。
cd ~/project/my-time-machine
此时,你的本地仓库并不知道模拟远程仓库中添加了 remote_file.txt
文件。这就是 git fetch
发挥作用的地方。
运行 git fetch
命令:
git fetch origin
你可能看不到太多输出,或者可能会看到一些表明已接收新对象的信息。
git fetch origin
的作用是连接到 origin
远程仓库,并下载本地仓库中没有的任何新提交和对象。但是,它 不会 将这些更改合并到你当前的分支(master
)中。这些更改现在已经存在于你的本地仓库中,但它们被存储在一个跟踪远程仓库的特殊分支中,通常命名为 origin/master
。
这是 git fetch
和 git pull
之间的一个关键区别。git pull
本质上是先执行 git fetch
再执行合并操作。通过先使用 git fetch
,你可以在决定将远程更改集成到你的工作之前,查看远程仓库上有哪些更改。这让你拥有更多的控制权,并有助于避免意外的冲突。
在下一步中,我们将了解如何将本地分支与获取到的远程分支进行比较,以了解下载了哪些更改。
git log HEAD..@{u}
在上一步中,我们使用 git fetch
从远程仓库下载了更改。现在,让我们看看如何查看那些存在于远程仓库但尚未同步到本地分支的提交。这就是 git log HEAD..@{u}
命令发挥作用的地方。
确保你仍然处于 ~/project/my-time-machine
目录中。
cd ~/project/my-time-machine
现在,运行以下命令:
git log HEAD..@{u}
你可能会看到类似以下的输出:
commit abcdef1234567890abcdef1234567890abcdef (origin/master)
Author: Simulated User <[email protected]>
Date: Mon Aug 7 10:05:00 2023 +0000
Simulated remote commit
让我们来详细解析这个命令:
git log
:这是用于查看提交历史的命令。HEAD
:它指向当前分支所指向的提交。@{u}
:这是上游分支的简写。在我们的例子中,由于我们从 origin
拉取了更新,并且本地的 master
分支跟踪的是 origin/master
,所以 @{u}
指的就是 origin/master
。HEAD..@{u}
:这是 Git 中的范围表示法。它的意思是“显示那些可以从 @{u}
到达,但不能从 HEAD
到达的提交”。简单来说,它会显示存在于远程跟踪分支(origin/master
)但 不在 当前本地分支(master
)上的提交。这个命令对于查看如果将本地分支与远程跟踪分支进行合并或变基(rebase)操作时会引入哪些更改非常有帮助。它让你在集成这些更改之前能够先审查即将到来的更改,这是安全且可控的工作流程中至关重要的一部分。
你可能会疑惑:“Git 是如何知道模拟的远程提交的呢?”当我们在上一步运行 git fetch origin
时,Git 下载了 origin
仓库中提交的相关信息,包括引入 remote_file.txt
的那次提交。这些信息被存储在本地仓库的 origin/master
跟踪分支中。然后,git log HEAD..@{u}
命令会将本地的 master
分支(HEAD
)与这个 origin/master
跟踪分支(@{u}
)进行比较,从而显示出差异。
如果日志视图处于全屏模式,按 q
键退出。
理解本地分支和远程跟踪分支之间的差异是有效使用远程仓库的基础。这个命令为可视化这些差异提供了一种清晰的方式。
在前面的步骤中,我们从模拟的远程仓库获取了更改,并学习了如何使用 git log HEAD..@{u}
查看那些存在于远程仓库但尚未同步到本地分支的提交。现在,让我们看看当本地分支与远程跟踪分支保持最新状态时会发生什么。
首先,让我们模拟将远程更改合并到本地分支的过程。git fetch
仅下载更改,而 git pull
则是下载并合并更改。为了进行本次测试,我们将通过手动更新本地分支以匹配远程跟踪分支的方式,模拟拉取操作后的状态。
确保你处于 ~/project/my-time-machine
目录中。
cd ~/project/my-time-machine
现在,让我们通过将本地的 master
分支重置为与 origin/master
相同的提交来模拟合并操作。注意:在实际场景中,你通常会使用 git merge origin/master
或 git pull origin master
来集成更改。我们在这里使用 git reset --hard
纯粹是为了演示目的,以便快速让本地分支与远程跟踪分支同步,从而进行测试。
git reset --hard origin/master
你应该会看到输出信息,表明你的分支已更新,并且工作区是干净的。
HEAD is now at abcdef1 Simulated remote commit
现在,我们的本地 master
分支已经与 origin/master
同步,让我们再次运行 git log HEAD..@{u}
命令。
git log HEAD..@{u}
这次,你应该看不到任何输出。
为什么没有输出呢?因为 HEAD
(我们的本地 master
分支)和 @{u}
(origin/master
跟踪分支)现在指向同一个提交。HEAD..@{u}
这个范围为空,因为不存在可以从 @{u}
到达但不能从 HEAD
到达的提交。
当你的本地分支与上游远程跟踪分支完全同步时,这就是预期的行为。git log HEAD..@{u}
命令是一种快速检查远程仓库中是否有尚未集成到本地的更改的方法。如果该命令没有输出,就意味着你的本地分支与远程跟踪分支是最新的。
了解如何检查即将到来的更改以及如何解读 git log HEAD..@{u}
命令的输出,对于与他人协作以及保持本地仓库与远程仓库同步至关重要。
在本次实验中,我们学习了如何检查 Git 远程仓库是否有新的提交。首先,我们了解了 git fetch
的用途,它可以从远程仓库下载更改,但不会进行合并操作。我们通过创建一个裸 Git 仓库并将其作为名为 origin
的远程仓库添加到本地的 my-time-machine
仓库中,模拟了一个远程仓库。我们使用 git remote -v
验证了远程仓库的设置。
接下来,我们通过直接在裸仓库的目录中创建一个文件,模拟了远程仓库中的更改。然后,我们使用 git fetch origin
命令将这些更改获取到本地仓库,为检查新提交做好准备。