uay*_*ver 9 git merge fast-forward
我想知道在运行merge命令之前是否通过"快进"解析特定合并.
我知道我可以通过"快进"(使用--no-ff选项)专门请求合并不能解决.或者我可以尝试仅通过快进(使用--ff选项)来解决合并.
但有时我想知道在运行它之前是否会通过快进解决特定的合并.我意识到理论上我可以通过挖掘历史树来解决这个问题.而且我也意识到我可以运行合并,看看会发生什么,但如果我决定我更倾向于以其他方式解决合并,这就成了问题,因为我必须撤消合并(通过重新分配分支标签)在ref-log中)并再次执行.
注意:--dry-run问题(是否存在git-merge --dry-run选项?)更多的是关于查看合并中可能存在哪些合并冲突,而不是关于可能通过快进解决的合并.
简介:git merge-base --is-ancestor测试一个提交是否是另一个提交的祖先(其中提交被视为自己的祖先,这是一种特别奇怪的乱伦形式,也许是:-))。由于只有git merge当当前分支(HEAD)指向另一个提交的祖先的提交时,分支标签才能被快进,因此我们可以使用它来确定是否git merge可以执行快进操作。
看来您想将此内容发布为答案,所以我已将其转换为有效的git别名,您可以将其放入全局git配置中。别名有点长而且很复杂,最好将其剪切并粘贴到git config别名部分:
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"
Run Code Online (Sandbox Code Playgroud)
这是与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
}
Run Code Online (Sandbox Code Playgroud)
Shell脚本只需要一个主要部分来驱动它,这就是f对别名后面的调用。别名本身只是从铲一切canff并upstream_name成一条线。然后,Git的配置文件规则要求整个别名都用双引号引起来,这反过来又要求所有内部双引号都转换为反斜杠-双引号序列。
(我也删除了该local b语句,因为作为别名,这每次都会触发一个新的shell实例,因此变量名卫生变得不重要。)
(实际上,可以将别名写成多行。只需在每个换行符前加反斜杠即可。但是,该别名太复杂了,以至于看起来也很丑陋,所以我最后只留下了一大行。)