Gradle-release-plugin 更新被拒绝,因为你当前分支的提示落后了
Gradle-release-plugin Updates were rejected because the tip of your current branch is behind
在我的工作场所,我们使用多个开发人员共享的月度发布分支。
Gradle 版本为 2.14.1
我们使用 Jenkins 手动触发代码构建和发布(任务)(有效 运行 - gradle clean compileJava release)
整个过程大约需要30-40分钟,主要是编译,生成工件,运行Junit测试,上传工件到Artifactory。
终于到了打标签推送版本号的步骤了:
preTagCommit,它尝试更新 gradle.properties 并增加版本号并提交和推送。
此时,如果在过去的 30-40 分钟内分支上没有任何提交(因为构建是手动触发的),则发布成功。
在整个过程之间甚至有一个提交的那一刻它失败并出现错误:
任务“:preTagCommit”执行失败。
*
error: failed to push some refs to 'xxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
*
我尝试了几种 hack 并搜索了文档,但还没有找到任何合适的解决方案。
我的发布步骤是这样的:
***
release {
project.setProperty("gradle.release.useAutomaticVersion", "true");
newVersionCommitMessage = "Re-snapshoted project to version "
preTagCommitMessage = "Preparing version for release "
tagCommitMessage = "Tagging Release "
tagPrefix = "calypso"
requireBranch = ""
// Sometimes the plugin trips over its own feet with modifying the gradle.properties
// then complaining it has changed.
failOnCommitNeeded = false
pushToCurrentBranch = true
}
***
抱歉,如果之前有人问过这个问题,我找到的所有解决方案都是 git 的一般方法,而不是来自使用 Gradle-Release-Plugin 和 git 的人。
如有任何回复,我们将不胜感激。
我相信插件的 GitHub page 中提到了您要查找的标志:
Eg. To ignore upstream changes, change 'failOnUpdateNeeded' to false:
release {
failOnUpdateNeeded = false
}
编辑
由于某种原因,上面的标志似乎不起作用。然而,还有另一种方法可以实现这一点,那就是在 release
扩展的 git
选项中添加一个强制推送选项(说起来多嘴)。
release {
git {
pushOptions = ['--force']
}
}
这基本上会强制覆盖分支(请参阅下面的问题分析),除非托管存储库的服务器已调整为拒绝此类强制推送。在那种情况下,您实际上没有可以通过此处提供帮助的选项。
问题分析
正如我在下面的最后一条评论中所说,失败的部分是扩展 运行 执行 preTagCommit
任务,然后尝试将此提交推送到上游分支(master
例如)。可以看到这个推送命令对here.
当然,如果其他人已经将提交推送到该分支,那么这当然会失败。
如果插件作者让我们能够说
,那么解决这个问题的更简单方法就是
不要将 preTag 提交推送到上游
或
将 preTagCommits 推送到名为 foo
的分支
不幸的是,他们没有给我们这个选项(至少从我目前收集到的信息来看)。所以我想出了一些 hacky 解决方案来规避这个问题。
Solutions/Hacks
指定 pushToBranchPrefix 创建标记分支
这是另一个可以传递给 git
对象的 option当前分支:
例如:
afterReleaseBuild {
doFirst {
project.exec {
executable = 'git'
args 'checkout', '-b', 'v1.x.x@master'
}
}
}
将 v1.x.x
替换为与当前版本的标签匹配的内容。
这样做的目的是,每当插件尝试 push/commit 时,它都会 push/commit 到我们创建的这个分支,并最终从这个分支创建标签。
我认为这可能是最好的选择
禁用 preTagCommit
任务
由于 preTagCommit
任务失败了,我们可以禁用该任务,它不会再 运行:
tasks.named('preTagCommit') {
enabled = false
}
自己决定是否可以接受。
动态推送行为
因为我看过源代码,所以我可以 see 它推送的原因是它看到 git.pushToRemote
不为空。知道了这一点,我们就可以动态地控制这种行为。
tasks.named('preTagCommit') {
def pushToRemote = null
doFirst {
project.extensions.configure(net.researchgate.release.ReleaseExtension) {
pushToRemote = it.git.pushToRemote
it.git.pushToRemote = null
}
}
doLast {
project.extensions.configure(net.researchgate.release.ReleaseExtension) {
it.git.pushToRemote = pushToRemote
}
}
}
这样,在 preTagCommit
中,它不会推送任何内容,但会成功执行其他所有操作。
针对我的情况,最简单的解决方法是在 build.gradle:
中简单地修改我的发布插件组件
***
release {
....
pushToRemote = ''
....
}
***
这确保发布插件不会推送!
控制权来自 gradle 版本后,我跟进了:
Git拉原点
Git push --tags origin
这很好地同步了我的提交,也遵循了先拉后推的规则!
尽管这是一个 hacky 解决方案,@Clijsters 建议我使用特殊发布分支来解决这个问题。
在我的工作场所,我们使用多个开发人员共享的月度发布分支。
Gradle 版本为 2.14.1
我们使用 Jenkins 手动触发代码构建和发布(任务)(有效 运行 - gradle clean compileJava release)
整个过程大约需要30-40分钟,主要是编译,生成工件,运行Junit测试,上传工件到Artifactory。
终于到了打标签推送版本号的步骤了: preTagCommit,它尝试更新 gradle.properties 并增加版本号并提交和推送。
此时,如果在过去的 30-40 分钟内分支上没有任何提交(因为构建是手动触发的),则发布成功。
在整个过程之间甚至有一个提交的那一刻它失败并出现错误: 任务“:preTagCommit”执行失败。
*
error: failed to push some refs to 'xxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
*
我尝试了几种 hack 并搜索了文档,但还没有找到任何合适的解决方案。
我的发布步骤是这样的:
***
release {
project.setProperty("gradle.release.useAutomaticVersion", "true");
newVersionCommitMessage = "Re-snapshoted project to version "
preTagCommitMessage = "Preparing version for release "
tagCommitMessage = "Tagging Release "
tagPrefix = "calypso"
requireBranch = ""
// Sometimes the plugin trips over its own feet with modifying the gradle.properties
// then complaining it has changed.
failOnCommitNeeded = false
pushToCurrentBranch = true
}
***
抱歉,如果之前有人问过这个问题,我找到的所有解决方案都是 git 的一般方法,而不是来自使用 Gradle-Release-Plugin 和 git 的人。
如有任何回复,我们将不胜感激。
我相信插件的 GitHub page 中提到了您要查找的标志:
Eg. To ignore upstream changes, change 'failOnUpdateNeeded' to false:
release {
failOnUpdateNeeded = false
}
编辑
由于某种原因,上面的标志似乎不起作用。然而,还有另一种方法可以实现这一点,那就是在 release
扩展的 git
选项中添加一个强制推送选项(说起来多嘴)。
release {
git {
pushOptions = ['--force']
}
}
这基本上会强制覆盖分支(请参阅下面的问题分析),除非托管存储库的服务器已调整为拒绝此类强制推送。在那种情况下,您实际上没有可以通过此处提供帮助的选项。
问题分析
正如我在下面的最后一条评论中所说,失败的部分是扩展 运行 执行 preTagCommit
任务,然后尝试将此提交推送到上游分支(master
例如)。可以看到这个推送命令对here.
当然,如果其他人已经将提交推送到该分支,那么这当然会失败。
如果插件作者让我们能够说
,那么解决这个问题的更简单方法就是不要将 preTag 提交推送到上游
或
将 preTagCommits 推送到名为 foo
的分支不幸的是,他们没有给我们这个选项(至少从我目前收集到的信息来看)。所以我想出了一些 hacky 解决方案来规避这个问题。
Solutions/Hacks
指定 pushToBranchPrefix 创建标记分支
这是另一个可以传递给 git
对象的 option当前分支:
例如:
afterReleaseBuild {
doFirst {
project.exec {
executable = 'git'
args 'checkout', '-b', 'v1.x.x@master'
}
}
}
将 v1.x.x
替换为与当前版本的标签匹配的内容。
这样做的目的是,每当插件尝试 push/commit 时,它都会 push/commit 到我们创建的这个分支,并最终从这个分支创建标签。
我认为这可能是最好的选择
禁用 preTagCommit
任务
由于 preTagCommit
任务失败了,我们可以禁用该任务,它不会再 运行:
tasks.named('preTagCommit') {
enabled = false
}
自己决定是否可以接受。
动态推送行为
因为我看过源代码,所以我可以 see 它推送的原因是它看到 git.pushToRemote
不为空。知道了这一点,我们就可以动态地控制这种行为。
tasks.named('preTagCommit') {
def pushToRemote = null
doFirst {
project.extensions.configure(net.researchgate.release.ReleaseExtension) {
pushToRemote = it.git.pushToRemote
it.git.pushToRemote = null
}
}
doLast {
project.extensions.configure(net.researchgate.release.ReleaseExtension) {
it.git.pushToRemote = pushToRemote
}
}
}
这样,在 preTagCommit
中,它不会推送任何内容,但会成功执行其他所有操作。
针对我的情况,最简单的解决方法是在 build.gradle:
中简单地修改我的发布插件组件***
release {
....
pushToRemote = ''
....
}
***
这确保发布插件不会推送!
控制权来自 gradle 版本后,我跟进了:
Git拉原点
Git push --tags origin
这很好地同步了我的提交,也遵循了先拉后推的规则!
尽管这是一个 hacky 解决方案,@Clijsters 建议我使用特殊发布分支来解决这个问题。