确定合并是否将通过快进解决
Determine if a merge will resolve via fast-forward
我想知道在 运行 执行合并命令之前,特定合并是否会通过 "fast-forward" 解决。
我知道我可以通过 "fast-forward"(使用 --no-ff
选项)明确请求不解决合并问题。或者我可以尝试仅通过快进(使用 --ff
选项)来解决合并问题。
但有时我想知道某个特定的合并是否会在 运行 之前通过快进解决。我意识到理论上我可以通过挖掘历史树来解决这个问题。而且我也意识到我可以 运行 合并并看看会发生什么,但是如果我随后决定我更愿意以其他方式解决合并,这就会成为问题,因为我必须撤消合并(通过重新指向参考日志中的分支标签)并再做一次。
注意:--dry-run
问题 (Is there a git-merge --dry-run option?) 更多是关于查看合并中可能存在哪些合并冲突,而不是关于可以通过快进解决的合并。
这里有一个类似但不完全相同的问题:Is there a git-merge --dry-run option?
第一个答案看起来可能就是您要找的。
具体来说,一个带有 --no-commit
标志的 merge
并在您已经看够并想返回并进行实际合并时使用 --abort
。
您可以测试 git merge-base <branch1> <branch2>
是否等于 git rev-parse <branch1>
。如果相等,则在 运行 git merge <branch1> <branch2>
时进行 ff 合并或已经更新。如果不是,则进行非 ff 合并。
function isff(){
a=$(git merge-base )
b=$(git rev-parse )
c=$(git rev-parse )
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
查看@Ashwin-nair 引用的问题,我找到了我认为是答案的答案。
为了
git checkout MY_BRANCH
git merge OTHER_BRANCH
如果
的输出
git branch --contains MY_BRANCH
包含OTHER_BRANCH
,然后可以通过快进解决与OTHER_BRANCH
的合并。
总结:git merge-base --is-ancestor
测试一个提交是否是另一个提交的祖先(其中提交被认为是他们自己的祖先,这是一种特别奇怪的乱伦形式,也许:-))。由于当当前分支(HEAD
)指向作为另一个提交的祖先的提交时,分支标签只能通过 git merge
快进,我们可以使用它来确定是否 git merge
可以进行快进操作。
您似乎希望将此作为答案发布,因此我已将其转换为有效的 git 别名,您可以将其放入全局 git 配置中。别名有点长且复杂,最好将其剪切并粘贴到您的 git 配置别名部分:
canff = "!f() { if [ $# -gt 0 ]; then b=\"\"; 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=""
# 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
}
shell脚本只需要一个主要部分来驱动它,就是别名后对f
的调用。别名本身只是将 canff
和 upstream_name
中的所有内容铲到一行中。 Git 的配置文件规则要求整个别名用双引号引起来,这又要求将所有内部双引号转换为反斜杠双引号序列。
(我还删除了 local b
语句,因为作为别名,它每次都会触发 shell 的一个新实例,因此变量名卫生变得不重要。)
(实际上可以将别名写成多行。只需在每个换行符前加上反斜杠即可。但是,这个别名太复杂了,这样看起来也很难看,所以我最后只留下了一大行。 )
我想知道在 运行 执行合并命令之前,特定合并是否会通过 "fast-forward" 解决。
我知道我可以通过 "fast-forward"(使用 --no-ff
选项)明确请求不解决合并问题。或者我可以尝试仅通过快进(使用 --ff
选项)来解决合并问题。
但有时我想知道某个特定的合并是否会在 运行 之前通过快进解决。我意识到理论上我可以通过挖掘历史树来解决这个问题。而且我也意识到我可以 运行 合并并看看会发生什么,但是如果我随后决定我更愿意以其他方式解决合并,这就会成为问题,因为我必须撤消合并(通过重新指向参考日志中的分支标签)并再做一次。
注意:--dry-run
问题 (Is there a git-merge --dry-run option?) 更多是关于查看合并中可能存在哪些合并冲突,而不是关于可以通过快进解决的合并。
这里有一个类似但不完全相同的问题:Is there a git-merge --dry-run option?
第一个答案看起来可能就是您要找的。
具体来说,一个带有 --no-commit
标志的 merge
并在您已经看够并想返回并进行实际合并时使用 --abort
。
您可以测试 git merge-base <branch1> <branch2>
是否等于 git rev-parse <branch1>
。如果相等,则在 运行 git merge <branch1> <branch2>
时进行 ff 合并或已经更新。如果不是,则进行非 ff 合并。
function isff(){
a=$(git merge-base )
b=$(git rev-parse )
c=$(git rev-parse )
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
查看@Ashwin-nair 引用的问题,我找到了我认为是答案的答案。
为了
git checkout MY_BRANCH
git merge OTHER_BRANCH
如果
的输出git branch --contains MY_BRANCH
包含OTHER_BRANCH
,然后可以通过快进解决与OTHER_BRANCH
的合并。
总结:git merge-base --is-ancestor
测试一个提交是否是另一个提交的祖先(其中提交被认为是他们自己的祖先,这是一种特别奇怪的乱伦形式,也许:-))。由于当当前分支(HEAD
)指向作为另一个提交的祖先的提交时,分支标签只能通过 git merge
快进,我们可以使用它来确定是否 git merge
可以进行快进操作。
您似乎希望将此作为答案发布,因此我已将其转换为有效的 git 别名,您可以将其放入全局 git 配置中。别名有点长且复杂,最好将其剪切并粘贴到您的 git 配置别名部分:
canff = "!f() { if [ $# -gt 0 ]; then b=\"\"; 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=""
# 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
}
shell脚本只需要一个主要部分来驱动它,就是别名后对f
的调用。别名本身只是将 canff
和 upstream_name
中的所有内容铲到一行中。 Git 的配置文件规则要求整个别名用双引号引起来,这又要求将所有内部双引号转换为反斜杠双引号序列。
(我还删除了 local b
语句,因为作为别名,它每次都会触发 shell 的一个新实例,因此变量名卫生变得不重要。)
(实际上可以将别名写成多行。只需在每个换行符前加上反斜杠即可。但是,这个别名太复杂了,这样看起来也很难看,所以我最后只留下了一大行。 )