重组git repo

时间:2018-08-30 13:31:16

标签: git github package

我有一个像这样的git repo结构-

main-repo
  -file1
  -file2

我想将其转换为类似的东西-

main-repo
   -javascript
       -file1
       -file2

,然后再添加另一种语言,如

main-repo
    -javascript
        -file1
        -file2
    -python
        -file1
        -file2

鉴于我已经进行了几次提交,并且在travis.yml中配置了测试以在推送至主服务器上运行时,如何执行此操作。

2 个答案:

答案 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,但今天不要检出。 :)