Git如何确定“我通常从中拉出的遥控器”?决定push.default =简单的行为? [英] How does Git determine the "remote I normally pull from" to decide the behavior of push.default = simple?

查看:137
本文介绍了Git如何确定“我通常从中拉出的遥控器”?决定push.default =简单的行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从Git 2.0版开始,如果未在用户的配置中指定 push.default 配置选项的默认值为简单


根据文档,这意味着:


在集中式工作流程中,像上游一样工作如果上游分支机构的名称与
本地分支机构的名称不同,则可以增加安全性来拒绝推送。


当推送到与远程站点不同的远程站点时通常来自。这是最安全的选项,适合
初学者。


在玩 git push时,在编写培训材料的一些极端案例中,我发现配置选项产生了令人惊讶的后果:


如果您所在的分支没有上游配置,并且您运行 git当您有两个遥控器时,按下my-remote ,在某些情况下,您会收到错误消息:

 致命:当前分支我的分支没有上游分支。 
要推送当前分支并将远程设置为上游,请使用

git push --set-upstream my-remote mybranch

在其他情况下,推送将成功并在远程上创建新分支,并与它一起使用远程跟踪分支(但不配置远程分支)


在对不一致之处进行了极大的困惑并仔细阅读了文档之后,我终于意识到 upstream config选项对于 push.default 简单 有时的行为)只会将 upstream 分支,因此如果未配置任何上游,而 current config选项(简单 有时的行为也一样)无论是否配置了上游都可以工作。


问题的关键在于,Git是否作为当前或作为上游选择简单选项(或保留为空白)时进行特别的推送。该文档仅说,它是 current 的功能,当推到与您通常从中拉出的遥控器不同的遥控器时。 那么,它如何确定呢?


我检查了一些显而易见的事情,例如我为哪些遥控器设置了远程跟踪分支,但结果仍然看起来我的两个测试存储库之间不一致。我什至尝试为我的仓库添加一个新的空仓库作为远程仓库,这会给我错误消息,并尝试推送到该仓库,但是我遇到了同样的错误。不幸的是,我今天一直在获取和推送这些测试存储库,以至于很难确定两者之间的区别是很困难的。


但是这个问题并不是关于我的特定存储库或它们表现不一致的原因;

参考文档的答案将不胜感激(我不确定答案是什么。)可以在那里找到);引用Git源代码的答案也很好,但是我对C的理解不是很流利,所以进行解释会有所帮助。 :)

解决方案

您可以 t5528-push-default.sh 中进行所有测试 git push 使用推送策略'简单 '


特别是:

  test_expect_success'推送到现有分支,未配置上游''
test_config branch.master.remote repo1&&
git checkout master&&
test_push_failure简单&&
test_push_failure上游


test_expect_success’推送到现有分支,上游配置了相同的名称’’
test_config branch.master.remote repo1&&
test_config branch.master.merge refs / heads / master&&
git checkout master&&
test_commit六个&&
test_push_success上游主服务器&&
test_commit七个&&
test_push_success简单母版


test_expect_success’推送到现有分支,上游配置了不同的名称’’
test_config branch.master.remote repo1&&
test_config branch.master.merge refs / heads / other-name&&
git checkout master&&
test_commit八个&&
test_push_success上游其他名称&&
test_commit九&&
test_push_failure简单&&
git --git-dir = repo1 log -1 --format =%h%s 其他名称 >期望其他名称&&
test_push_success当前主&&
git --git-dir = repo1 log -1 --format =%h%s 其他名称 >实际其他名称&&
test_cmp期望其他名称实际其他名称
'

如果上游分支是指定( git config branch.master.merge refs / heads / master ),将使用简单或上游推送策略。

提供了分支名称匹配上游的。


上游-将当前分支推回到通常更改其所在的分支集成到当前分支中(称为 @ {upstream} )。
仅当您推送到通常从中提取的相同存储库(即中央工作流)时,此模式才有意义。




