将文件移动到单独的存储库而不移动磁盘上的文件

时间:2017-02-08 13:13:38

标签: git repository-design

此问题与例如How to move files from one git repo to another (not a clone), preserving history有关 Detach (move) subdirectory into separate Git repository但问题(或者至少解决方案,我认为)是不同的。我有以下目录结构:

abc/
    .git/
    def/
       file1.txt
       file2.txt
    xyz/
       file3.txt

目录abc是git存储库的根,比如repo1

我想要的是将file2.txt放在另一个存储库repo2(本地并链接到远程)。但是,我不想将file2.txt移出目录(如相关问题)。所有其他文件和文件夹(def, file1.txt, xyz/*)必须保留在repo1

当我执行git commitgit push时,对file1.txt的更改应转到repo1,对file2.txt的更改应转到repo2

作为一种解决方法,我可以在def中创建一个额外的目录,然后在那里移动file2.txt,如果这样可以更容易。但是,我不想将file2.txt移出当前树。

file2.txt的历史不一定需要保留在这一行动中。

1 个答案:

答案 0 :(得分:1)

首先,确保提交或存储任何更改,并且您的工作树是干净的。运行git status以确定。

可以通过两个简单的步骤来实现目标。

  1. abc/def中创建一个新的空仓库。将其配置为忽略除file2.txt之外的所有内容(您希望以与file2.txt相同的方式处理任何其他文件)。将.gitignorefile2.txt添加到新的repo并提交:

    $ cd abc/def
    $ git init
    $ echo '*' > .gitignore
    $ echo '!/file2.txt' >> .gitignore
    $ git add .
    $ git status
    $ git commit
    

    仔细阅读git status的输出,并确认它仅将所需文件添加到repo中。提交一切正常或调整.gitignore和索引,直到达到您需要的状态。

  2. 转到abc repo,将def/file2.txtdef/.gitignore添加到此repo的忽略列表中,从索引中删除def/file2.txt并提交:

    $ cd ..
    $ echo '/def/file2.txt' >> .gitignore
    $ echo '/def/.gitignore' >> .gitignore
    $ git rm --cached def/file2.txt
    $ git status
    $ git commit
    

    再次,在提交之前阅读git status的输出。

  3. 说明

    您可以照常使用这两个回购。它们是独立的,它们不以任何方式链接(除了每个repo配置为忽略由另一个repo管理的文件的事实)。

    如果您不将内部仓库推送到远程位置,我建议您将.git目录(存储库本身)移到abc目录之外的某处,以防止意外删除。命令很简单。在abc/def目录内运行:

    git init --separate-git-dir=/path-where-to-move-the-git-dir
    

    您可以在创建abc/def repo时运行此命令行,也可以在此之后运行它。回购中包含的数据是安全的。它只会将回购移动到指定的位置。