【问题标题】:How to push git snapshots from a private git repository to public git repository?如何将 git 快照从私有 git 存储库推送到公共 git 存储库?
【发布时间】:2019-08-30 17:55:29
【问题描述】:

我有两个 git repos:

  1. 为开发者和他们的日常提交提供一个私有的
  2. 还有一个用于公开发布的公开版本。

每当我想发布代码时,我都想将开发者仓库的快照推送到公共仓库。由于开发者 repo 可能包含一些不适合公开的提交消息,我想用新的提交消息推送到公共 repo。

我的想法是(假设我在 dev repo 的主分支中):

// create remote 
git remote add p_repo git://some_repo
// create orphaned branch to get rid of commit history
git checkout --orphan pub_sync
// commit 
git commit -m "release info"
// push local master to remote master
git push p_repo pub_sync:master

当公共存储库为空时,这是第一次工作。但是对于第二次公开推送,我得到了一个快进错误。 与此同时,没有其他对公共回购的承诺!

我认为问题是,git 不知道孤立分支与公共 master 相关。

但是我该如何解决呢?

【问题讨论】:

    标签: git git-rebase git-push git-remote


    【解决方案1】:

    TL;DR

    使用git merge --squash --no-commit

    详情

    对于第一次提交,您的过程听起来很查找。

    对于后续提交,我会使用

    git merge --squash --no-commit
    

    为此,您需要一个包含您的开发存储库和公共存储库的沙箱,正如您所做的那样,但我认为如果沙箱是公共存储库的克隆,那将是最简单的。

    这是一个应该有效的过程:

    git clone public_repo
    cd public_repo
    git remote add dev dev_repo_url
    git fetch dev
    git merge --squash --no-commit dev/master
    git commit -m'updated to version X'
    git push
    

    您从git merge --squash --no-commit 获得的结果将与您的开发存储库没有任何关联,它只会将文件的状态获取到您的沙箱中,然后您可以将其作为后续步骤提交。

    如果合并导致冲突,您可能需要添加 -Xtheirs,因为我假设您想要的正是 dev/master 的状态,而不是公共和开发分支的某些合并。

    为什么

    这种方法的要点是,新提交将以前的公共版本作为其父版本,这是您在公共存储库中想要的。你得到的错误是由于新版本不是前一个的子版本,而是一个新的根,一般不推荐。

    【讨论】:

      【解决方案2】:

      问题是您正在尝试将新的提交推送到远程主机,而远程主机上当前的提交是无法访问的。你第一次这样做的时候,大概遥控器没有提交。所以你开始了

      O -- x ... x -- A <--(master)
      

      在您的本地存储库中。你创建了孤儿分支并推送,所以现在你有

      O -- x ... x -- A <--(master)
      
      R1 <--(pub_sync)(p-repo/master)
      

      现在您没有明确说明您第二次是如何做到的,但听起来您要么删除了本地 pub_sync 分支,要么做了类似的事情。 (否则,按照与上述完全相同的步骤,分支创建将失败。)因此,在您进行一些开发和另一个新的 checkout --orphan 之后,您将拥有

      O -- x ... x -- A -- x .. x -- B <--(master)
      
      R1 <--(p-repo/master)
      
      R2 <--(pub_sync)
      

      也许这就是你所说的 git“不知道”新的孤立分支与远程 master 相关的意思,在这种情况下你是对的。现在你可以强制推送pub_sync,但我不推荐它,原因有两个:首先,强制推送不应该成为你工作流程的常规部分。其次,由于您将发布保存在一个存储库中,我假设您想在其中保留发布历史记录。

      您真正需要的是创建R2 作为R1 的子级。

      在另一个答案中,有人建议壁球合并;问题是,您必须手动跟踪合并基础。您可以遵循一种模式,首先对中间分支进行真正的合并,然后将那个补丁重新应用到最终发布分支;但这对于您的用例可能有点过分了。或者,您可以创建一个 ref 来表示合并基础,并记住在每次 squash 合并后移动它。此外,与其他答案的说明相反,如果您不想冒险在 prod 存储库中意外暴露开发提交,则需要在开发端进行壁球合并并仅推送结果。

      或者,您可以使用commit-tree;这也有点麻烦,但也许可以编写脚本或别名。您将删除/重新孤立同步分支;所以从

      O -- x ... x -- A -- x .. x -- B <--(master)
      
      R1 <--(pub_sync)(p-repo/master)
      

      你会

      git checkout pub_sync
      git merge $(git commit-tree -p HEAD -m "commit message" master)
      git push p-repo pub_sync:master
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-15
        • 2010-10-11
        相关资源
        最近更新 更多