(不知道为什么这个问题被否决了,1而且你几乎已经自己回答了......)
您快到了:只需将push.default 配置为simple 或nothing,以便您必须为此案例指定推送目标,然后对于您的最终命令,使用:
git push origin my-local-branch:some-remote-branch
其工作方式是git push 在origin(遥控器的名称)之后采用一系列refspecs。 refspec 不是很复杂:它只是一对名称,例如 master:master、develop:develop 或 develop:foo,可以选择带有前导加号 +,并且可以选择省略第一个或第二个名称:@ 987654331@或develop。
Refspecs 会变得稍微复杂一点,因为它们在git fetch 和git push 中的工作方式不同,如果你省略了这两个名称之一。如果您每次都使用这两个名称,它们将保持简单:左侧的名称是 source 存储库上的名称,右侧的名称是 destination 上的名称>。对于fetch,源是远程,目标是您自己的存储库。对于push,源是您的存储库,目标是远程。
省略源名称仅适用于push,在这种情况下,它意味着删除。因此git push origin :foo 表示删除远程origin 上的foo。 (这不是你想要的,所以要避免。)
省略目标名称适用于fetch 和push,但对它们来说意味着不同的东西。让我们在这里忽略fetch。对于push,这意味着在本地和远程使用相同的名称。既然您不在此处使用它,请不要在此处使用它。 (或者,如果您确实需要它,请继续使用它。)
前导 + 符号(如果存在)与 --force 的含义相同。 (实际上--force 只是在所有内容上添加+。)
如果您运行 git push origin 或 git push(甚至没有 remote 参数),Git 会查找 push.default 以查看要推送的内容。将其设置为nothing 意味着只是失败/错误输出,所以我必须输入一个参考规范。将其设置为simple 意味着只将一个分支,即当前分支推送到当前分支的上游,但还要求上游名称匹配。由于my-local-branch 和some-remote-branch 不匹配,因此对于您的本地分支foo 正在跟踪远程跟踪分支origin/develop 的情况将失败:名称foo 和@987654360 @不匹配。
无论哪种方式,Git 都会强制您为此推送输入 refspec。
使用nothing 配置,Git 将强制您为每个 推送输入一个参考规范。 (我已经使用过它并且它有效,但它不是非常方便。)使用simple 配置,Git 将允许您将develop 轻松推送到上游develop,并允许您推送您的@987654365 @ 到上游develop(或上游jazzy,或除foo 之外的任何其他名称),但不会将foo 推送到foo,因为这不是它定义的上游。 (我用过这个,效果更好。)
从 Git 2.0 版开始,simple 是默认配置。因此,如果您拥有 Git 2.0 版或更高版本,您就可以开始使用了。如果没有,请查看您是否可以升级您的 Git 版本,但 push.default 可早于 Git 版本 1.6 进行配置。 (那么,我不确定它可以采用什么值。我认为,如果不是更早的话,当前的 5 组值可以追溯到 1.7.11。)
为了完整起见,其他三个可能的值是:current、upstream 和 matching。 current 值表示使用当前分支的名称:git push origin $branch:$branch 其中$branch 是当前分支。 upstream 值表示使用当前分支的上游名称:git push origin $branch:$merge,其中$merge 来自git config --get branch.$branch.merge。
matching 值是最难描述的,并且是 Git 2.0 版之前的默认值:这意味着 获取远程上每个分支的列表,并将它们的名称与我们的本地分支名称匹配,并且然后将我们所有的本地分支整体推送到远程上同名的分支,只要两个名称匹配。这不是一个非常安全的设置,尽管只要你不这样做使用--force,它实际上在实践中效果很好,这就是它可以使用这么多年的原因。
旁注:术语
Git 的术语有点乱。
-
local 分支(或只是“分支”或“分支名称”),例如 master,是 refs/heads/ 命名空间中的名称。它指向一个提交 ID。当您在该分支上进行新提交时,Git 会读取提交 ID,使用该 ID 作为新提交的父级进行新提交,然后将新提交的 ID 写入分支名称,以便分支现在指向新的提交(它又指向前一个分支提示,依此类推)。
您可以git checkout 一个本地分支,这会将您置于“分支上”,例如,git status 表示On branch master。正如我上面刚刚提到的,这会设置好新的提交来推进分支。
-
像origin/master 这样的远程跟踪分支 是refs/remotes/ 命名空间中的名称。在refs/remotes/ 之后,我们找到远程本身的名称origin,然后是另一个斜线,最后是在该远程上看到的分支名称(当然没有refs/heads/)。这些名称存储在本地,在您自己的存储库中:它们实际上根本不是远程的。当您的 Git 通过git fetch 和(在更有限的范围内)通过git push 联系远程时,它们只是自动更新。
您可以git checkout 远程跟踪分支,但如果这样做,git checkout 会将您置于“分离 HEAD”模式,因此 git status 和 git branch 声称您不在任何分支上(或在“无分支”或类似情况下,有时使用“分离的 HEAD”措辞)。当这种情况发生时,你实际上是在(单一的,特殊的)anonymous 分支上。当您回到正常分支时,您在匿名分支上所做的任何工作最终都会消失。 (因此,如果您想保留这项工作,请设置一个名称,使其不再是匿名的 - 或使用 git checkout 回到常规分支,然后再执行该工作。)
-
本地分支可以跟踪另一个分支(本地或远程)。当本地分支 B 正在跟踪另一个分支 U 时,Git 将其称为本地分支的“上游”。这个上游由两部分组成:远程名称,如origin,以及远程分支的名称,如master。要将本地分支跟踪为分支 B 的上游,Git 只需将远程设置为 .。
因此本地分支 B 正在跟踪上游 U 是否配置了这两个项目。 U 本身通常是一个远程跟踪分支,它是一个本地实体(refs/remotes/ 名称空间名称之一)。您必须git fetch 或git push 才能更新远程跟踪分支,之后git status 和git branch -vv 将报告跟踪远程跟踪分支的本地分支领先和/或落后他们的同行。
本地分支 B 可以改为跟踪另一个本地分支作为其上游。在这种情况下,由于所有内容都是本地更新的,git status 和 git branch -vv 将是最新的,不需要任何 git fetch。
本地分支B当然不需要跟踪任何东西。命令git branch --set-upstream-to <em>upstream</em> 和git branch --unset-upstream 将设置或取消设置当前分支的上游。您还可以使用 git config 设置、更改和检查上游的两个单独部分(branch.$branch.remote 和 branch.$branch.merge 部分),尽管使用 git branch 通常更好更方便。
1可能是因为 Git 2.0 默认 push.default。