下面是我从主分支中使用的命令
git branch experiment
git checkout experiment
然后我对我的文件做了一些更改,提交这些更改,并将新的分支推送到GitHub。
git commit . -m 'changed files'
git push -u origin experiment
后来,我决定将我的实验分支合并到主分支中。
git checkout master
git merge experiment
最后,我把这些改动推到了GitHub上。
git push -u origin master
一切都很顺利,直到我试图删除我的实验分支使用
git branch -d experiment
我得到了错误信息:
错误:分支'experiment'没有完全合并。
如果你确定要删除它,运行'git branch -D experiment'。
我对git有点陌生,我不知道我还能合并多少两个分支。我错过了什么?
Git警告你删除这个分支可能会丢失历史记录。即使它实际上不会立即删除任何提交,但如果分支上的一些或所有提交也不是其他分支的一部分,那么它们将变得不可访问。
为了让分支实验“完全合并”到另一个分支,它的尖端提交必须是另一个分支尖端的祖先,使得实验中的提交成为另一个分支的子集。这使得删除实验是安全的,因为它的所有提交都将通过另一个分支保留存储库历史的一部分。它必须是“完全”合并的,因为它可能已经合并了几次,但现在已经添加了自上次合并以来不包含在另一个分支中的提交。
不过,Git不会检查存储库中的所有其他分支;只有两个:
当前分支(HEAD)
上游分支,如果有的话
在你的例子中,实验的“上游分支”可能是origin/experiment。如果实验被完全合并到当前分支中,Git会毫无怨言地删除它。如果不是,但它已经完全合并到上游分支中,Git会继续发出如下警告:
warning: deleting branch 'experiment' that has been merged
to 'refs/remotes/origin/experiment', but not yet merged to
HEAD.
Deleted branch experiment (was xxxxxxxx).
其中xxxxxxxx表示提交id。在上游完全合并表明实验中的提交已经被推到原始存储库,因此即使在这里丢失了它们,它们至少可以保存在其他地方。
由于Git不检查其他分支,因此删除一个分支可能是安全的,因为您知道它已经完全合并到另一个分支中;你可以使用-D选项来完成,或者先切换到那个分支,让Git为你确认完全合并的状态。
注:根据评论意见,措辞有所改变。由于@slekse
这不是错误,这是警告。这意味着您将要删除的分支包含从以下任何一个都无法到达的提交:它的上游分支或HEAD(当前检出的修订)。换句话说,当你失去提交¹。
在实践中,这意味着你可能修改、重基(包括压缩合并)或过滤提交,它们看起来并不相同。
因此,你可以通过签出一个分支来避免这个警告,这个分支包含了你要删除的另一个分支
你会想要验证你实际上没有错过任何重要的提交:
git log --graph --left-right --cherry-pick --oneline master...experiment
这将为您提供分支之间任何非共享的列表。如果你好奇的话,在没有选择的情况下可能会有区别,这种差异很可能是你得到警告的原因:
--cherry-pick
Omit any commit that introduces the same change as another commit on the "other side" when the set of commits are limited with symmetric difference. For example, if you have two branches, A and B, a usual way to list all commits on only one side of them is with --left-right, like the example above in the description of that option. It however shows the commits that were cherry-picked from the other branch (for example, "3rd on b" may be cherry-picked from branch A). With this option, such pairs of commits are excluded from the output.
¹默认情况下,它们只会在一段时间后被垃圾收集。另外,git-branch命令不会检查所有分支的修订树。这个警告是为了避免明显的错误。
²(我更倾向于强制删除,但你可能想要额外的保证)。
有解释的最简单解决方案(重复检查解决方案)(之前遇到过这个问题)
问题是:
1-我不能删除分支
2-终端保持显示一个警告消息,有一些提交还没有被批准
3-知道我检查了主和分支,他们是相同的(最新)
解决方案:
git checkout master
git merge branch_name
git checkout branch_name
git push
git checkout master
git branch -d branch_name
解释:
当你的分支连接到上游的远程分支(在Github, bitbucket或其他平台上)时,你需要将它合并(推送)到主平台,你需要将新的更改(提交)从分支推送到远程repo (Github, bitbucket或其他平台),
我在我的代码中所做的是,我切换到master,然后将分支合并到它(以确保它们在你的本地机器上是相同的),然后我再次切换到分支,并使用“git push”将更新或更改推到远程在线回购。
之后,我再次切换到master,尝试删除分支,问题(警告消息)消失,分支删除成功
公认的答案是正确的。在这里,我想补充三点:
这是如何发生的(经常发生在我身上)
举个例子
如何确保在通过-D强制删除之前不遗漏任何更改
我在GitHub上使用Rebase和merge作为默认的PR合并方法。这将为相同的更改创建新的提交(哈希)。
例如,当我跑步的时候
git log --graph --left-right --oneline add-theme-dark-2...main
在我的一个项目中,我得到了这个:
> fba6fce (HEAD -> main, tag: v2.0.9, origin/main) Refactored to semantic class names.
> 4e665bc Refactored to semantic class names. (1a)
....
> 8bd13a6 Added 'font-semibold' to title. (2a)
< 23f7b8a (add-theme-dark-2) Refactored to semantic class names.
< cf71814 Refactored to semantic class names. (1b)
....
< d3a774a Added 'font-semibold' to title. (2b)
(END)
注意1a/1b和2a/2b有不同的提交哈希值。
要确保您没有错过更改,请运行:
git log --graph --left-right --cherry-pick --oneline add-theme-dark-2...main
如果它返回一个列表,则每一行都以“=”开头:
= fba6fce (HEAD -> main, tag: v2.0.9, origin/main) Refactored to semantic class names.
= 4e665bc Refactored to semantic class names.
...
= 346770b Moved text size to component.
= 68cd471 Added theme-dark.
= 8bd13a6 Added 'font-semibold' to title.
使用以下命令可以安全地删除分支:
git branch -D add-theme-dark2