简单-在集中式工作流程中,像上游一样工作,并增加了安全性,如果上游分支的名称与本地分支不同,则拒绝推送。


如果您认为这些测试未涵盖边缘情况,则新的 git bugreport命令(Git 2.27+)可以派上用场。


Starting with Git version 2.0, the default value for the push.default config option if not specified in the user's config, is simple.

According to the documentation, this means:

in centralized workflow, work like upstream with an added safety to refuse to push if the upstream branch's name is different from the local one.

When pushing to a remote that is different from the remote you normally pull from, work as current. This is the safest option and is suited for beginners.

In playing around with "git push" edge cases while writing training materials, I found a surprising ramification of the configuration options:

If you are on a branch that has no upstream configured, and you run git push my-remote when you have two remotes, in some cases you will get the error:

fatal: The current branch my-branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream my-remote my-branch

And in other cases, the push will succeed and will create the new branch on the remote, and the remote-tracking branch to go along with it (but not configure the remote branch as upstream).

After some extreme confusion about the inconsistency and some digging through the documentation, I finally realized that the upstream config option for push.default (which simple sometimes acts like) will only push to the upstream branch, and so will fail if no upstream is configured, whereas the current config option (which simple also sometimes acts like) will work regardless of whether an upstream is configured or not.

The crux of the matter, then, is whether Git is working as current or as upstream for a particular push when the simple option is selected (or left blank). The documentation only says that it works as current "when pushing to a remote that is different from the remote you normally pull from." So, how does it determine that?

I've checked some obvious things like which remotes do I have remote-tracking branches for, but the results still seem inconsistent between my two test repos. I've even tried adding a new empty repo as a remote for my repo that's giving me the error message, and trying to push to that, but I get the same error. Unfortunately, I've been playing with fetching and pushing in these test repos so much today that it's hard to pin down what the difference is.

But this question isn't about my specific repos or why they're behaving inconsistently; that's just an attempt to reverse engineer the answer to this question, which the documentation seems to leave unclear.

Answers that refer to the documentation would be greatly appreciated (I'm not sure the answer can be found there); answers that refer to Git source code are fine also, but I'm not fully fluent reading C so an explanation would be helpful. :)

解决方案

You can see in t5528-push-default.sh all the tested use-cases with git push using a push policy 'simple'

In particular:

test_expect_success 'push to existing branch, with no upstream configured' '
    test_config branch.master.remote repo1 &&
    git checkout master &&
    test_push_failure simple &&
    test_push_failure upstream
'

test_expect_success 'push to existing branch, upstream configured with same name' '
    test_config branch.master.remote repo1 &&
    test_config branch.master.merge refs/heads/master &&
    git checkout master &&
    test_commit six &&
    test_push_success upstream master &&
    test_commit seven &&
    test_push_success simple master
'

test_expect_success 'push to existing branch, upstream configured with different name' '
    test_config branch.master.remote repo1 &&
    test_config branch.master.merge refs/heads/other-name &&
    git checkout master &&
    test_commit eight &&
    test_push_success upstream other-name &&
    test_commit nine &&
    test_push_failure simple &&
    git --git-dir=repo1 log -1 --format="%h %s" "other-name" >expect-other-name &&
    test_push_success current master &&
    git --git-dir=repo1 log -1 --format="%h %s" "other-name" >actual-other-name &&
    test_cmp expect-other-name actual-other-name
'

If your upstream branch is specified (git config branch.master.merge refs/heads/master), a simple or upstream push policy will work.
Provided the branch name matches the upstream one.

upstream - push the current branch back to the branch whose changes are usually integrated into the current branch (which is called @{upstream}). This mode only makes sense if you are pushing to the same repository you would normally pull from (i.e. central workflow).

simple - in centralized workflow, work like upstream with an added safety to refuse to push if the upstream branch’s name is different from the local one.

If you think an edge-case is not covered by those tests, the new git bugreport command (Git 2.27+) can come in handy.

这篇关于Git如何确定“我通常从中拉出的遥控器”?决定push.default =简单的行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