【问题标题】:Track files locally, but never allow them to be pushed to the remote repository在本地跟踪文件,但绝不允许将它们推送到远程存储库
【发布时间】:2012-03-22 08:15:24
【问题描述】:

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

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

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

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

【问题讨论】:

标签: git github


【解决方案1】:

好的,所以我实际上想出了一个更好的解决方案来解决这个问题。 My previous solution 涉及第二个 git 存储库,由于我正在使用的 sqlite 文件的大小,它很快就出现了问题; git 无法处理大文件。我研究了各种方法来提高 git 处理文件的能力(例如git-bigfilesgit-annex),但似乎没有什么能优雅地处理我的情况。

答案:符号链接。

注意这个解决方案是 Unix 特有的,但您可能可以为非 Unix 系统重新设计它。

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

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

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

由于数据文件不在存储库中,因此无需担心它们会被 git 索引。

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

这就是符号链接发挥作用的地方。符号链接实际上是文件的快捷方式,因此想法是将符号链接放入存储库中的数据文件。符号链接由 git 索引(它们非常小),因此不同的分支可以有不同的符号链接。

为了解释这一点,让我们以一个示例项目为例,该项目在 ma​​ster 分支上有一个当前运行的版本 (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

ma​​ster 分支上,Data-Symlink.sqlite

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

version-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 -ProjectMy-Project-Data 必须 存在于其中。但我个人的观点是,好处超过了这个小警告。在实际项目中,我正在使用这种技术,我有一个 800MB 的 sqlite 数据文件,能够在实时和开发分支之间切换并让我的项目自动更新数据文件是无价的。

【讨论】:

    【解决方案2】:

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

    你不能,真的。

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

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

    【讨论】:

    • 与其他答案一样,当您包含另一个 remote 存储库时会使用子模块,但我使用的数据必须保持离线状态。
    • 什么?您可以将子模块与本地存储库一起使用。
    • @Len 另一个存储库不是答案,请参阅我的实际解决方案来解决问题。
    • @EllNeal:这不是我在这里讨论的内容,你说“当你包含另一个 remote 存储库时使用子模块”,我说“你可以使用带有本地存储库的子模块就好了”。 :) 答案是另一个问题。
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-09
      • 2016-05-10
      • 2011-02-15
      • 2013-06-20
      • 1970-01-01
      • 2017-09-07
      相关资源
      最近更新 更多