如何强制子树推送覆盖远程更改?

Posted

技术标签:

【中文标题】如何强制子树推送覆盖远程更改?【英文标题】:How do I force a subtree push to overwrite remote changes? 【发布时间】:2016-01-15 08:19:39 【问题描述】:

我们使用this Gist 的子树部署来部署Yeoman 项目的子目录。在我们的例子中,这个分支叫做 production,而不是 gh-pages

直到昨天 Git 服务器拒绝了命令 git subtree push --prefix dist origin production 时,这一直运行良好,并说

 ! [rejected]        9fe1683aa574eae33ee6754aad702488e0bd37df -> production (non-fast-forward)
error: failed to push some refs to 'git@gitlab.sdstate.edu:web-and-new-media/graduation2015.git'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart.

如果我在本地切换到生产分支(这是干净的),git pull 会返回 Your branch is up-to-date with 'origin/production'.,即使我使用了 --rebase 选项。

我可以通过我们的 Web UI 看到服务器上生产分支的内容,那里没有不应该的内容,只是我们的 dist 目录的编译输出,就像我期望的那样。

为此,我似乎应该能够安全地强制覆盖这些文件,但如何? git subtree push 没有 --force 选项。

【问题讨论】:

命令git subtree split --prefix dist origin production 也失败:fatal: ambiguous argument 'origin': unknown revision or path not in the working tree. 好吧,现在我真的很难过。我运行了git subtree pull --prefix dist origin production,这确实给我留下了与我更改的代码相关的合并冲突,所以我修复了这个问题并再次运行git subtree push --prefix dist origin production...只是再次失败并出现同样的错误。 【参考方案1】:

我刚刚增强了ele 的答案添加泛型表达式<> 使其更清晰:

git push <remote> `git subtree split --prefix <local-folder> <local-branch>`:<remote-branch> --force

示例值

&lt;remote&gt;

origin
other-origin-name
https://github.com/full-url/of-repo

&lt;local-folder&gt;

相对于 repo root 的本地文件夹路径,例如:/dist(您需要在 root 中执行此命令)

&lt;remote-branch&gt;

master
any-other-branchname

【讨论】:

【参考方案2】:

有一个更简单的解决方案

这总是对我有用。

    设置一个 bash 脚本,它可以帮助您执行以下操作:
cd dist
git init
git add .
git commit -am "deploy"
git push --force <remote URL> master
rm -rf .git
cd ..

这会在您指定的子目录中创建一个新的 git 存储库,并从那里强制推送所有内容。

    利润

【讨论】:

【参考方案3】:

其实有一个更简单的解决方案。

来源:https://gist.github.com/cobyism/4730490#gistcomment-2337463

设置

$ rm -rf dist
$ echo "dist/" >> .gitignore
$ git worktree add dist gh-pages

做出改变

$ make # or what ever you run to populate dist
$ cd dist
$ git add --all
$ git commit -m "$(git log '--format=format:%H' master -1)"
$ git push origin production --force
$ cd ..

【讨论】:

【参考方案4】:

诀窍是将子树拆分为强制推送:

git push origin `git subtree split --prefix dist master`:production --force

我从 http://clontz.org/blog/2014/05/08/git-subtree-push-for-deployment/ 的附录中得到了这个,他实际上在 Stack Overflow 上引用了 this 答案。我之前浏览过这个,但 Steve Clontz 的帖子让我点击了。

【讨论】:

此解决方案因“致命:不明确的参数 'publish-dev':未知修订或路径不在工作树中而失败。” 对于致命的模棱两可的参数,使用 -b 前缀作为分支名称 仅供参考:与 Github Pages 一起使用时,这会重置您的自定义域名。 您能详细解释一下什么是origin、master和production吗? 未知选项前缀

以上是关于如何强制子树推送覆盖远程更改?的主要内容,如果未能解决你的问题,请参考以下文章

Git强制推送命令

如何使现有分支跟踪远程分支[关闭]

如何临时更改 git ssh 用户进行远程推送?

当标签已经存在于远程时​​,Git 强制推送标签

常用的Git命令

git 强制推送到master