【发布时间】:2014-03-06 23:09:25
【问题描述】:
这里给出一般答案:How do I make git merge's default be --no-ff --no-commit?
但是如何仅对远程分支强制执行此操作?有没有办法做到这一点?
【问题讨论】:
这里给出一般答案:How do I make git merge's default be --no-ff --no-commit?
但是如何仅对远程分支强制执行此操作?有没有办法做到这一点?
【问题讨论】:
没有,或者至少据我所知没有;并请参阅下面的警告:我怀疑您想要做的事情的用处非常有限,您可能会以错误的方式进行操作。 (见What is the XY problem?)
(我也认为VonC's answer to a related question 在尝试使用此答案之前值得一读。)
如果您“手动”进行合并,您始终可以编写自己的脚本来执行此操作。 (这意味着避免 git pull 支持 git fetch 例如:运行 git fetch,然后运行您的 do-merge 脚本,无论您如何称呼它。)
那么:如何编写一个模仿git merge 的脚本?当然,这取决于您想要做到多彻底。您可以使用git rev-parse --parseopt 为您解析参数(例如,请参阅git-rebase 脚本和git-sh-setup 脚本,都在git-core 目录中,通常是/usr/libexec 或/usr/local/libexec,尽管安装方式有所不同)。
如果没有 commit 参数,您还必须决定是否使用merge.defaultToUpstream,以及在合并开始之前您希望检测正在进行的合并、修改的工作目录的彻底程度,等等。
无论如何,假设您已经在脚本中准备好运行“真正的”git merge 命令,并且您想添加--no-ff --no-commit 当且仅当 (1)脚本的参数不会覆盖它,并且 (2) 要合并的“提交”,无论是直接给出还是由 merge.defaultToUpstream 暗示,都会命名一个“远程分支”。你如何确定提交是一个“远程分支”?
最简单的测试是在其上运行git rev-parse --symbolic-full-name。如果生成的名称以refs/remotes/ 开头,则该名称是符号名称并命名一个远程分支:
name_is_remote_branch() {
local full
full=$(git rev-parse --symbolic-full-name $1)
case $full in
refs/remotes/*) return 0;;
*) return 1;;
esac
}
上面的shell函数可以用作,例如:
if name_is_remote_branch origin/master; then
echo seems to work
else
echo oops
fi
或(更短,仍然只是为了演示):
name_is_remote_branch master || echo ok # master should not be "remote branch"
(换句话说,就像任何“真正的命令”一样,该函数返回 0 表示成功/真,非零表示“失败”/假,所以 boolean_test && if_true 和 boolean_test || if_false 是可用的简写。)
现在您可以使用小 shell 函数来测试为您的合并脚本提供的符号引用,当然前提是条件 (1)(“脚本的参数不会覆盖”)也满足。
合并实际上是通过提交 ID 工作的,提交 ID 是永久性的;但是你的自动控制旋钮是基于提交name,这是可变的。
如果我们将此测试应用于原始 SHA-1 ID,会发生什么情况?
$ git log -1 --decorate --oneline
676699a (origin/master, master) commit subject here
如果我在其他分支上运行do-merge 676699a,你想要发生什么?请注意,这个特定的提交 ID 有两个标签,origin/master(远程分支)和master(本地分支)。我没有给出 label 作为参数,但我要求合并那个特定的 commit。
所写的函数表明这是不是一个远程分支。 (特别是,git rev-parse --symbolic-full-name 不输出任何内容并退出 0,表示成功;case 然后将空字符串与两个 glob 模式进行比较,仅匹配第二个。)
如果您希望发生其他事情,则需要采取更多措施。您可以为空字符串添加大小写模式,这是您为任何不是符号名称的有效 SHA-1 返回的“符号全名”。 (这包括甚至不是提交的事情,也包括无法解决的事情。)然后你可以为这些情况做任何你想做的事情,但你需要弄清楚你想要什么。
请注意,git-sh-setup 脚本有一个函数 peel_commitish,它可以帮助将修订说明符解析为提交。 (与所有这些情况一样,它最终使用git rev-parse,这次使用特殊的^0 后缀,这意味着与^{commit} 相同。)
章鱼合并呢?
例如,如果我在分支 B 上并要求合并(按名称)两个分支 feature1 和 origin/feature2,这意味着什么?我是合并远程分支还是本地分支,是否默认使用--no-ff --no-commit?
【讨论】: