本地跟踪文件,但不允许将它们推送到远程仓库

22
我正在处理一个涉及使用非常敏感数据的项目,并被指示只能通过自定义文件传输系统在线传输此数据。该项目本身处于git源代码控制下,包括一个包含敏感数据的sqlite文件。
到目前为止,我一直在gitignore文件中忽略sqlite文件,以防止它被推送到远程存储库。然而,现在我已经达到了项目的一个阶段,在这个阶段中我们有一个生产版本和一个开发版本,而事实上数据没有被本地跟踪,这使得使用分支变得非常困难。
因此,我的问题是:是否有一种方法让我在本地跟踪sqlite文件,这样我就可以在不同的分支上拥有不同的数据版本,但永远不会将其推送到远程存储库?
在阅读这个问题之后,我考虑使用仅限本地的开发分支,使用不同的gitignore文件,但是合并到共享的远程分支时,gitignore文件的更改也会被合并,这很快就会变得繁琐。

这里适用于“如何处理公共git仓库中的敏感数据?”这个问题的答案。 - Lazy Badger
3个回答

7

好的,我实际上想到了一个更好的解决方案来解决这个问题。我的先前的解决方案涉及到第二个git存储库,由于我正在处理的sqlite文件的大小,git不能处理大文件,因此很快就出现了问题。我研究了各种改善git处理这些文件的方法(例如git-bigfilesgit-annex),但是没有什么优雅地解决我的情况。

答案:使用符号链接。

N.B.这个解决方案相当Unix特定,但您可能能够调整它以适用于非Unix系统。

问题#1:确保数据永远不会发送到远程存储库。

这个很容易。与我以前的解决方案类似,我将数据存储在存储库之外。

Root-Directory/
    My-Project/
        .git/
        Source-Code-and-Stuff/
    My-Project-Data/
        A-Big-Sqlite-File.sqlite

因为数据文件不在代码库中,所以不需要担心它们被git索引。

问题#2:不同分支应该引用数据的不同版本。

这就是符号链接发挥作用的地方。符号链接实际上是指向文件的快捷方式,因此想法是将指向数据文件的符号链接放置在代码库内。符号链接被git索引(并且它们非常小),因此不同的分支可以有不同的符号链接。

为了解释这一点,让我们以一个示例项目为例,该项目在master分支上有当前版本(1.1); 在version-1.2分支上有一个新版本(1.2)。为简单起见,该项目仅具有一个数据文件:Data.sqlite

数据文件存储在上述My-Project-Data目录中,并按如下方式在文件系统上进行版本控制:

My-Project-Data/
    v1.1/
        Data.sqlite
    v1.2/
        Data.sqlite

使用符号链接将数据文件添加到存储库中:

My-Project/
    .git/
    Source-Code-and-Stuff/
        Data-Symlink.sqlite

分支上,Data-Symlink.sqlite是。
../../My-Project-Data/v1.1/Data.sqlite

版本1.2分支上,它是这样的

../../My-Project-Data/v1.2/Data.sqlite

所以,当开始1.3版本的开发时,以下Bash脚本将设置所有内容:
# Get to the root directory
cd path/to/Root-Directory
# Enter the data directory
cd My-Project-Data
# Make a directory for the new version and enter it
mkdir v1.3
cd v1.3
# Copy the new sqlite file into it
cp ~/path/to/data/file.sqlite Data.sqlite
# Move to the project directory
cd ../../My-Project
# Create a new branch
git checkout -b version-1.3
# Move to the source code directory and delete the current symlink
cd Source-Code-and-Stuff
rm Data-Symlink.sqlite
# Create a symlink to the new data file
ln -s ../../Project-Data/v1.3/Data.sqlite Data-Symlink.sqlite
# Commit the change
cd ../
git add Source-Code-and-Stuff/Data-Symlink.sqlite
git commit -m "Update the symlink"

结论

显然这不是一个完美的解决方案。如果你在团队中工作,团队中的每个人都需要有相同的相对目录 - 符号链接是相对路径,因此到根目录的绝对路径可能会改变,但我的项目我的项目数据必须存在于其中。但我个人认为收益超过了这个小缺点。在我正在使用这种技术的实际项目中,我有一个800MB的sqlite文件用于数据,在生产和开发分支之间切换,并使我的项目自动更新数据文件是无价的。


3

本地跟踪文件,但永远不允许将它们推送到远程存储库

实际上你做不到。

Git 跟踪你的仓库的快照。这些快照是通过 git pushgit pull 来进行操作,如果一个文件在快照中,它(通常)会被包含在 git push 等操作中。

你最好的选择是使用 git submodule 来保存敏感数据。这个问题 对这个解决方案进行了详细说明。


与其他答案一样,当您包含另一个远程存储库时,子模块会被使用,但我正在使用的数据必须保持离线状态。 - Ell Neal
什么?你可以很好地使用本地存储库与子模块。 - Asherah
@Len 另一个存储库不是答案,看看我的实际解决方案,它可以解决这个问题。 - Ell Neal
@EllNeal:这不是我在争论的问题,你说“子模块是用于包含另一个远程仓库”,而我说“你可以很好地使用子模块与本地仓库”。:)答案是另一个问题。 - Asherah

0

我想花点时间解释一下我的解决方案:

我为我的项目创建了一个根目录:MyRootDirectory。在MyRootDirectory中,我有两个目录,分别称为MyProjectMyProjectDataMyProjectMyProjectData都是git存储库,其中MyProject在github上有一个远程对应项,而MyProjectData是仅本地存储库。在我的项目文件中(我正在使用Xcode),我使用如下路径引用数据文件:../MyProjectData/MyDatabase.sqlite

这个结果使我能够为数据和项目拥有开发和主分支;数据包含在构建产品中,因为它存在于项目索引中,但它从未被推送到远程存储库,因为只有其路径包含在本地存储库中。神奇。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接