改变git分支的根目录,保留旧的提交作为分支head?

问题描述 投票:0回答:1

如果我的措辞不对,请原谅我,但我有的是 mastermaster-variant 其中后者是我正在研究的通用产品的一个变体。它包含了额外的文件和一些修改过的文件。

问题是我是 "反向 "创建的,因为我从变种开始,现在需要这个新的通用 "根",因为我将在它的基础上添加其他新的变种。

所以我从最初的变体开始,在 master 并建立了一个分支 master-variant 的当前状态,而不做任何修改(即它指向与 master).

然后我修改了 master 使之成为 "通用的",即删除所有与变量有关的东西,并将其提交到那里。在这种状态下。master 相比之下,有一个新的提交。master-variant 指向。

但我想让它看起来就像我一开始用的是通用的 master (最后一次提交),然后分支到 master-variant 的状态,并添加了变量特有的东西,即在 master.

我试着说明一下。我所拥有的是这样的(m = master, v = master-variant):

m0---m1---m2---m3 (changes to create generic variant)
           \
            v1 (just a new ref to m2)

注意: m0..m2 ...是在 master 枝,但其 内容 是原来的变体,现在我想把它放在一个分支中。

我想把它改成这样。

m0---m1---m2---m3 (same as above, the generic variant)
                \
                 v1 (same content as "v1" above, which is also the same content as "m2" in both illustrations)

我怎么才能做到这一点?

我首先想到的是使用 git rebase但我不明白这怎么可能,因为它做的是重播提交,而我需要重播的是 反面 的反面,也就是说,在提交的过程中。m3 提交。

我想我可以把 m2v1 删去 master-variant 枝,切换到 master 承诺 m3),弹出stashed状态,并将其提交到一个新的 master-variant 枝。

但是有没有更直接的方法呢?

简而言之,我想我真正想要的是创建一个包含历史提交状态的分支,但这个分支的根在 HEAD(而不是历史提交)。

git branch git-rebase git-rewrite-history
1个回答
1
投票

提醒:提交 文件状态的快照。 提交本身形成了提交图,而提交图中的 分支名称 是简单的标签,用于识别(指向)一个特定的提交。

你在图中说过。v1 是字面意思 提及 承诺 m2. 也就是说,它还不是一个独立的提交。 所以你真正拥有的是

C0--C1--C2   <-- v1
          \
           C3   <-- master

哪儿 v1master 是指向由提交本身形成的图的标签(名称),这些标签就是 C0 通过 C3. 您所描述的您想要的图增加了一个新的提交。C4 其内容与 C2 但其父级(历史提交就在自己后面)是C3。

C0--C1--C2    C4   <-- v1
          \  /
           C3   <-- master

既然如此,你有两个相对简单的选择。 一个是进入 Git 的所谓 水管命令 并使用命令创建一个新的提交,给它一个特定的保存的快照和父节点集。 新的提交就是你的 C4. 然后,在复制了 C2C4你会把名字移到 v1 指向 C4. 两个特定的Git命令是

hash=$(git commit-tree -p master v1^{tree} -F /tmp/message)

其中 /tmp/message 包含了您想使用的提交日志信息。 请注意,有些shell可能会将 ^{ 字符;如果是,请引用它们。 然后您可以运行 git log $hash 来验证提交是否正确。 然后,如果你现在是 "在 "分支上的 v1:

git reset $hash

将调整 v1 标签。 确保你的索引和工作树是干净的,也就是说,没有任何未提交的东西可以保存)。 如果没有。

git branch -v v1 $hash

将调整 v1 标签。

或者,考虑到 还原 承诺 C3 会收回它的修改,并给您留下一个新的提交,以符合 C2. 所以你可以。

git checkout v1
git merge --ff-only master

这将产生。

C0--C1--C2
          \
           C3   <-- v1 (HEAD), master

然后你只需运行:

git revert HEAD

进行一个新的提交,以回退这两者之间的差异。C2C3,给你一个新的承诺 C4:

C0--C1--C2    C4   <-- v1 (HEAD)
          \  /
           C3   <-- master

然后你又完成了。

如果你有很多承诺要恢复--即,如果你想。

C0--C1--C2   <- v1
          \
           C3--C4--C5   <-- master

变成:

C0--C1--C2            C6   <- v1
          \          /
           C3--C4--C5   <-- master

那么... git commit-tree 方法的工作量较小(尽管您仍然可以使用 git revert,你只需要 -n 在这种情况下,在恢复 C5, C4C3或随后的 git rebase -i 的地方,你把所有新提交的内容压在一起)。) 换句话说 git commit-tree 正是实现这一目标的工具。

...我真正想要的是创建一个包含历史提交状态的分支,但这个分支的根在HEAD(而不是历史提交)。

© www.soinside.com 2019 - 2024. All rights reserved.