我只想一般地获取当前分支:
git fetch origin HEAD
但是如何确定默认遥控器?
git fetch DEFAULT_REMOTE HEAD
我假设HEAD是引用当前分支的最通用方法,但是我还需要一种引用当前分支的默认远程对象的通用方法?
请注意,这样做:
git fetch HEAD
给我这个问题:
致命:“ HEAD”似乎不是git存储库
致命:无法从远程存储库读取。
答案 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
。它们使用每个引用的完整拼写,如果您正在编写脚本,这是个好主意,因为缩写名(master
和origin/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
相反。由于您正在编写脚本,因此您可以在此处控制边缘情况和错误情况。