【问题标题】:How do I make unpushable commits pushable?如何使不可推送的提交可推送?
【发布时间】:2012-03-14 01:05:25
【问题描述】:

Master 分支有这样的提交:A -> B -> C(HEAD)HEAD 位于 C

我做了什么:

我查看了B 并在其上进行了提交。

现在树看起来像这样:

A -> B -> C(master)(原点/master) | | -> B1 -> B2(头部)

项目目录上的git status 给了我以下信息:

# 目前不在任何分支上。 没有什么可提交的(工作目录干净)`

所以这意味着B1B2不能被推送。我知道这是因为这些提交在任何分支上都不存在。现在,如果我将分支切换回 master,这些提交会丢失吗?我期待在这些未命名的分支上进行更多提交(B3, B4 ... BN),之后我希望C 能够超越它。本质上,我希望以这种方式看到master 分支:

A -> B -> B1 -> B2 -> B3 -------> BN -> C(master)(origin/master)

或者至少这样:

A -> B ---------> C(master)(origin/master) -> D | ^ | | | -> B1 -> B2 -> -> ...->BN--------------------------

我必须通过哪些选项来完成此任务?我希望能够将提交保存在origin 中。

任何建议/方向表示赞赏。

【问题讨论】:

  • 了解为什么您希望在origin 中提交您的提交会很有帮助。只是为了备份,或者其他人可以看到它们,还是其他什么?
  • 只是备份。实际上,应该在发布之前进行 C 提交,并且在我进行 C 提交之后弹出问题。所以我不得不检查以前的提交并解决问题。不确定何时合并 C 提交,但会在发布之前完成。
  • 因此,选择将临时分支推送到origin,还是合并到master 并将临时分支保持在本地,将取决于您的工作流程。如果您确实想推送临时分支,请告诉我,我可以在该部分添加更多详细信息。

标签: git git-branch git-push git-commit


【解决方案1】:

你想要的结果

A -> B -> B1 -> B2 -> B3 -------> BN -> C(master)(origin/master)

不可能,除非您可以在远程仓库中重写 C;这样做会给所有基于 C 工作的其他人带来问题。

第二个偏好

A -> B ---------------------> C(master)(origin/master) -> D
     |                                                    ^
     |                                                    |
     | -> B1 -> B2 -> -> ...->BN--------------------------

很简单:正如 Magnus 所说,如果你给 B2 (或者你序列中当前最新的提交)一个分支名称,你会让你的生活更轻松:这更容易记住并键入而不是哈希,并确保它不会被垃圾收集。

git checkout -b bbranch

A -> B -> C(master)(origin/master)
     |                                                    
     |                                                    
     | -> B1 -> B2 (bbranch)

现在,如果您想将 B1B2 推送到原点,无论出于何种原因,您都可以正常合并和推送

git checkout master
git pull
git merge bbranch

A -> B ------> C -> D (master)
     |             /
     |            /
     | -> B1 -> B2 (bbranch)

git push

您可以继续处理 bbranch 并在完成后再次合并

A -> B ------> C -> D -> E -> ... -> En -> F (master)
     |             /                      /
     |            /                      /
     | -> B1 -> B2 -> B3  ->  ...  -> Bn  (bbranch)

注意:如果您出于任何原因想要将提交推送到 origin,但您希望它们在 ma​​ster 上,您可以简单地推送 bbranch ,它会带着你的提交。然后,您需要确保没有其他人会触及 bbranch,或者将本地副本设为远程跟踪分支。

在这种情况下,将合并步骤 B2 -> D 替换为 git push origin bbranch

【讨论】:

    【解决方案2】:

    不确定为什么不为提交创建新分支。这就是我要做的:

    git checkout B
    git checkout -b fix
    .. do some stuff
    git commit -am 'did some stuff to B'
    git checkout master
    git merge fix
    

    第一个答案:

    git checkout master
    git merge B2
    

    您的提交永远不会丢失,除非您清理对它们的引用(使用 git gc 等)。只要您提交了更改,您就是安全的。

    【讨论】:

    • 我只想在提交BN 之后合并,并且我希望能够保存/推送B1...BN 提交。
    • git checkout master, git merge BN .. 然后你的提交在 master 分支上,你可以推送你的 master 分支。
    • 但问题是提交BN 可能会在一周后发生,我想通过将提交B1, B2 etc., 推送到原点来保存它。
    • B1、B2 没有丢失,它们还在。只需与它们的哈希值合并。将来请确保从 B 创建一个新分支以简化此操作。
    • 重写了我的答案。但是,仍然可以合并在任何分支上进行的单个提交。
    【解决方案3】:

    如果我理解正确,您所要求的是一种在外部存储库中使提交可见的方法当它们不属于分支时

    提交 B1 和 B2 可以通过它们的 SHA1 哈希访问,但不能通过任何命名的 ref 访问。因此,从 git 的角度来看,它们是“垃圾”,最终会被 git gc 清理(在您的设置定义的足够时间过后)。

    当您执行git push 时,它会推送属于您存储库“一部分”的更改。这包括所有 可从命名 ref 访问的变更集。 “垃圾”提交不会去。

    因此,如果您不希望更改成为某个 other 分支的一部分,但仍想推送它们,则应该将它们设为自己的分支。这将具有允许您推送它们、为您提供访问它们的句柄并防止它们被垃圾收集(这是您不想要的)的效果。

    另一方面,如果您已准备好将松散提交 作为master 分支的一部分,则需要git rebase(将它们放在当前master 之上)或git merge(将它们与 master 集成,同时保留您当前拥有的准确历史记录)。您还可以重写 master 分支以将提交包含为您的“第一个”示例,但我不建议这样做(特别是如果您已经将 master 推送到另一个状态)。

    要更明确地回答您的问题“如果我将我的 HEAD 切换回 master,这些提交会丢失吗?”,答案是“最终,是,但立即,不是。”。您可以检查提交的显式 SHA1 ID(并使用 git reflogHEAD@{1} 语法查找那些)。但是如果你不给它们附加一个命名的引用,它们就会消失。

    【讨论】:

    • 感谢您的详细回答。是否可以现在给分支B -> B1 -> B2 起一个名字并推送它?还是我应该签出B,创建一个新分支,将B1, B2 合并到该分支然后推送它?
    • 是的,你可以给分支起个名字。 git checkout -b new_name B2(使用B2 的SHA1 哈希)将创建一个new_name 分支,其HEADB2。如果您已经在B2 上,则只需git branch new_name 而不是使用checkout -b 方法。
    【解决方案4】:

    使用 --interactive 选项检查 git rebase。

    【讨论】:

      猜你喜欢
      • 2012-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-18
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 2017-12-22
      相关资源
      最近更新 更多