我有一个带有多个分支的 git 存储库。
我如何知道哪些分支已经合并到主分支中?
git branch --merged master
列出合并到 master 中的分支
git branch --merged
列出合并到 HEAD 中的分支(即当前分支的尖端)
git branch --no-merged
列出尚未合并的分支
默认情况下,这仅适用于本地分支机构。 -a
标志将显示本地和远程分支,而 -r
标志仅显示远程分支。
您可以使用 git merge-base
命令查找两个分支之间的最新共同提交。如果该提交与您的分支头相同,则该分支已完全合并。
请注意,git branch -d
已经执行了此类操作,因为它会拒绝删除 尚未 已完全合并的分支。
git branch -d
将拒绝删除尚未合并到当前分支的分支。不删除 current 分支。
为了验证哪些分支合并到 master 中,您应该使用以下命令:
git branch
git branch
标志是:
-a 标志 - (全部)显示远程和本地分支
-r 标志 - (远程)仅显示远程分支
例如: git branch -r --merged master
将向您显示合并到主存储库中的所有远程存储库。
git branch -r merged main
将显示您在 GitHub 上“删除”的分支,因为 GitHub keeps a record of recently deleted PR branches
还有一个图形界面解决方案。只需键入
gitk --all
一个新的应用程序窗口将提示您整个 repo 的图形表示,在这里很容易意识到一个分支是否已经合并
git
客户端的应用程序。在 Ubuntu 上,apt-get install gitk
。
brew install git-gui
,以在命令行上获取 gitk
。
我正在使用以下 bash 函数,例如:git-is-merged develop feature/new-feature
git-is-merged () {
merge_destination_branch=$1
merge_source_branch=$2
merge_base=$(git merge-base $merge_destination_branch $merge_source_branch)
merge_source_current_commit=$(git rev-parse $merge_source_branch)
if [[ $merge_base = $merge_source_current_commit ]]
then
echo $merge_source_branch is merged into $merge_destination_branch
return 0
else
echo $merge_source_branch is not merged into $merge_destination_branch
return 1
fi
}
使用 git merge-base <commit> <commit>
。
此命令在两个提交之间找到最佳共同祖先。如果共同祖先与“分支”的最后一次提交相同,那么我们可以安全地假设“分支”已经合并到主节点中。
以下是步骤
查找主分支上的最后一次提交哈希 查找“分支”上的最后一次提交哈希 运行命令 git merge-base
有关 git merge-base https://git-scm.com/docs/git-merge-base 的更多信息。
master
是否已合并到 branch
,然后又有 4 个提交添加到 branch
。
git log -1 $(git merge-base base-branch feature-branch)
,如果您在输出中看到 feature-branch
,那么您知道它们已合并?
关于清理远程分支的话题
git branch -r | xargs -t -n 1 git branch -r --contains
这会列出每个远程分支,然后列出其最新 SHA 所在的远程分支。
这有助于辨别哪些远程分支已合并但未删除,哪些尚未合并因此正在衰减。
如果您使用的是“tig”(它类似于 gitk,但基于终端),那么您可以
tig origin/feature/someones-decaying-feature
无需 git checkout 即可查看分支的提交历史
origin/master
但没有被远程删除的分支?
git remote prune origin
来更新您的本地机器上哪些是删除和未删除
我使用 git for-each-ref 获取已合并或未合并到给定远程分支的分支列表(例如 origin/integration
)
遍历所有匹配
注意:如果您倾向于使用 git pull
而不是 git fetch
,请将 origin/integration
替换为 integration
。
合并到远程源/集成分支的本地分支列表
git for-each-ref --merged=origin/integration --format="%(refname:short)" refs/heads/
# ^ ^ ^
# A B C
branch1
branch2
branch3
branch4
A:只取合并到远程 origin/integration
分支中的分支
B:打印分支名称
C:只查看 heads
引用(即分支)
未合并到远程源/集成分支的本地分支列表
git for-each-ref --no-merged=origin/integration --format="%(committerdate:short) %(refname:short)" --sort=committerdate refs/heads
# ^ ^ ^ ^
# A B C D
2020-01-14 branch10
2020-01-16 branch11
2020-01-17 branch12
2020-01-30 branch13
A:只获取未合并到远程 origin/integration
分支中的分支
B:打印分支名称以及最后提交日期
C:按提交日期排序输出
D:只查看 {2 } refs(即分支)
当我需要确定分支是否已合并时,这是我的技术,即使它可能已被重新定位以与我们的主分支保持同步,这是功能分支的常见场景。
这些方法都不是万无一失的,但我发现它们多次有用。
1 显示所有分支的日志
使用 gitk 或 TortoiseGit 之类的可视化工具,或者简单地使用 --all 进行 git log,查看历史记录以查看所有与主分支的合并。您应该能够发现此特定功能分支是否已合并。
2 在功能分支中合并时始终删除远程分支
如果你有一个好习惯,当你合并到一个特性分支时总是删除本地和远程分支,那么你可以简单地更新和修剪另一台计算机上的远程,特性分支就会消失。
为了帮助记住这样做,我已经使用 git flow extensions (AVH edition) 在本地创建和合并我的功能分支,所以我添加了以下 git flow 挂钩来询问我是否还想自动删除远程分支。
示例创建/完成功能分支
554 Andreas:MyRepo(develop)$ git flow start tmp
Switched to a new branch 'feature/tmp'
Summary of actions:
- A new branch 'feature/tmp' was created, based on 'develop'
- You are now on branch 'feature/tmp'
Now, start committing on your feature. When done, use:
git flow feature finish tmp
555 Andreas:MyRepo(feature/tmp)$ git flow finish
Switched to branch 'develop'
Your branch is up-to-date with 'if/develop'.
Already up-to-date.
[post-flow-feature-finish] Delete remote branch? (Y/n)
Deleting remote branch: origin/feature/tmp.
Deleted branch feature/tmp (was 02a3356).
Summary of actions:
- The feature branch 'feature/tmp' was merged into 'develop'
- Feature branch 'feature/tmp' has been locally deleted
- You are now on branch 'develop'
556 Andreas:ScDesktop (develop)$
.git/hooks/post-flow-feature-finish
NAME=$1
ORIGIN=$2
BRANCH=$3
# Delete remote branch
# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty
while true; do
read -p "[post-flow-feature-finish] Delete remote branch? (Y/n) " yn
if [ "$yn" = "" ]; then
yn='Y'
fi
case $yn in
[Yy] )
echo -e "\e[31mDeleting remote branch: $2/$3.\e[0m" || exit "$?"
git push $2 :$3;
break;;
[Nn] )
echo -e "\e[32mKeeping remote branch.\e[0m" || exit "$?"
break;;
* ) echo "Please answer y or n for yes or no.";;
esac
done
# Stop reading user input (close STDIN)
exec <&-
exit 0
3 按提交信息搜索
如果您并不总是删除远程分支,您仍然可以搜索类似的提交以确定该分支是否已合并。这里的陷阱是远程分支是否已重新定位到无法识别的位置,例如压缩提交或更改提交消息。
获取并修剪所有遥控器
在功能分支上查找上次提交的消息
查看是否可以在 master 分支上找到具有相同消息的提交
master 分支上的示例命令:
gru
gls origin/feature/foo
glf "my message"
在我的 bash .profile 配置中
alias gru='git remote update -p'
alias glf=findCommitByMessage
findCommitByMessage() {
git log -i --grep="$1"
}
git log --all --color --graph --decorate --topo-order --date=relative --abbrev-commit --pretty=format:"%C(green)%h %C(red bold)[%<(14)%ad] %Creset%s%Cred%d%C(blue) [%an]"
git log
中,您可以添加 --merges
以仅显示合并提交。 stackoverflow.com/a/25986615/134761
这是一个小小的单线,可以让您知道您当前的分支是否包含来自远程源/主分支的数据:
$ git fetch && git branch -r --merged | grep -q origin/master && echo Incorporates origin/master || echo Out of date from origin/master
我在处理功能分支时遇到了这个问题,并且经常想确保我将最新的工作合并到我自己的单独工作分支中。
为了概括这个测试,我在 ~/.gitconfig 中添加了以下别名:
[alias]
current = !git branch -r --merged | grep -q $1 && echo Incorporates $1 || echo Out of date from $1 && :
然后我可以打电话:
$ git current origin/master
检查我是否是最新的。
要检查源分支是否已合并到 master 分支,可以使用以下 bash 命令:
git merge-base --is-ancestor <source branch name> master && echo "merged" || echo "not merged"
git branch --merged
识别状态,然后删除本地和远程分支。git branch -a --merged/no-merged
也可以工作,而无需在此过程中创建本地跟踪分支。git branch -r --merged/--no-merged
只查找远程分支。--merged/--no-merged
后面有一个可选的提交参数。至少在我的 git (1.9.1) 版本中,在它之后添加-a
或-r
标志会给我一个致命错误。添加-a
或-r
之前--(no-)merged
。