Git:在一个命令中将提交链复制到其他提交,不涉及任何分支
Git: Copy a chain of commits to some other commit, no branches involved, in one command
我有这些提交:(下面的 TL;DR...)
A <- B <- C
这些是在同事提交的基础上:
U <- V <- W <- A <- B <- C
现在同事将他的分支重新定位到新的 master
,推送到更新 PR 的 github 仓库,然后添加一个提交,推送到 github 仓库,然后我解决了github 上的冲突并提交到 github 上的分支,然后同事压缩了两个提交并添加了另一个,然后我们的团队领导插话并开始编辑 git 集线器编辑器。所以它最终是这样的:[1]
X' <- A'' <- U -> C <- W -> B ---> L --> O --> O
<--- master' / | / <------ master
G ---------> M --/ \- abyssmal' <-- P --/
换句话说,原来的分支变得非常无关紧要,事物的新状态与原来的状态关系不大。我认为没有 git 操作分支的命令可以使用 .我只想利用我工作的残余(以几次连续提交的形式)并尝试使其适应今天的代码库。
我写这个故事是因为通常人们会尝试为我的潜在问题提供解决方案,这很好,但我更愿意知道这个特定的操作,如果 github 有办法做到这一点。另外,我说没有分支是因为只要很少有人在一个分支上工作,事情就会很快变得混乱并且分支失去任何意义。缺乏纪律或以错误的方式使用 Git。我知道。不解决这个问题,我会很高兴解决这个问题。
对我来说重要的是:
TL;DR:
如何在一个命令中将任何提交链(假设它们被链接)复制到其他提交? IE。我有:
...hicSuntLeones <- myCommitA <- myCommitB <- myCommitC <- whatever...
我想要一个超级简单的命令:
git copyCommits --since myCommitA --until myCommitC --putThemTo terraInrecognita
我希望它像这样结束:
...terraIncognita <- myCommitA' <- myCommitB' <- myCommitC'
当然要解决中间冲突。
我正在查看 git rebase --onto
,但这似乎适用于我需要的不同逻辑 - 它会让我 "divorce" 另一个分支,但我没有那个分支。如果我没理解错的话。
我在 stack overflow 和 web 上四处寻找,但还是找不到。 git 答案倾向于解释 git 如何工作,how git rebase works, what is the contrast of the design philosophy of git with the philosophy of a more traditional source control tool like svn, how SCM works in general, how the 和其他事情。我不想听起来傲慢,但我只是在寻找执行上述操作的命令。有没有?谢谢:)
[1] 其实并没有那么糟糕,只是正常的日常混乱。但它仍然使这种方法比在分支中思考更容易。
编辑:未提供答案:
这个引用的副本,也在问题中引用,没有回答我的问题。它对 git 如何工作、分支机构如何工作有很长的答案,但并没有真正回答我的问题。也许它暗示在那里但没有给出。
你想要的只是git cherry-pick
,它可以选择一个提交链。
这将需要两个命令(除非您编写自己的脚本),因为您需要 git checkout
您希望副本到达的位置。然后,如果要复制的第一个提交是 S(开始),最后一个是 E(结束):
git cherry-pick S^..E
您需要 hat-suffix 来使范围包含提交 S 本身。
我的第一个想法是 git rebase
。在 man git-rebase
页面中有一个带有三个参数的 rebase
有这个很好的例子(以及许多其他例子):
H---I---J topicB
/
E---F---G topicA
/
A---B---C---D master
$ git rebase --onto master topicA topicB
H'--I'--J' topicB
/
| E---F---G topicA
|/
A---B---C---D master
使用以下命令可以在您的存储库中实现类似的效果。
首先我们用我们感兴趣的最后一次提交创建一个分支,然后检查它:
$ git checkout -b newC myCommitC
然后我们将这个分支变基到想要的地方。不要忘记指定第一个提交的父级,因为你必须告诉最后一个提交不包含在 rebase 中;
$ git rebase --onto terraIncognita myCommitA^ newC
大功告成!现在你有 newC 指向新分支的尖端:
terraIncognita <- myCommitA' <- myCommitB' <- myCommitC'
我有这些提交:(下面的 TL;DR...)
A <- B <- C
这些是在同事提交的基础上:
U <- V <- W <- A <- B <- C
现在同事将他的分支重新定位到新的 master
,推送到更新 PR 的 github 仓库,然后添加一个提交,推送到 github 仓库,然后我解决了github 上的冲突并提交到 github 上的分支,然后同事压缩了两个提交并添加了另一个,然后我们的团队领导插话并开始编辑 git 集线器编辑器。所以它最终是这样的:[1]
X' <- A'' <- U -> C <- W -> B ---> L --> O --> O
<--- master' / | / <------ master
G ---------> M --/ \- abyssmal' <-- P --/
换句话说,原来的分支变得非常无关紧要,事物的新状态与原来的状态关系不大。我认为没有 git 操作分支的命令可以使用 .我只想利用我工作的残余(以几次连续提交的形式)并尝试使其适应今天的代码库。
我写这个故事是因为通常人们会尝试为我的潜在问题提供解决方案,这很好,但我更愿意知道这个特定的操作,如果 github 有办法做到这一点。另外,我说没有分支是因为只要很少有人在一个分支上工作,事情就会很快变得混乱并且分支失去任何意义。缺乏纪律或以错误的方式使用 Git。我知道。不解决这个问题,我会很高兴解决这个问题。
对我来说重要的是:
TL;DR:
如何在一个命令中将任何提交链(假设它们被链接)复制到其他提交? IE。我有:
...hicSuntLeones <- myCommitA <- myCommitB <- myCommitC <- whatever...
我想要一个超级简单的命令:
git copyCommits --since myCommitA --until myCommitC --putThemTo terraInrecognita
我希望它像这样结束:
...terraIncognita <- myCommitA' <- myCommitB' <- myCommitC'
当然要解决中间冲突。
我正在查看 git rebase --onto
,但这似乎适用于我需要的不同逻辑 - 它会让我 "divorce" 另一个分支,但我没有那个分支。如果我没理解错的话。
我在 stack overflow 和 web 上四处寻找,但还是找不到。 git 答案倾向于解释 git 如何工作,how git rebase works, what is the contrast of the design philosophy of git with the philosophy of a more traditional source control tool like svn, how SCM works in general, how the
[1] 其实并没有那么糟糕,只是正常的日常混乱。但它仍然使这种方法比在分支中思考更容易。
编辑:未提供答案:
你想要的只是git cherry-pick
,它可以选择一个提交链。
这将需要两个命令(除非您编写自己的脚本),因为您需要 git checkout
您希望副本到达的位置。然后,如果要复制的第一个提交是 S(开始),最后一个是 E(结束):
git cherry-pick S^..E
您需要 hat-suffix 来使范围包含提交 S 本身。
我的第一个想法是 git rebase
。在 man git-rebase
页面中有一个带有三个参数的 rebase
有这个很好的例子(以及许多其他例子):
H---I---J topicB
/
E---F---G topicA
/
A---B---C---D master
$ git rebase --onto master topicA topicB
H'--I'--J' topicB
/
| E---F---G topicA
|/
A---B---C---D master
使用以下命令可以在您的存储库中实现类似的效果。
首先我们用我们感兴趣的最后一次提交创建一个分支,然后检查它:
$ git checkout -b newC myCommitC
然后我们将这个分支变基到想要的地方。不要忘记指定第一个提交的父级,因为你必须告诉最后一个提交不包含在 rebase 中;
$ git rebase --onto terraIncognita myCommitA^ newC
大功告成!现在你有 newC 指向新分支的尖端:
terraIncognita <- myCommitA' <- myCommitB' <- myCommitC'