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

Move file to separate repository without moving file on disk

此问题与例如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的历史不一定需要保留在这一步

首先,确保您提交或存储任何更改并且您的工作树是干净的。 运行 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 的输出并确认它仅将所需的文件添加到存储库中。如果一切正常,请提交或调整 .gitignore 和索引,直到它们达到您需要的状态。

  2. 转到 abc 仓库,将 def/file2.txtdef/.gitignore 添加到此仓库的忽略列表中,从索引中删除 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 的输出。

备注

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

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

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

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