如何在服务器上用符号链接替换文件夹

时间:2018-11-22 13:28:15

标签: bash git gitignore symlink

我们有一个用于科学软件的git存储库,需要在其中为数据文件维护特定的文件夹结构。 这些文件夹应保持为空,git不应跟踪将放置在其中的所有内容。但是,必须存在这些文件夹。

解决方案是在每个目录中添加一个.gitignore文件,如下所示:

*
!.gitignore

,这意味着该文件夹中的所有内容都将被忽略,除了.gitignore文件。

这很好用。

我们将所有数据保存在一台特定的服务器上。 我们的科学家经常使用此服务器进行计算。 能够替换git存储库中的当前仅包含.gitignore文件的数据文件夹,并以指向该服务器上完整数据文件的符号链接进行替换。服务器上的数据文件还具有一个.gitignore文件,该文件看起来与每个存储库中的文件完全相同。

我编写了一个bash脚本来执行此操作,如下所示:

rm -r path/to/empty/data/in/repository/name
ln -sfn /absolute/path/to/data/on/server/ path/to/empty/data/in/repository

现在,该软件可以完美运行,您可以访问所有数据,而无需将其复制到git存储库中。

但是,git现在变得困惑了。

如果我运行git status,则仅列出我的更改。它不会抱怨新的符号链接取代了现有目录。

运行git add .进行更改时,符号链接将显示为new file:,替换文件夹中的.gitignore文件将列为deleted:

对我来说这似乎是个问题,因为只要有人推送他在服务器上所做的代码更改,符号链接就会被上传(我想),.gitignore文件将被删除,因此该文件夹结构将不会保留。

是否可以告诉git它应该比较符号链接文件夹的内容而不是符号链接本身?

PS:我知道这似乎是git内部包含静态文件夹结构的软件设计问题,但我不想在此讨论。我们都是科学家,而不是程序员,并且该软件由许多不同的人开发超过10年。无法更改代码以使其更灵活。

编辑:此bash代码重现了该问题:

cd ~            #setup
mkdir tmp
cd tmp

mkdir server    #server data folder (this one is full of data)
mkdir server/data
printf '*\n!.gitignore' > server/data/.gitignore
printf 'data file 1' > server/data/data1.txt
printf 'data file 2' > server/data/data2.txt

mkdir repo      #repo data folder (this one only contains .gitignore file)
mkdir repo/data
printf '*\n!.gitignore' > repo/data/.gitignore

cd repo              # create a dummy repo
git init
git add .
git commit -am"commit 1"

git status

cd ..              # replace data folder with server/data folder which hase exactly the same content
rm -r repo/data/
ln -sfn ~/tmp/server/data/ ./repo/

cd repo
git status

理想情况下,git状态最后不应列出存储库中的任何更改。

编辑: 我找到了一种解决方法:不是链接整个目录,而是链接目录的内容:

ln -sfn /absolute/path/to/data/on/server/* path/to/empty/data/in/repository/

之所以可行,是因为.gitignore文件会忽略符号链接。 缺点是它仅适用于现有数据。服务器目录中一旦有新文件,我就必须再次运行bash脚本。

1 个答案:

答案 0 :(得分:1)

Git跟踪符号链接。您想要实现的目标可以通过绑定安装来完成。

将最终的ln -sfn ~/tmp/server/data/ ./repo/替换为sudo mount --bind $PWD/repo $HOME/tmp/server/data/