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

问题描述 投票:1回答:1

我想使用一个命令:

  1. 如果它不存在,请创建一个新分支。
  2. Checkout分支如果存在而没有任何修改。

目前使用的git checkout -B branchname违反了第二个要求,因为如果分支存在,它会将分支重置为起始点的HEAD。你知道checkout / workarounds /其他命令的任何标志会满足这两个要求吗?

git git-branch git-checkout
1个回答
2
投票

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

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

git checkout <name>

然后,如果失败:

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

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

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

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

这里的主要问题是:

  • 如果要创建新分支名称,则必须选择此新分支名称将标识的提交。您通过提供<starting-point>参数选择一个特定的起点;如果你没有命名一个起点,Git会假设你想要HEAD作为起点。 您还可以选择新分支是否应该具有上游集:这是--track的用途。但请注意,在某些情况下,--track会自动隐含。
  • 如果您使用的是现有分支名称,则根据上述语句,您不希望更改它将识别的提交。 (此时,您没有选择设置/更改现有分支的上游,因此特定问题会从图片中删除。)

现在让我们来谈谈这里发生的所有问题。

With -b, git checkout always wants to create a new branch

-b和/或--track标志告诉git checkout它应该创建新分支然后切换到它。如果切换到或将失败,它应该回滚整个操作,而不是创建新的分支。所以这里有一个起点。起点可能是HEAD。因为分支是新的,它还没有上游,但你可以告诉git checkout设置一个上游,使用--track--track的参数是上游的名称(应该是本地分支名称,或远程 - 跟踪名称,如origin/master)。

如果您提供-b标志,您还提供新的分支名称,因此它是新分支的名称。如果你省略-b标志,你必须提供--track和远程跟踪名称:在这种情况下,分支的名称是通过删除远程跟踪部分产生的名称,例如,origin/feature变为feature,所以git checkout --track origin/feature意味着同样的事情作为git checkout -b feature --track origin/feature

如果你提供一个起点,Git将需要检查特定的提交。起始点名称可以是远程跟踪名称(例如origin/masterorigin/feature),或提交哈希ID,或标识提交的任何其他名称。在大多数情况下,提供远程跟踪名称作为起点也等同于提供--track参数,因此如果您不想设置上游,请添加--no-track。有关完整说明,请参阅the git checkout documentation

Without -b, git checkout still sometimes creates a new branch

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

但你可以写,例如:

git checkout feat/ure

当你没有名为feat/ure的分支时。在这种情况下,Git将枚举所有远程跟踪名称,例如origin/masterupstream/master等。如果在剥离远程部分之后只有一个匹配feat/ure,Git假定您打算写:

git checkout --track origin/feat/ure

(或者遥控器上还有其他任何名称)。因此,这将创建feat/ure,指向与origin/feat/ure相同的提交,origin/feat/ure作为新分支feat/ure的上游设置。

如果没有feat/ure存在并且要么没有,或者有太多(两个或更多)远程跟踪feat/ure样式名称 - 例如,origin/feat/ureupstream/feat/ure都存在 - 这个git checkout将会失败,现在你必须求助于一个或多个-b和/或--track

Another alternative

如果您不喜欢这些替代方案,则可以测试是否存在分支名称。为此,请git rev-parse翻译名称,并在其前面插入refs/heads/

git rev-parse --quiet --verify refs/heads/feat/ure

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

在shell脚本中,这变为:

name=feat/ure
git rev-parse --quiet --verify refs/heads/$name >/dev/null && exists=true || exists=false
if $exists; then git checkout $name; else git checkout -b $name ...additional arguments; fi

当然,您可以将此脚本转换为shell别名或实际的shell脚本,无论您喜欢什么,都可以调用它。添加足够的参数解析和错误处理。

© www.soinside.com 2019 - 2024. All rights reserved.