git checkout -B没有重置或替代方法?

时间:2019-04-10 22:47:46

标签: git git-branch git-checkout

我想使用将执行的命令:

  1. 创建新分支(如果不存在)。
  2. 检出分支(如果未修改则存在)。

当前使用的git checkout -B branchname违反了第二个要求,因为如果存在分支,它将分支重置为起点的HEAD。您是否知道checkout的所有标志/解决方法/可以满足这两个要求的其他命令?

1 个答案:

答案 0 :(得分:2)

没有一个单独的Git命令可以做到这一点。

我建议使用的命令顺序是:

git checkout <name>

后跟 if 失败:

git checkout -b <name> [<starting-point>]

(取决于您想要的行为):

git checkout [-b <name>] --track <remote-tracking-name>

其中尖括号中的每个项目都代表您要替换的东西(例如<name>可能是feature/fast),方括号中的每个项目都代表了可选内容。

这里的主要问题是:

  • 如果要创建新的分支名称,则必须选择该新分支名称将标识的提交。您可以通过提供<starting-point>参数来选择特定的起点;如果您没有指定起点,Git会假设您要以HEAD作为起点。

    还可以选择新分支是否应具有上游集:这就是--track的目的。但是,请注意,在某些情况下,会自动暗示--track

  • 如果您使用的是现有分支名称,则根据上面的声明,您不想更改它将识别的提交。 (您目前无法选择设置/更改现有分支的上游,这样特定的问题就会消失。)

现在让我们触摸一下这里发生的所有附带问题。

对于-bgit checkout一直想创建一个新分支

-b和/或--track标志告诉git checkout应该同时创建新分支,然后切换到该分支。如果切换将失败或确实失败,则应回滚整个操作,而不要完全不创建新分支。因此,这里是一个 起点。起始点可以HEAD。由于分支是 new ,因此它还没有上游,但是您可以使用git checkout告诉--track将上游 set 设置为: --track的参数是上游的名称(应该是本地分支名称,也可以是远程跟踪名称,例如origin/master)。

如果提供-b标志,则还将提供新的分支名称,因此也就是新分支的名称。如果省略-b标志,则必须提供--track和一个远程跟踪名称:在这种情况下,分支的名称是通过删除远程跟踪部分而产生的名称,例如{{ 1}}变成origin/feature,因此feature的含义与git checkout --track origin/feature相同。

如果提供起点,Git将需要签出该特定提交。起点名称可以是远程跟踪名称(例如git checkout -b feature --track origin/featureorigin/master),提交哈希ID或其他标识提交的名称。在大多数情况下,提供远程跟踪名称作为起点也等同于提供origin/feature参数,因此,如果您不想要设置上游,请添加{ {1}}。有关完整说明,请参见the git checkout documentation

在没有--track的情况下,--no-track有时仍会创建一个新分支

当您遗漏-b时,git checkout将首先测试以查看 name 是否与某个现有分支匹配。如果是这样,操作的解码部分就完成了:Git现在尝试检查该特定提交(由该分支标识),如果成功,则将您的-b 附加到该分支,这样您就可以在分支机构了。

但是您可以写,例如:

git checkout name

当您没有一个名为HEAD的分支时。在这种情况下,Git将枚举 all 您的远程跟踪名称,例如git checkout feat/ure feat/ure,依此类推。如果在剥离远端部分后恰好一个origin/master相匹配,则Git会假设您 meant 要写:

upstream/master

(或其他名称,但仍在其中)。因此,这将创建 feat/ure,指向与相同的提交git checkout --track origin/feat/ure ,并以feat/ure作为新分支的上游设置origin/feat/ure

如果不存在origin/feat/ure,或者不存在,或者存在太多(两个或更多)远程跟踪feat/ure样式名称,例如feat/ure和{{1} }存在–此feat/ure只会失败,现在您必须诉诸origin/feat/ure和/或upstream/feat/ure中的一个或多个。

另一种选择

如果您不喜欢这些替代方法,则可以 测试分支名称是否存在。为此,请git checkout转换名称,并在其前面插入-b

--track

如果成功,它将打印git rev-parse解析为的哈希ID,并以零状态退出。打印的哈希ID是refs/heads/分支的尖端,因此存在。如果失败,则不打印任何内容(git rev-parse --quiet --verify refs/heads/feat/ure )并以非零状态退出,因此refs/heads/feat/ure不存在。现在,您可以放心地要求 create feat/ure了-也就是说,前提是没有其他人偷偷进入您的存储库并在查看退出状态时创建了--quiet --verify。确定feat/ure不存在(但现在存在)。

在shell脚本中,它变为:

feat/ure

当然,您可以将此脚本转换为Shell别名或实际的Shell脚本,并根据需要进行调用。添加足够的参数解析和错误处理以品尝。