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