git 从其他分支创建分支,而不跟踪它

lokaqttq  于 2023-04-19  发布在  Git
关注(0)|答案(5)|浏览(200)

通常,我会创建一个这样的分支:

git checkout branch
git checkout -b new_branch

它工作得很好,因为它不会自动设置一个上游分支,所以它会向我显示一个警告,让我推送设置上游分支。我通常会复制粘贴它,然后它会正确跟踪一个远程分支...
这就是说,它是相当繁琐...
所以我开始使用一种新的方法来减少步骤:

git checkout -b new_branch from_branch

不幸的是,它给了我这样的输出:

git checkout -b xxx origin/staging
Branch xxx set up to track remote branch staging from origin.
...

所以当我试着推的时候,它给了我这个错误:

fatal: The upstream branch of your current branch does not match

显然上游不是我想要的......我宁愿让它自动添加origin/xxx或者根本不添加上游。
我看到有一个“--no-track”选项;有办法让它成为默认值吗?我还没有成功使用跟踪选项。

bvn4nwqk

bvn4nwqk1#

正如你所注意到的,git checkout命令支持与git branch相同的--track/--no-track选项,因此要使新分支zorblatt指向与origin/master相同的 commit,但不将origin/master作为其(错误的)上游:

git checkout -b zorblatt --no-track origin/master

不幸的是,没有办法默认设置。(奇怪的是,有一个git-guigui.matchTrackingBranch的配置旋钮。)
(旁白:古老的动词,轨道,有点糟糕:“分支X跟踪远程跟踪分支Y/Z”,很快,“分支”和“跟踪”这两个词似乎不再意味着任何东西。“作为上游”是笨拙的,但至少它不是来自冗余部门。)

jexiocij

jexiocij2#

tl;dr:您可能希望执行git config --global push.default=upstream,但是对于纯git push将执行的确切操作,还有其他设置,这些设置可能更适合您的工作流。
Git的默认设置一直在进行中。一个裸git push执行的操作曾经是......好吧,C++术语是“Maven友好的”,它对理解的人来说是完全有意义的,但对仍然在寻找自己腿的人来说是一个惊喜。所以后来git添加了一个push.default设置,以及各种“模式”,决定裸git push将做什么的方法,他们的想法是找到并最终切换到一些合理的东西,而不会导致新手抱怨他们无意中造成的损害。
简而言之,新的工厂默认行为实际上是一个儿童保护帽,你只需要学会克服它,它阻止了粗心的人伤害自己。
如果您阅读git push文档,它会暗示所有这些内容,并将您指向push.defaultgit config文档:
当命令行没有使用<refspec> ...参数或--all--mirror--tags选项指定推送内容时,命令会通过查询remote.*.push配置来查找默认的<refspec>,如果没有找到,则使用push.default配置来决定推送内容(有关push.default的含义,请参阅git-config)。

**当命令行和配置都没有指定推送内容时,将使用默认行为,对应于push.defaultsimple值:将当前分支推送到相应的上游分支,但是作为安全措施,如果上游分支与本地分支的名称不相同,则中止推送。

其他的选择是

push.default

定义在没有明确给出refspec的情况下git push应该执行的操作。不同的值非常适合特定的工作流;例如,在一个纯粹的中央工作流中(即获取源等于推送目的地),上游可能是你想要的。可能的值是:

  • nothing -除非明确给出了refspec,否则不要推送任何东西(错误)。2这主要是针对那些希望通过始终明确来避免错误的人。
  • current -推送当前分支以更新接收端上同名的分支。在中心和非中心工作流中均有效。
  • upstream -将当前分支推回其更改通常被集成到当前分支的分支(称为@{upstream})。此模式仅在推送到通常从其拉取的存储库(即中央工作流)时才有意义。
  • 简单-在集中式工作流中,像上游一样工作,如果上游分支的名称与本地分支的名称不同,则增加了拒绝推送的安全性。

当按下的遥控器与您通常拉动的遥控器不同时,按电流工作。这是最安全的选择,适合初学者。
此模式已成为Git 2.0中的默认模式。

  • matching - push所有两端同名的分支。这会让你推送的仓库记住将要推送的分支集合(例如,如果你总是在那里推送maint和master,而没有其他分支,那么你推送的仓库将拥有这两个分支,你的本地maint和master将被推送到那里)。

为了有效地使用这种模式,你必须确保在运行git push之前,你要推送的所有分支都已经准备好了,因为这种模式的全部意义就是让你可以一次性推送所有的分支。如果你通常只在一个分支上完成工作并推送结果,而其他分支都没有完成,此模式不适合您。2此模式也不适合推送到共享的中央存储库,因为其他人可能会在那里添加新的分支,或更新您无法控制的现有分支的提示。
这曾经是默认值,但自从Git 2.0以来就不是了(简单是新的默认值)。

qncylg1j

qncylg1j3#

正如其他人所说,没有默认的配置,但是没有--no-track的方法是使用^{} revision suffix

git checkout -b new_branch origin/master^{}

后缀告诉git引用分支后面的对象,而不是分支本身。
我喜欢这种方法,因为它的意图更明确,这在某些标记场景中尤为重要。例如,使用git tag -a TagB TagA实际上会让TagB引用TagA本身,而不是它背后的提交。为了避免嵌套标记,您可以使用git tag -a TagB TagA^{}

2g32fytz

2g32fytz4#

--no-track标志将成为你的朋友,它将实现你的最终目标,当你使用checkout命令而不是branch命令创建一个新分支时,它将不跟踪一个远程分支。
这只节省了三次击键,所以输入的内容仍然很多。你可以将其 Package 在一个git别名中以简化操作,这是我用于此任务的别名:

git config --global alias.nb '!bash -c "git checkout -b $1 --no-track ${2-origin/master}" -'

这里接受两个参数,并调用bash来完成操作。我们使用branch-per-feature,并且(几乎)总是从master开始新的分支,所以我把第二个参数设置为可选的,并使用origin/master作为默认值。
要使用HEAD作为默认值,只需将${2-origin/master}更改为$2,或者替换您自己的分支名称以适应团队的工作流。
使用方法:

git nb <branch-name> [<source-commit>]
rqcrx0a6

rqcrx0a65#

它工作得很好,因为它不会自动设置上游分支
你同时是对的和错的。这怎么可能?
这取决于你的Git版本。
Git版本1.X将以与git v2.X不同的方式工作。
你的上游依赖于你用来创建分支的git版本。如果你使用1.X创建了一个分支,然后更新了你的git版本并创建了一个新的分支,两者的行为都会不同。
您可以随时手动编辑.git/config文件以查看您的跟踪分支。git remote -v会将它们打印到屏幕上。

git release notes 2.0

https://git.kernel.org/cgit/git/git.git/tree/Documentation/RelNotes/2.0.0.txt
git push [$there]没有说要推送什么时,我们使用了传统的**matching语义(只要那里已经有同名的分支,所有的分支都被发送到远程)
在Git 2.0中,默认值现在是
simple**语义,

你能做什么?

正如您所发现的,--no-track选项将创建一个没有上游的分支。

另一个选项:

您可以创建一个孤立分支(没有历史记录的分支),然后使用cherry-pick向其添加所有所需的历史记录。

git checkout --orphan <new_branch> [<sha-1>]

现在你将清空历史记录,你可以添加任何你想要的提交。

相关问题