是远程跟踪分支的名称和相应的名称 被跟踪的远程分支必然相同?
如果它们可以有不同的名称,git fetch
如何匹配这两者
分支呢? (典型的refspec
到git fetch
是+refs/heads/*:refs/remotes/remote/*
)
如果我是正确的,给定远程跟踪分支,我们可以创建一个
本地跟踪分支与其关联但具有不同的分支
分店名称。 (通过-b
中的git checkout
选项)
此外,如果远程跟踪分支的名称和
被跟踪的相应远程分支是一样的,怎么做
git push
匹配本地跟踪分支和远程分支? (典型的refspec
到git push
是+refs/heads/*:refs/heads/*
)
答案 0 :(得分:5)
远程跟踪分支的名称和跟踪的相应远程分支是否必须相同?
没有。然而,使它们不匹配会导致很多痛苦(我还没有在推动方面对它进行测试)。
如果它们可以有不同的名称,那么git fetch如何匹配这两个分支呢? (典型的
git fetch
refspec是+refs/heads/*:refs/remotes/remote/*
)
您可能有多条fetch =
行,例如,您可以执行此操作:
[remote "strange"]
fetch = +refs/heads/master:refs/remotes/strange/surprise
fetch = +refs/heads/other:refs/remotes/strange/surprise2
但请注意,您不能再使用任何其他提取引用参数左侧的refs/heads/*
,因为它会匹配master
和other
,并且(可能)将它们映射到名称除surprise
和surprise2
以外,git fetch
除了中止,并且在这种情况下会出现错误消息。这实际上会强制您列出要从给定远程(refs/heads
复制)的每个strange
名称。在这种情况下。
(正如我所说,我还没有通过推送对此进行测试,而且我不知道push是否遵循与fetch相同的映射规则。最近有一些更改,在git 2.5左右,要处理"三角形"工作流程更好,例如从localmirror
获取并推送到centralserver
。其中一项更改是为推送添加相同类型的名称映射据推测,在这个新代码进入之前,做这种推动带来了更多的痛苦,甚至可能没有三角形的工作流程;并且可能现在它的工作效果更好......)
我们可以称之为"愚蠢的重命名技巧",我的建议是:不要使用它们。 :-)我认为他们可以正常使用大多数命令,并且与其他命令失败,但我不能指出任何特定的失败例子(只是模糊的记忆我过去如何做事。)
如果我是正确的,给定远程跟踪分支,我们可以创建一个与之关联但具有不同分支名称的本地跟踪分支。 (通过git checkout中的-b选项)
是;这适用于各种本地工作。我再次避免使用短语"本地跟踪分支",并且只说"本地分支与上游"因为这是git文档从大约1.7开始移动的方向(见下文)。
请记住"本地分支的上游 $branch
"由...产生:
git config --get branch.$branch.remote
和git config --get branch.$branch.merge
映射到该远程的fetch =
refspec。因此,假设我们已创建了两个本地分支test1
和test2
并具有以下内容:
$ git config --get branch.test1.remote
origin
$ git config --get branch.test1.merge
refs/heads/test
$ git config --get branch.test2.remote
origin
$ git config --get branch.test2.merge
refs/heads/test
test1
和test2
都引用refs/heads/test
,这是其他 git存储库上的分支名称,该存储库将通过名称{ {1}}:这就是我们需要通过origin
的{{1}}地图运行这些内容的原因。
在没有愚蠢的重命名技巧的情况下,"映射到" part将branch-name部分(fetch =
之后的所有内容)保持不变,只替换中间位,以便origin
变为refs/heads
。这很容易做出假设。我相信一些懒惰的脚本编写者(包括我自己过去)可能已经使用了这段shell脚本代码:
refs/heads/test
不仅假设缺乏愚蠢的重命名技巧,甚至假设如果我们在分支refs/remotes/origin/test
上,则上游必须是fullbranch=$(git rev-parse --symbolic-full-name $branch) || exit 1
remote=$(git config --get branch.$branch.remote)
rmtbranch=refs/remotes/$remote/$branch
,而不是test1
。略微不那么懒惰的脚本编写者(包括我自己过去)然后必须修复他们的脚本,例如:
origin/test1
现在假定origin/test
上的fullbranch=$(git rev-parse --symbolic-full-name $branch) || exit 1
remote=$(git config --get branch.$branch.remote)
theirname=$(git config --get branch.$branch.merge)
rmtbranch=refs/remotes/$remote/${theirname#refs/heads/}
映射到本地存储库中的refs/heads/test
。
添加愚蠢的重命名技巧意味着我们根本无法轻松找到实际的上游名称,但各种命令(例如origin
,refs/remotes/origin/test
)会自动找到正确的上游名称。为了使脚本更容易,git 1.7.0版增加了git merge
符号:现在你可以简单地编写git rebase
。 git解析器为您查找上游,上面(损坏的)脚本片段可以重写为:
@{upstream}
这对 fetch 来说很好,但是 push 呢?好吧,如果您正在推送到您正在提取的相同的遥控器,那么您只需做同样的事情。但是,出于各种原因,您可以将 1 拆分:从存储库 $branch@{upstream}
获取并推送到存储库 rmtbranch=$(git rev-parse --symbolic-full-name $branch@{upstream}) || exit 1
< / em>的。在这种情况下,我们可能需要 F
和 P
的不同的映射。
Git 2.5引入F
,正如VonC在一些早期的SO帖子中所指出的那样,我无法随意找到,并且在github blog posting中。新的P
表示法只是从上游使用 fetch 切换到使用 push 上游,即使用 @{push}
映射而不是 @{push}
映射。
还有一个好问题,这是你最后一个问题:
此外,如果跟踪的远程跟踪分支和相应的远程分支的名称相同,git push如何匹配本地跟踪分支和远程分支? (git push的典型refspec是
P
)
我对git 2.5的回答,包括新的推送内容,是:我确实不知道,但你的&#34;典型的refspec&#34;不再是默认值(因为git 2.0)。当你运行没有refspec参数的F
时,git会查找你的+refs/heads/*:refs/heads/*
设置(以及更多可选设置,但git push
实际上需要 2 )。它有五个可能的值,只有其中一个 - 不是默认值push.default
。
其中一个设置是push.default
,该设置通过地图功能运行当前分支的refs/heads/*:refs/heads/*
设置(可能是在git 2.5及更高版本中,通过新的单独推送映射如果存在,否则通过获取地图)。
1 一个原因是使用拉取请求存储库,如链接的github博客文章中所述。另一个是从本地镜像获取(如在大型企业设置中使用本地镜像用于各个分支机构),但是推送到单个中央服务器(公司指定的&#34;主站&#34;所有本地镜像的站点)实际上镜像)。
2 如果你没有设置upstream
,git就会吐出很多恼人的文字。关闭它的最佳方法是设置merge
,这意味着您需要&#34;必需&#34; (无论如何)设置它。而且,由于git 2.0,默认设置(如果你还没有设置)是push.default
,它禁止愚蠢的重命名技巧。
答案 1 :(得分:4)
refspec
正如你所说的{。{1}}位于.git / config文件中
git配置文件包含有关refspec
为了看到你所描述的内容,请执行以下操作:
refspec
使用// Checkout master
git checkout master
// rename the master branch to a new name
git branch -m <old name> <new name>
// View the .git/config file and you will see the the new branch is still
// pointing (tracking) to the master branch, just like you described
,您可以控制refspec
将引用的分支。
pull/push
当git branch -u <upstream>/<branch name>
没有说要推送什么时,我们已经使用了
到目前为止传统的“匹配”语义(所有分支都被发送了
只要已经存在同名分支,就可以到远程控制台
在那边)。在Git 2.0中,默认是现在的“简单”语义,
推动:
只有当前分支到同名的分支,并且只有 当前分支设置为与该远程集成时 分支,如果你正在推送到同一个遥控器;或
只有当前分支到具有相同名称的分支,如果您 正在推送到一个不是你常去的地方的遥控器。
您可以使用配置变量git push [$there]
来更改此信息
如果你是一个想要继续使用的老人
push.default
语义,您可以将变量设置为“匹配”,用于
例。阅读文档以了解其他可能性。
答案 2 :(得分:2)
来自@codeWizard的答案是完整而完整的答案,但简单的英语答案(根据您对其答案的评论问题)是:
1 真的是两个问题。第一个答案是:不,它们不必具有相同的名称。第二个答案是:fetch
实际上并不映射本地和远程分支。所有fetch
确实(使用您的示例 - 默认值)是远程询问它的refs/heads/*
列表以及关联的blob,并将refs存储在使用远程名称生根的refs/remotes/*
中。
2 本地分支到远程分支的映射可以通过使用显式pull
和fetch
调用来控制,也可以在.git/config
中设置所有内容。在git/config
中,拉动行为由$branch.merge
控制,但推送由push.default
控制:默认情况下,它将推送到远程上与本地相同的分支名称。如果您将其设置为upstream
,那么它将使用$branch.merge
作为推送目标。
操作实例:
mkdir t1 && cd t1
git init
touch file
git add file
git commit -a -m "remote"
cd ..
git clone t1 t2
cd t2
git branch -a # you should see 'master' and 'origin/master'
git branch -m master local
git pull # Should say "Already up-to-date"
git branch -a # you should now see 'local' and 'origin/master'
git push # damn! It pushed 'local' to 'origin/local'!
git push origin :local # delete 'origin/local'
git config push.default upstream # tell git to use 'local.merge' as the push target
git push # Now it should say "Everything up-to-date"
毕竟,t1
配置应如下所示:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
t2
应如下所示:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = /nas/src/t/t1
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "local"]
remote = origin
merge = refs/heads/master
[push]
default = upstream
答案 3 :(得分:0)
我知道这是一个老问题,但明确的答案是正确的git-config手册(输入git help config
或man git-config
)。关于如何使用以下信息的示例就在报价之后:
push.default
定义git push应该采取的操作,如果没有显式的refspec 给出。不同的值非常适合特定的工作流程;对于 例如,在纯粹的中心
工作流程(即获取源等于推送目标), 上游可能就是你想要的。可能的值有:
·没有 - 除非refspec是,否则不要推送任何东西(错误输出) 明确给出。这主要是针对想要避免的人 始终存在的错误
显式的。
·current - 推送当前分支以使用相同的更新分支 接收端的名称。适用于中央和非中央 工作流程。
·upstream - 将当前分支推回到其分支 通常将更改集成到当前分支中(即 叫@ {upstream})。此模式仅
如果你要推送到同一个存储库,是有意义的 通常来自(即中央工作流程)。
·简单 - 在集中式工作流程中,像上游一样添加工作 如果上游分支的名称不同,则拒绝推送的安全性 来自当地的。
当推到与遥控器不同的遥控器时 通常来自,作为当前工作。这是最安全的选择 适合初学者。
此模式已成为Git 2.0中的默认模式。
·匹配 - 推送两端具有相同名称的所有分支。 这使您正在推动的存储库记住了这一组 将被推出的分支
(例如,如果你总是推动maint和master那里没有其他分支, 你推送的存储库将拥有这两个分支,以及你的 当地的maint和主人
将被推到那里。
要有效地使用此模式,您必须确保所有分支 在推出git push之前你会推出准备推出的,
的全部意义此模式允许您一次性推送所有分支。如果 你通常只在一个分支上完成工作并推出结果, 而其他分支是
未完成,此模式不适合您。此模式也不合适 用于推入共享中央存储库,就像其他人可能添加的那样 那里有新的分支机构,或
更新您控制之外的现有分支的提示。
这曾经是默认设置,但不是自Git 2.0以来(简单就是新版本) 默认值)。
因此,要将git设置为适合您的配置,请输入:
git config push.default nothing
使用您的首选配置替换nothing
。如果您希望它是全局的(本地计算机上的所有存储库),请添加全局选项:
git config --global push.default nothing
回答你的问题: