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

时间:2012-03-04 16:49:23

标签: git github

我正在开展涉及使用非常敏感数据的项目,并且我已被指示仅通过自定义文件传输系统在线传输此数据。项目本身在git源代码控制之下,包含一个包含敏感数据的sqlite文件。

到目前为止,我只是通过gitignore文件忽略了sqlite文件,这阻止了它被推送到远程存储库。但是,我现在已经达到了项目的一个点,我们有一个实时版本和一个开发版本,并且数据没有在本地跟踪这一事实使得使用分支非常困难。

所以我的问题是:有没有办法让我在本地跟踪sqlite文件,所以我可以在不同的分支上拥有不同的数据版本,但从未将它推送到远程存储库?

在阅读this question后,我考虑使用仅限本地的开发分支,这些分支使用不同的gitignore文件,但是git merge进入远程共享的事实分支也会合并gitignore文件的更改很快就会变得很麻烦。

3 个答案:

答案 0 :(得分:7)

好的,所以我实际上想出了一个更好的解决方案来解决这个问题。由于我正在使用的sqlite文件的大小,My previous solution涉及第二个git存储库,很快就成了问题。 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索引(并且它们非常小),因此不同的分支可以有不同的符号链接。

为了解释这一点,我们来看一个示例项目,它在分支上有一个当前实时版本(1.1);和版本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"

结论

显然这不是一个完美的解决方案。如果您正在与团队合作,团队中的每个人都需要具有相同的相对目录 - 符号链接是相对路径,因此 Root-Directory 的绝对路径可以更改,但 My - 项目我的项目数据 必须存在于其中。但我个人认为,这些好处超过了这个小小的警告。在实际项目中,我使用这种技术,我有一个800MB的sqlite文件用于数据,并且能够在实时和开发分支之间切换,让我的项目自动更新数据文件是无价的。

答案 1 :(得分:3)

  

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

你不能,真的。

Git跟踪存储库的快照。这些快照是git pushedgit pulled - 如果快照中的文件,它(通常)将包含在git push等中。

您最好的选择是使用git submodule来保存敏感数据。 This question详细介绍了该解决方案。

答案 2 :(得分:0)

我想花一点时间来解释我对这个问题的解决方案:

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

这个结果允许我为数据和项目提供开发和主分支;数据包含在构建的产品中,因为它存在于项目索引中,但它永远不会被推送到远程存储库,因为它的路径只包含在本地存储库中。魔法。