git 拉 <link-to-remote> 有什么作用?
What does git pull <link-to-remote> do?
我工作中的一个新 git 用户错误地 运行 命令
git pull https://github.com/our-repo.git
他们的意思是:
git clone https://github.com/our-repo.git
或至少
git remote add origin https://github.com/our-repo.git
git pull origin master
然而 git pull https://github.com/our-repo.git
似乎引入了一些代码,但显然它并没有创建 origin
或任何 b运行ches。
git pull <url-to-remote>
究竟会做什么?
pull 命令用于在一个 git fetch 之后进行 git merge单个命令。
fetch 命令从远程存储库导入信息。导入是通过特殊分支完成的,以便我们进行比较。
git 合并。将分支与当前分支合并
感谢提问。
假设您已经拥有存储库的克隆副本,并且有许多开发人员在处理该存储库,并且最近在远程存储库中合并了一个拉取请求,现在远程存储库比 forked/local 存储库。
现在要保持 local/forked repo 即使与远程存储库我们必须 git pull
远程然后 git push
保持本地和分叉甚至与远程存储库。
更多详细信息,请看这里:https://git-scm.com/docs/git-pull
TL;DR
由于您的 Git 对命名遥控器一无所知,Git 只是询问另一个 Git 它推荐什么——具体来说,它的 HEAD 是什么。您的 Git 然后将其用于提取和合并步骤。
换句话说,这相当于:
git pull <url> HEAD
这还有一些奇怪的地方需要解释。
长
正如到目前为止其他两个回答者所说,git pull
只是 运行s git fetch
后跟第二个 Git 命令,通常是 git merge
。棘手的部分在于 如何 git pull
运行 这两个命令,以及它们随后执行的操作。
如果在命令行输入:
git pull abc bra
然后 abc
部分被视为 远程或存储库 ,bra
部分被视为 refspec。 Git 然后 运行s:
git fetch abc bra
如果您从 git pull
命令中省略 bra
部分(refspec),Git 只需 运行s:
git fetch abc
即,它也省略了 fetch
步骤中的 refspecs。 (请注意,在 remote-or-repository 之后的 every 非选项参数是一个 refspec,但在命令行中放置多个参数通常是不明智的。)
如果省略两个名字,git pull
将运行git fetch
和两个远程 或 refspec 参数。所以现在我们需要看看 git fetch
对其 remote-or-repository 和 refspec,参数做了什么。
git fetch
获取的内容
你——或者你的 git pull
——将 运行 git fetch
具有:
- 没有命名的远程或存储库,也没有引用规范;或者
- 一个名为 remote-or-repository 且没有 refspecs;或者
- 一个名为 remote-or-repository 和一个或多个 refspecs。
在第一种情况下,git fetch
根据您当前的分支找出要使用的遥控器(它 运行 相当于 git 配置 -- get branch.<em>branch</em>.remote
),或者如果失败,假设 origin
。在第二种或第三种情况下,你可以给它一个像origin
这样的远程名称,或者你可以给它一个像https://github.com/our-repo.git
这样的URL。由于第一种情况转化为第二种情况,我们这里只需要担心这两种情况。
如果您使用 命名的遥控器 ,例如 origin
,您的 Git 查找 remote.origin.url
以获得 URL,还有 remote.origin.fetch
。通常 remote.origin.fetch
设置为:
+refs/heads/*:refs/remotes/origin/*
因此,当您 运行 git fetch origin
时,您的 Git 获取 所有 其他 Git 提供的分支,转向他们变成远程跟踪名称。当您 运行 git fetch origin bra
时,您的 Git 只获取获取 bra
所需的任何内容(我在这里假设 bra
是一个分支名称)。如果您的 Git 至少是 1.8.4,它仍然会进行相同的重命名,因此也会更新 refs/remotes/origin/bra
。
当你给你的 Git 一个原始的 URL 时,它可能找不到 remote.https://github.com/our-repo.git.fetch
配置(它甚至可能不会尝试查找,但如果它确实如此,它不会找到任何东西)。它仍然知道要联系什么URL,所以它联系那里的Git;但它没有特定的 fetch =
指令。如果您给 git fetch
一个分支名称,您的 Git 将向他们的 Git 询问该分支。但你也没有这样做——所以你的Git只是问他们的Git:嘿,其他Git,你设置了什么HEAD
?
所以你什么都不说,他们的 Git 给你一个散列 ID 和 他们的 HEAD
,你的 Git 写这到 .git/FETCH_HEAD
。或者,你说 "give me your branch bra
",他们的 Git 给你一个哈希 ID 和他们的 refs/heads/bra
,然后你的 Git 把它写到 .git/FETCH_HEAD
。在任何一种情况下,任何远程跟踪名称都不会发生任何变化。没有命名的远程名称,因此无法更新正确的远程跟踪名称。
尽管如此,您的 Git 总是将它获取的所有内容写入 .git/FETCH_HEAD
, 无论是否更新 origin/master
或 origin/develop
这样的名称。这在一定程度上是一个古老的向后兼容性问题——除了 git pull
仍在使用它,我们稍后会看到。
git merge
运行 由 git pull
合并的内容
此步骤在几个方面比提取步骤简单,但仍然非常棘手。当git pull
运行s git merge
时,它预先设置了一些选项和参数:
-m
: git pull
始终提供初始合并消息。这不是一个非常 好的 合并消息,但它确实提供了一个。 (默认情况下,如果涉及实际合并,它会让您编辑此合并消息。)
- 来自
git pull
的其他选项:如果您使用 --ff
或 --no-ff
或 --ff-only
,或 -s strategy
,或 [=] 中列出的各种其他选项91=], git pull
将它们传递给 git merge
.
- 一个或多个原始提交 ID。
git fetch
在 .git/FETCH_HEAD
中留下踪迹后,git pull
代码读取整个文件。在该文件中,Git 记录了它获取的每个分支提示提交。在某些情况下,只有一个这样的提交。 (例如,对于这种获取 HEAD
的情况就是如此。)在其他情况下——none 适用于这种特殊情况,但为了完整性我们应该记住它们——它列出了更多;但它标记了其中的大多数 not-for-merge
。它 没有 标记的是那些与您在命令行中提供的 refspec 名称相对应的名称,例如 bra
,或者 - 如果您没有命名在命令行上——来自 branch.<em>branch</em>.merge
的那个,如果你从一个命名的 remote.
无论如何,git pull
提取任何 git fetch
没有 标记为 "not for merge" 的内容。理想情况下,这只是一个提交哈希,否则您的 git pull
将调用 git merge
以进行 octopus 合并 。这很少是你想要的——如果你不知道它是什么,你肯定不想要它!——所以如果只涉及一个哈希 ID(就像这里的情况),你会更开心。
此时,git merge
会根据选项和参数执行它一贯执行的操作。 Git 从当前提交(您自己的存储库的 HEAD
)和参数提交计算合并基础。如果合并基础与其他(单个)提交相同,则没有要合并的内容:Git 如此说但什么也不做。如果合并基础是 HEAD
,则可以进行快进非真正合并; Git 如果您没有禁止它,就会执行此操作。否则,需要真正的合并,如果您没有禁止它,Git 会这样做。
完成后,无法完成(在中间停下来获得用户的帮助),或者甚至不尝试合并,git merge
退出,现在 git pull
完成.
结论
通过 运行宁 git pull
与 URL,您已要求另一个 Git 将其 HEAD
发送给您(可能 master
) 提交,加上任何其他所需的提交,然后将该提交合并到您当前的分支中,无论您当前的分支是什么。通过使用 URL 而不是 origin
,您已经禁用了自己的 Git 对 origin/master
或任何其他 origin/*
名称的更新。因此,如果需要合并或快进以引入他们的 HEAD
,并且没有被禁止,那么它要么现在完成,要么处于失败合并的半完成状态。
的缩写
git pull <URL> HEAD
可以通过
找到HEAD所在的位置
cat .git/FETCH_HEAD
示例:
cat .git/FETCH_HEAD
b521bea1b4b336864462e
我工作中的一个新 git 用户错误地 运行 命令
git pull https://github.com/our-repo.git
他们的意思是:
git clone https://github.com/our-repo.git
或至少
git remote add origin https://github.com/our-repo.git
git pull origin master
然而 git pull https://github.com/our-repo.git
似乎引入了一些代码,但显然它并没有创建 origin
或任何 b运行ches。
git pull <url-to-remote>
究竟会做什么?
pull 命令用于在一个 git fetch 之后进行 git merge单个命令。
fetch 命令从远程存储库导入信息。导入是通过特殊分支完成的,以便我们进行比较。
git 合并。将分支与当前分支合并
感谢提问。
假设您已经拥有存储库的克隆副本,并且有许多开发人员在处理该存储库,并且最近在远程存储库中合并了一个拉取请求,现在远程存储库比 forked/local 存储库。
现在要保持 local/forked repo 即使与远程存储库我们必须 git pull
远程然后 git push
保持本地和分叉甚至与远程存储库。
更多详细信息,请看这里:https://git-scm.com/docs/git-pull
TL;DR
由于您的 Git 对命名遥控器一无所知,Git 只是询问另一个 Git 它推荐什么——具体来说,它的 HEAD 是什么。您的 Git 然后将其用于提取和合并步骤。
换句话说,这相当于:
git pull <url> HEAD
这还有一些奇怪的地方需要解释。
长
正如到目前为止其他两个回答者所说,git pull
只是 运行s git fetch
后跟第二个 Git 命令,通常是 git merge
。棘手的部分在于 如何 git pull
运行 这两个命令,以及它们随后执行的操作。
如果在命令行输入:
git pull abc bra
然后 abc
部分被视为 远程或存储库 ,bra
部分被视为 refspec。 Git 然后 运行s:
git fetch abc bra
如果您从 git pull
命令中省略 bra
部分(refspec),Git 只需 运行s:
git fetch abc
即,它也省略了 fetch
步骤中的 refspecs。 (请注意,在 remote-or-repository 之后的 every 非选项参数是一个 refspec,但在命令行中放置多个参数通常是不明智的。)
如果省略两个名字,git pull
将运行git fetch
和两个远程 或 refspec 参数。所以现在我们需要看看 git fetch
对其 remote-or-repository 和 refspec,参数做了什么。
git fetch
获取的内容
你——或者你的 git pull
——将 运行 git fetch
具有:
- 没有命名的远程或存储库,也没有引用规范;或者
- 一个名为 remote-or-repository 且没有 refspecs;或者
- 一个名为 remote-or-repository 和一个或多个 refspecs。
在第一种情况下,git fetch
根据您当前的分支找出要使用的遥控器(它 运行 相当于 git 配置 -- get branch.<em>branch</em>.remote
),或者如果失败,假设 origin
。在第二种或第三种情况下,你可以给它一个像origin
这样的远程名称,或者你可以给它一个像https://github.com/our-repo.git
这样的URL。由于第一种情况转化为第二种情况,我们这里只需要担心这两种情况。
如果您使用 命名的遥控器 ,例如 origin
,您的 Git 查找 remote.origin.url
以获得 URL,还有 remote.origin.fetch
。通常 remote.origin.fetch
设置为:
+refs/heads/*:refs/remotes/origin/*
因此,当您 运行 git fetch origin
时,您的 Git 获取 所有 其他 Git 提供的分支,转向他们变成远程跟踪名称。当您 运行 git fetch origin bra
时,您的 Git 只获取获取 bra
所需的任何内容(我在这里假设 bra
是一个分支名称)。如果您的 Git 至少是 1.8.4,它仍然会进行相同的重命名,因此也会更新 refs/remotes/origin/bra
。
当你给你的 Git 一个原始的 URL 时,它可能找不到 remote.https://github.com/our-repo.git.fetch
配置(它甚至可能不会尝试查找,但如果它确实如此,它不会找到任何东西)。它仍然知道要联系什么URL,所以它联系那里的Git;但它没有特定的 fetch =
指令。如果您给 git fetch
一个分支名称,您的 Git 将向他们的 Git 询问该分支。但你也没有这样做——所以你的Git只是问他们的Git:嘿,其他Git,你设置了什么HEAD
?
所以你什么都不说,他们的 Git 给你一个散列 ID 和 他们的 HEAD
,你的 Git 写这到 .git/FETCH_HEAD
。或者,你说 "give me your branch bra
",他们的 Git 给你一个哈希 ID 和他们的 refs/heads/bra
,然后你的 Git 把它写到 .git/FETCH_HEAD
。在任何一种情况下,任何远程跟踪名称都不会发生任何变化。没有命名的远程名称,因此无法更新正确的远程跟踪名称。
尽管如此,您的 Git 总是将它获取的所有内容写入 .git/FETCH_HEAD
, 无论是否更新 origin/master
或 origin/develop
这样的名称。这在一定程度上是一个古老的向后兼容性问题——除了 git pull
仍在使用它,我们稍后会看到。
git merge
运行 由 git pull
合并的内容
此步骤在几个方面比提取步骤简单,但仍然非常棘手。当git pull
运行s git merge
时,它预先设置了一些选项和参数:
-m
:git pull
始终提供初始合并消息。这不是一个非常 好的 合并消息,但它确实提供了一个。 (默认情况下,如果涉及实际合并,它会让您编辑此合并消息。)- 来自
git pull
的其他选项:如果您使用--ff
或--no-ff
或--ff-only
,或-s strategy
,或 [=] 中列出的各种其他选项91=],git pull
将它们传递给git merge
. - 一个或多个原始提交 ID。
git fetch
在 .git/FETCH_HEAD
中留下踪迹后,git pull
代码读取整个文件。在该文件中,Git 记录了它获取的每个分支提示提交。在某些情况下,只有一个这样的提交。 (例如,对于这种获取 HEAD
的情况就是如此。)在其他情况下——none 适用于这种特殊情况,但为了完整性我们应该记住它们——它列出了更多;但它标记了其中的大多数 not-for-merge
。它 没有 标记的是那些与您在命令行中提供的 refspec 名称相对应的名称,例如 bra
,或者 - 如果您没有命名在命令行上——来自 branch.<em>branch</em>.merge
的那个,如果你从一个命名的 remote.
无论如何,git pull
提取任何 git fetch
没有 标记为 "not for merge" 的内容。理想情况下,这只是一个提交哈希,否则您的 git pull
将调用 git merge
以进行 octopus 合并 。这很少是你想要的——如果你不知道它是什么,你肯定不想要它!——所以如果只涉及一个哈希 ID(就像这里的情况),你会更开心。
此时,git merge
会根据选项和参数执行它一贯执行的操作。 Git 从当前提交(您自己的存储库的 HEAD
)和参数提交计算合并基础。如果合并基础与其他(单个)提交相同,则没有要合并的内容:Git 如此说但什么也不做。如果合并基础是 HEAD
,则可以进行快进非真正合并; Git 如果您没有禁止它,就会执行此操作。否则,需要真正的合并,如果您没有禁止它,Git 会这样做。
完成后,无法完成(在中间停下来获得用户的帮助),或者甚至不尝试合并,git merge
退出,现在 git pull
完成.
结论
通过 运行宁 git pull
与 URL,您已要求另一个 Git 将其 HEAD
发送给您(可能 master
) 提交,加上任何其他所需的提交,然后将该提交合并到您当前的分支中,无论您当前的分支是什么。通过使用 URL 而不是 origin
,您已经禁用了自己的 Git 对 origin/master
或任何其他 origin/*
名称的更新。因此,如果需要合并或快进以引入他们的 HEAD
,并且没有被禁止,那么它要么现在完成,要么处于失败合并的半完成状态。
的缩写
git pull <URL> HEAD
可以通过
找到HEAD所在的位置
cat .git/FETCH_HEAD
示例:
cat .git/FETCH_HEAD
b521bea1b4b336864462e