在Git中,可以做这样的事情吗?Git新提交作为项目的旧版本
master B - C - D
要这样吗?
master A - B - C - D
我已经有一个使用Git的项目,一切都很顺利。但是我发现该项目的旧版本,我希望将它提交给相同的回购,但将其作为A,并使其看起来像它是该项目的最早版本。在Git中可以做到这一点吗?或者还有其他解决方法吗?
在Git中,可以做这样的事情吗?Git新提交作为项目的旧版本
master B - C - D
要这样吗?
master A - B - C - D
我已经有一个使用Git的项目,一切都很顺利。但是我发现该项目的旧版本,我希望将它提交给相同的回购,但将其作为A,并使其看起来像它是该项目的最早版本。在Git中可以做到这一点吗?或者还有其他解决方法吗?
是的,这样做很容易,但是我会从标准警告开始,知道它会将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
的复杂程度。
您可以将A添加为新的提交,然后在B(rebase -i B~1
)之前将提交的交互重新赋值为提交,以便按照您的要求对提交进行重新排序?
总之,没有。
Git中的每个提交都由一个散列表示,“父”提交是散列生成的一个元素。
因此,如果你改变B的母公司,B将不再是B(即哈希将不再是相同的)
你仍然可以这样做,通过重订,您创建的第一和在A上重新分配B,C,D ...但是,正如我之前所说的,哈希将不再相同。如果它适合你,那么继续为此:)
是的,有一个警告。比方说,你开始:
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
。