我想知道在运行merge命令之前是否通过“fast-forward”解析特定合并。
我知道我可以通过“快进”(使用--no-ff
选项)专门请求合并无法解决。或者我可以尝试仅通过快进来解决合并(使用--ff
选项)。
但有时我想知道在运行之前是否会通过快进解决特定合并。我意识到理论上我可以通过挖掘历史树来解决这个问题。而且我也意识到我可以运行合并,看看会发生什么,但是如果我决定我更倾向于以其他方式解决合并,这会成为问题,因为我必须撤消合并(通过重新分配分支标签)在ref-log中)并再次进行。
注意:--dry-run
问题(Is there a git-merge --dry-run option?)更多的是关于查看合并中可能存在的合并冲突,而不是关于可能通过快进解决的合并。
答案 0 :(得分:5)
总结:git merge-base --is-ancestor
测试一个提交是否是另一个提交的祖先(提交被认为是他们自己的祖先,这是一种特别奇怪的乱伦形式,也许是:-))。由于当前分支(git merge
)指向作为另一个提交的祖先的提交时,分支标签只能由HEAD
快进,我们可以使用它来确定是否{{1可以进行快进操作。
看起来你想把这个贴出来作为答案,所以我把它转换成了一个工作的git别名,你可以把它放在你的全局git配置中。别名有点长且复杂,最好将它剪切并粘贴到你的git config别名部分:
git merge
这是与shell脚本相同的东西,以更易读的方式和一些评论:
canff = "!f() { if [ $# -gt 0 ]; then b=\"$1\"; git rev-parse -q --verify \"$b^{commit}\" >/dev/null || { printf \"%s: not a valid commit specifier\n\" \"$b\"; return 1; } else b=$(git rev-parse --symbolic-full-name --abbrev-ref @{u}) || return $?; fi; if git merge-base --is-ancestor HEAD \"$b\"; then echo \"merge with $b can fast-forward\"; else echo \"merge with $b cannot fast-forward\"; fi; }; f"
shell脚本只需要一个主要部分来驱动它,即在别名之后调用#! /bin/sh
#
# canff - test whether it is possible to fast-forward to
# a given commit (which may be a branch name). If given
# no arguments, find the upstream of the current (HEAD) branch.
# First, define a small function to print the upstream name
# of the current branch. If no upstream is set, this prints a
# message to stderr and returns with failure (nonzero).
upstream_name() {
git rev-parse --symbolic-full-name --abbrev-ref @{u}
}
# Now define a function to detect fast-forward-ability.
canff() {
local b # branch name or commit ID
if [ $# -gt 0 ]; then # at least 1 argument given
b="$1"
# make sure it is or can be converted to a commit ID.
git rev-parse -q --verify "$b^{commit}" >/dev/null || {
printf "%s: not a valid commit specifier\n" "$b"
return 1
}
else
# no arguments: find upstream, or bail out
b=$(upstream_name) || return $?
fi
# now test whether git merge --ff-only could succeed on $b
if git merge-base --is-ancestor HEAD "$b"; then
echo "merge with $b can fast-forward"
else
echo "merge with $b cannot fast-forward"
fi
}
。别名本身只是将f
和canff
中的所有内容划分为一行。然后Git的配置文件规则要求用双引号引用整个别名,这反过来要求所有内部双引号都转换为反斜杠双引号序列。
(我还拿出了upstream_name
语句,因为作为别名,每次都会激活一个新的shell实例,因此变量名称的卫生变得不重要。)
(实际上可以将别名写成多行。只需在每个换行符前加上反斜杠。但是,这个别名非常复杂,看起来也很丑陋,所以我最后只留下一个大行。)< / p>
答案 1 :(得分:1)
您可以测试git merge-base <branch1> <branch2>
是否等于git rev-parse <branch1>
。如果相等,则在运行git merge <branch1> <branch2>
时ff合并或已经是最新的。如果没有,非ff合并。
function isff(){
a=$(git merge-base $1 $2)
b=$(git rev-parse $1)
c=$(git rev-parse $2)
if [[ "$b" == "$c" ]] || [[ "$a" == "$c" ]];then
echo merge dry run: already up-to-date
return
fi
if [ "$a" == "$b" ];then
echo merge dry run: a fast forward merge
else
echo merge dry run: a non fast forward merge
fi
}
isff master topic
答案 2 :(得分:0)
这里有一个类似但不完全相同的问题:Is there a git-merge --dry-run option?
第一个答案看起来可能就是您正在寻找的内容。
具体来说,merge
标有--no-commit
标记并在您看到足够的时候使用--abort
,并希望返回并进行实际合并。
答案 3 :(得分:0)
看看@ Ashwin-nair引用的问题,我发现我认为是一个答案。
有关
git checkout MY_BRANCH
git merge OTHER_BRANCH
如果输出
git branch --contains MY_BRANCH
包含OTHER_BRANCH
,然后可以通过快进解决与OTHER_BRANCH
的合并。