我有一个像这样的git repo结构 -
main-repo
-file1
-file2
我想把它转换成像 -
main-repo
-javascript
-file1
-file2
然后再用另一种语言添加另一个repo
main-repo
-javascript
-file1
-file2
-python
-file1
-file2
如何做到这一点,因为我已经有几个提交和测试在travis.yml中配置为在push to master上运行。
最简单的方法就是移动文件并进行新的提交。这可能是也可能不够。一方面,当然你还没有你要添加的python文件的历史记录,所以这将为完整的历史记录腾出空间。另一方面,单个文件的早期历史可能并不总是以您喜欢的方式显示(因为git对文件移动的处理虽然不错,但并不完美)。
另一个选择是重写repo的历史记录,使其看起来总是具有所需的目录结构。你可以用git filter-branch
做到这一点。如果repo相当小,那么你可以使用类似的脚本传递--tree-filter
参数
mkdir javascript
mv file1 file2 javascript
(或mv *.js javascript
,或任何有意义的)。
这个操作非常慢,但对于只有“几个”提交的相对较新的repo,它应该是合理的。
有关更多详细信息,请参阅git filter-branch文档。 https://git-scm.com/docs/git-filter-branch
我有一个像这样的git repo结构 - ...我想把它转换成类似的东西......
在存储库中移动文件没有任何问题。但是,即使Git可以自动检测文件移动(因为有些会消失,而其他一些会出现,具有完全相同的内容),所以有一个专门的命令来执行此操作:
git mv <source> <destination>
该文件将自动移动,这将显示在git status
的报告中。因此,您需要提交记录此内容。
这样做总是一个好主意,因为如果不是真的需要,总是希望避免在git存储库中重命名/移动文件。这是因为它打破了这些给定文件的连续历史记录,并使它们难以追溯。
每个提交应该独立于其他提交,即使每个提交都引用前一个(或合并时的提交)。它们基本上是一个完全限定文件名列表,每个文件名都指向它们各自的内容,这使您可以轻松地比较(使用git diff
)任何两个提交,无论它们位于图形中的哪个位置。
这真的很强大,但缺点是git依赖于文件名来知道要比较什么。如果提交和下一个提交之间只有少数名称更改,git会猜测它们实际上是哪些。但是,如果您同时引入文件更改和名称重命名,或者重命名文件并创建另一个具有相同内容的文件,则会混淆。
通过使用git mv
,您可以让Git有机会存储所有必需的信息,以帮助它完成此任务。此外,在其他一些工作方式不同的SCM中,这可能是强制性的。
然后再用另一种语言添加另一个repo
没什么特别的。只需添加您在开头时所做的额外内容(不要忘记提交),但要注意Git无法处理空目录。因此,您需要在“python”目录中添加至少一个文件。这也意味着一旦删除了给定目录中最后一个文件,目录本身也会在下次结帐时自动消失。不要对此感到惊讶。
这是因为,如前所述,Git只考虑文件(即使它仍然能够处理符号链接和特殊文件)并通过维护完全限定的文件名来跟踪它们各自的位置(例如“/ dirname”) /基名“)。因此它无法处理最后没有叶子的分支。
此外,如果你的“javascript”和“python”目录没有任何关系(没有给定的独特项目的部分),你最好把它们变成多个独立的git存储库。请记住,即使已经有一些东西,你总是可以使用git init
初始化一个新的存储库。
最后,当您达到想要在更大的存储库中创建存储库的位置时,例如公开共享小存储库,同时保留一些关于它的其他信息,或者在处理其中一个库的大型项目时是一个独立的项目,你想要检查git submodule
,但不是今天。 :)