我们有一个用于科学软件的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脚本。
答案 0 :(得分:1)
Git跟踪符号链接。您想要实现的目标可以通过绑定安装来完成。
将最终的ln -sfn ~/tmp/server/data/ ./repo/
替换为sudo mount --bind $PWD/repo
$HOME/tmp/server/data/