2013-03-01 67 views
1

在Git中,可以做这样的事情吗?Git新提交作为项目的旧版本

master B - C - D 

要这样吗?

master A - B - C - D 

我已经有一个使用Git的项目,一切都很顺利。但是我发现该项目的旧版本,我希望将它提交给相同的回购,但将其作为A,并使其看起来像它是该项目的最早版本。在Git中可以做到这一点吗?或者还有其他解决方法吗?

回答

2

是的,这样做很容易,但是我会从标准警告开始,知道它会将B-C-D更改为B'-C'-D',也就是说,它们会有新的提交哈希,并且会与任何现有的克隆发生冲突的存储库。假设你的罚款...

我们从理解git被组织为一系列提交,每个都有一个指向它的父(s)的指针。通过这种方式创建了一个提交树。

tree 1: B - C - D 

因为什么你想要做的是前第一添加的东西提交 - 并没有什么解决之前,首先提交 - 我们必须创建一个新的树来做到这一点。

要创建一棵新树,我们将从空提交开始。作为存储库的第一次提交,提交一个空提交会让事情变得更容易。这是通过下面的命令(增加供以后参考号码)

git checkout --orphan new-branch   (1) 
git rm -r --force --cached .    (2) 
git clean -fd        (3) 
git clean -fd        (3a) 
git commit --allow-empty -m 'Initialize' (4) 

此创建未连接到任何其他分支(1)一个新的分支进行。这将工作目录中的所有文件都缓存并准备好提交。我们不想提交这些文件,所以(2)将它们从缓存中删除; (3)将它们从目录中删除。有时需要清理两次,因为忽略的文件不会被清理,但.gitignore文件将会 - 需要再次清理文件。

最后,(4)创建一个空提交作为此分支中的第一个提交。 --allow-empty参数使这成为可能 - 任何消息都可以做到。

现在,添加项目早期版本A的所有文件,然后执行。

git add . 
git commit -m 'A' 


------------------ 
tree 1: B - C - D 
tree 2: A 

我们准备将B-C-D移动到A。虽然仍然在new-branch,这个命令会移动它们。

git rebase -i --onto new-branch --root D 

这将签D,在树内(退)回到根B动人每次提交,依次将A - 制作新提交的每一步,直到它回来给D注意:很有可能你会在这里合并冲突,准备好处理它们。

完成后的树是这个样子

tree 1: <empty>    <-- this will be garbage collected in time 
tree 2: A - B' - C' - D' 

此时推回你的任何远程仓库 - 你将需要强制推送

git push --force <remote> <local-branch>:<remote-branch> 

这将覆盖远程分支 - 确保这是你想要的

就是这样。请记住,不要仅处理存储库的唯一副本,以便在重新克隆并重新尝试时重新尝试。除此之外,我建议您阅读git rebase ...,以便您熟悉正在发生的事情 - 以及您可能遇到的问题,具体取决于您实际存储库中B-C-D的复杂程度。

1

您可以将A添加为新的提交,然后在B(rebase -i B~1)之前将提交的交互重新赋值为提交,以便按照您的要求对提交进行重新排序?

0

总之,没有。

Git中的每个提交都由一个散列表示,“父”提交是散列生成的一个元素。

因此,如果你改变B的母公司,B将不再是B(即哈希将不再是相同的)

你仍然可以这样做,通过重订,您创建的第一和在A上重新分配B,C,D ...但是,正如我之前所说的,哈希将不再相同。如果它适合你,那么继续为此:)

1

是的,有一个警告。比方说,你开始:

 
B - C - D 

其结果将是

 
A - B' - C' - D' 

注“地王”标记B”将具有相同(内容)为B,但它会一个不同的SHA-1哈希,因为它的父项是不同的。

最简单的方法是使用移植物。创建一个同时包含A和B的存储库:

 
A 

B - C - D 

注意它们如何不互相连接。您将它们与“嫁接”(Wiki page),这使得B的家长互相连接...

 
A 
\ 
    ... 
    \ 
     B - C - D 

我用虚线因为移植是暂时的。

 
<hash of B> <hash of A> 

移植物永久使用以下命令:移植物是通过编辑.git/info/grafts和写作创造

 
git filter-branch --tag-name-filter cat -- --all 

这将更改图表:

 
A - B' - C' - D' 

使其后永久,删除移植文件。

通常的警告适用 - 您正在重写历史记录,因此,只要没有本地更改,那么已经拉动存储库的任何人都必须使用git reset

相关问题