如果我想创建一个新分支,我会这样做:
git checkout -b new-branch
但是,有时候这个分支已经存在了,eg:
fatal: A branch named 'new-branch' already exists.
有没有比执行以下操作更简单的方法?
git branch -D new-branch
git checkout -b new-branch
我试过了,但没用:
git checkout -b new-branch --force
最佳答案
你在这里想要的是 git checkout -B <em>name</em>
。如果 name
没有命名现有分支,这将创建新分支,指向当前提交,就像通过常规 git checkout -b
一样。
如果 name
确实 命名了一个现有分支,Git 会强制将分支名称重新指向当前提交。这很像 git reset --soft
。分支名称实际上只是一些 Git 哈希 ID 的人类可读名称,软重置会更改附加到分支名称的哈希 ID,而不会触及索引或工作树。同样,git checkout -B
将更改附加到该名称的 ID,而不会触及索引或工作树。
(主要答案到此结束,剩下的只是关于所有各种成功与失败模式的旁白。)
-B
和--force
有很大区别
这里有两个重要的区别。
这种特殊 checkout 的一般形式是:
git checkout [-b | -B] <em>name</em> [<em>target-commit-specifier</em>]
例如 git checkout -b newbr a234567
。
此时 -b
和 -B
之间的区别很明显:如果 name
部分命名了一个已经存在的分支,git checkout -b
会立即失败。 Git 不必尝试 checkout :名称存在;错误。但是,如果该名称不存在,或者您使用了 -B
,还有更多尝试。
如果您像我们在上面和原始问题中所做的那样省略目标说明符,那么一整类问题就会消失。这种没有目标提交的形式意味着:保留当前提交。根本不要触及索引或工作树。什么都不做很容易,而且永远不会失败,所以这部分永远不会失败。
但是,当您使用 git checkout -B <em>name</em> <em>target-commit-specifier</em>
形式时,该命令会尝试 git checkout
目标提交 a234567
。此步骤需要更新索引和/或工作树,这可能会失败,例如:
error: The following ... files would be overwritten ...
在这种情况下,git checkout -b
或 git checkout -B
被中止并且没有创建或重新设置分支。 (另见 Checkout another branch when there are uncommitted changes on the current branch 。)
--force
选项告诉 Git 如果这个 check out 步骤即将失败,Git 应该继续进行 check out ,覆盖或删除没有安全保存在存储库中的文件。这可以对索引和/或工作树进行各种更改,并且任何未永久、安全地存储在提交中的文件数据都可能在此处丢失。所以 --force
仍然很危险(因为它可能会丢失文件数据),但与 -b
和 -B
无关:它只影响 this 这一步,即从当前提交(无论它是什么)转移到另一个目标提交。
如果 Git 做到这一点——目标提交现在被安装为当前提交,索引和工作树已更改;或者目标提交是当前提交,所以索引和工作树保持不变——那么在这一点上,整个事情注定要成功。我们已经检查了 -b
的分支名称是否存在。 Git 现在要做的就是将当前提交的哈希 ID 写入分支名称(例如, name
指向 a234567
)并将 ref: refs/heads/<em>name</em>
写入 .git/HEAD
,这样您就可以了分支 name
。
关于git 强制 check out 重复分支?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45969568/