如何只获取当前分支

时间:2020-02-20 19:00:03

标签: git git-fetch

我只想一般地获取当前分支:

git fetch origin HEAD

但是如何确定默认遥控器?

git fetch DEFAULT_REMOTE HEAD

我假设HEAD是引用当前分支的最通用方法,但是我还需要一种引用当前分支的默认远程对象的通用方法?

请注意,这样做:

git fetch HEAD

给我这个问题:

致命:“ HEAD”似乎不是git存储库

致命:无法从远程存储库读取。

2 个答案:

答案 0 :(得分:1)

答案

git fetch origin $(git rev-parse --abbrev-ref HEAD)

使用通用遥控器

git fetch $(git config --local branch.$(git rev-parse --abbrev-ref HEAD).remote) $(git rev-parse --abbrev-ref HEAD)

说明

根据the docs,您可以从特定的refspec发出git fetch。

使用git fetch的以下格式,您可以要求提供特定的参考: git fetch [<options>] [<repository> [<refspec>…​]]

指定要获取的引用和要更新的本地引用。

此子外壳$(git rev-parse --abbrev-ref HEAD)来自this answer

我自己写的另一个是下面的$(git config --local branch.$(git rev-parse --abbrev-ref HEAD).remote),它使用第一个来增加泛化,但是它的作用是在本地配置中返回与分支关联的远程名称。 ,遵循此模式git config --local branch.<branch_name>.remote

答案 1 :(得分:0)

我认为HEAD是引用当前分支的最通用的方式...

是的,是的。不过这里有一个陷阱,我们稍后会看到。

但是我还需要一种通用方法来引用当前分支的默认遥控器?

执行此操作的方法有很多,每种方法都有其可能的陷阱,但是我认为最简单的方法是使用git config来回读当前分支的上游的一半设置。

这里明显的陷阱是,当前分支可能没有上游。

如果您拥有现代化的Git,git rev-parse可以返回有关任何分支上游(包括当前分支)的信息:

$ git rev-parse --symbolic-full-name HEAD
refs/heads/master
$ git rev-parse --symbolic-full-name HEAD@{u}
refs/remotes/origin/master

此处,当前分支为master,上游分支为origin/master。它们使用每个引用的完整拼写,如果您正在编写脚本,这是个好主意,因为缩写名(masterorigin/master)可能无法正确解析:例如,master如果有人创建了名为refs/tags/master的标签,则可能会变成master

上游(如果有),例如git branch --unset-upstream master删除上游master设置为两部分:

$ git config --get branch.master.remote
origin
$ git config --get branch.master.merge
refs/heads/master

branch.master.remote正是您想要的设置:遥控器的名称,在本例中为origin。因此,如果您首先找到当前的分支名称

$ git symbolic-ref --short HEAD
master

您可以使用它来获取适当的远程名称:

branch=$(git symbolic-ref --short HEAD) || die ...
remote=$(git config --get branch.$branch.remote) || die ...

您现在可以运行:

$ git fetch $remote HEAD

但是现在我们遇到了我提到的第一个陷阱:

remote: Enumerating objects: 928, done.
remote: Counting objects: 100% (928/928), done.
remote: Compressing objects: 100% (401/401), done.
remote: Total 928 (delta 601), reused 809 (delta 526)
Receiving objects: 100% (928/928), 843.84 KiB | 1.62 MiB/s, done.
Resolving deltas: 100% (601/601), completed with 74 local objects.
From [url]
 * branch                  HEAD       -> FETCH_HEAD

请注意,尽管我在这里(2.24.0)拥有现代的Git,但我的origin/master却没有更新。为此,我必须改用:

$ git fetch $remote $branch
From [url]
 * branch                  master     -> FETCH_HEAD
   c7a6207591..51ebf55b93  master     -> origin/master

这次,我的origin/master得到了适当的更新。

编辑:起初我没有提到它,但是我们可以在这里看到我的Git向他们的Git请求他们的 HEAD。他们的HEAD是他们的 master;如果我在其他分支机构,那么我的HEAD中仍会得到他们的master,即他们的.git/FETCH_HEAD。因此,这不仅仅是装饰性的:您必须在自己的Git中输入一个分支名称,而不是符号名称HEAD。与git push相比,您可以放心使用HEAD,因为git push是解析符号名称{的不是您的,而是您的 Git {1}}更改为分支机构名称。

结论和另外一个陷阱

您应该首先获取当前的分支名称。请记住,这可能会失败:可能没有当前的分支名称。然后,使用HEAD获取上游设置的 remote 部分。 (其余部分需要通过远程服务器的默认获取refspec映射进行映射,但是我们不需要它-git config --get将处理此问题-因此根本不用理会git fetch。)

这里值得一提的最后一个陷阱是:上面的示例代码使用branch.$branch.merge,其中git config --get ... || die ...是(大概)是一个完全退出脚本的shell函数。但是,如果您为当前分支设置上游设置,那么die本身不会退出。它将仅使用硬编码名称git fetch。因此,根据您想要模拟原始origin的狂热程度,您可能需要:

git fetch

相反。由于正在编写脚本,因此您可以在此处控制边缘情况和错误情况。