我被腌渍了。我无法从其他SO问题或阅读git文档中找到答案。我非常感谢你的帮助。
在Github上合并我的分支后,我从UI(远程)删除了我的分支。 我定期修剪当地的分支机构:
git checkout master
git pull origin master
git fetch -p
git branch -d X
Error: error: The branch X is not fully merged. If you are sure you want to delete it, run 'git branch -D X'
分支X已合并。当我在git log
上master
时,我可以看到来自X的提交。为什么会这样?我想使用-d
而不是-D
,因为这可能会导致严重删除真正未合并的分支。
答案 0 :(得分:8)
这里有几个不同的技巧。
git branch -d
的关键问题(删除而不强制 1 )不是"是否合并分支?",因为该问题实际上是无法回答的。问题是"是分支合并到<在这里填写一些东西>?"
这个测试在Git版本1.7中更改了(这意味着每个人都应该拥有它,但请检查您的Git版本),在commit 99c419c91554e9f60940228006b7d39d42704da7中由Junio C Hamano进行了更改:
branch -d:基础"已经合并"它与
合并的分支机构的安全性当分支被标记为与另一个引用合并时(例如本地'接下来的那个引用) 合并并推送到原点' next' branch.next.merge' 设置为' refs / heads / next'),基于"分支-d"是没有意义的。 安全,其目的不是失去未与其他人合并的承诺 分支机构,在当前分支机构。检查它是否更明智 与它合并的另一个分支合并。
因此,有两个或有时三个,如果你看一下你(或Git)必须回答的上述提交问题,看看是否允许-d
:
分支名称指向一个特定提交(让我们为提示调用此 T )。上游分支名称还指向一个特定的提交(调用此提交 U )。
T 是 U 的祖先吗?
如果问题2的答案为是(即T≤U),则允许删除。
如果 没有上游怎么办?好吧,那是"在1.7"进来:原始测试不是T≤U而是T≤HEAD。那个测试仍在那里。现在,如果没有上游,则使用HEAD测试而不是上游测试。同时,对于过渡期"当每个人都适应新奇的Git 1.7行为时,当 上游时,你也可能会收到警告或额外的解释。即使在今天,这个警告仍然存在,在Git 2.10中(差不多7年后现在:这是一个非常漫长的过渡时期!):
if ((head_rev != reference_rev) &&
in_merge_bases(rev, head_rev) != merged) {
if (merged)
warning("deleting branch ... not yet merged to HEAD.");
else
warning("not deleting branch ... even though it is merged to HEAD.");
}
(我在这里修剪了一些用于显示目的的代码):基本上,如果HEAD
解析为除了我们在T≤测试中使用的提交之外的其他提交,和 T≤HE T≤U T≤U T 我们添加了T≤U额外的警告信息。 (请注意,测试的第一部分是多余的:如果由于1.7之前的兼容性和上游缺失而与HEAD进行比较,那么如果我们进行比较,我们将得到相同的结果HEAD再次。我们真正需要的是in_merge_bases
测试。)
你怎么知道上游是什么?好吧,实际上有一个简单的命令行方式可以找到:
$ git rev-parse --abbrev-ref master@{u}
origin/master
$ git rev-parse --symbolic-full-name master@{u}
refs/remotes/origin/master
--abbrev-ref
变体为您提供Git的典型缩写版本,而--symbolic-full-name
为您提供完整的参考名称。如果在没有上游集的分支上运行,则两者都会失败。当然,您也可以使用git branch -vv
查看缩写的上游(对于所有分支)。
你如何测试整个T≤U的东西? git merge-base --is-ancestor
命令对shell脚本执行此操作,因此:
$ git merge-base --is-ancestor master origin/master && echo yes || echo no
将告诉您master
是否是origin/master
的祖先(为此目的,"指向相同的提交"计为"是#an祖先&#34} ;即,这是非常相同的≤测试。)
每当这个过渡期最终结束时,"使用HEAD"测试可能完全消失,或者可能继续用于没有上游设置的分支。但无论如何,问题始终是"待删除的分支是否已将合并到 ____? (填空)"你必须看看填补空白的内容。
上游中与您要删除的分支上的提交相对应的提交必须(或至少在其历史记录中)相同的提交,通过提交哈希ID,为此"合并到"测试成功。如果feature/X
通过所谓的" squash merge"合并到origin/develop
(这不是合并,虽然它是通过合并 2 完成的),但提交ID不匹配,并且"合并到"测试永远都会失败。
1 顺便提一下,从Git 2.3开始,您现在可以将--force
添加到git branch -d
,而不是被要求使用git branch -D
,当然{ {1}}仍有效。
2 这里的区别在于"合并" -merge作为名词,这意味着"提交是一个合并提交" (使用合并作为形容词)和"合并" -merge作为动词,意味着组合一些变化集的动作。 -D
命令可以:
A"壁球合并"只有当你提出要求时才会发生,而快速前进的非合并"只有当和
答案 1 :(得分:5)
当提交的内容与您尝试删除的分支相差足够时,就会发生这种情况。这可能是因为壁球提交或附加到先前基地的分支,然后当它们被遥控器上的其他人合并时。
如果您确信这些更改实际上是合并的(如您所说),则branch -D
是安全的。
最后,
灾难性地删除分支
不真实。删除分支不是可撤销的问题。所有操作都存储在git reflog
和分支指向的提交中至少保留30天。如果真的偏执,你可以重命名分支。但实际上,删除分支更容易。
换句话说,分支只是一个指针。删除指针不会删除内容。因此,如果需要,您可以轻松地恢复分支。