将文件注入git存储库而不进行检出

时间:2012-03-23 14:25:03

标签: git

我正在开发一个本地化框架,用于管理库中多个应用程序(wpf,android,ios)的文本资产。我们使用git作为所有应用程序的版本控制系统。现在我想将这些资产直接导出到git-repository中。

问题是:每次我将资产导出到git存储库时,我都不想克隆/拉出整个存储库。事实上,我不想知道任何文件占用这些资产。我已经发现使用git无法检查子目录,但有没有办法将这些更改“注入”或“强制”到存储库中,而不必拉出所有其他更改和文件? (注意:资产仅在此更改,不由开发人员直接编辑) 它基本上应该忽略assets文件夹之外发生的所有事情。 另一个重要的事情是它不应该改变我们的开发人员的工作流程,因此子模块实际上不是一个选项,因为它们必须一直拉动子模块。

有没有一个很好的方法用git做到这一点除外?提前谢谢!

2 个答案:

答案 0 :(得分:3)

只要存储库本身在本地可用,就可以编写一个可以注入blob而无需签出工作树的脚本。不过,这不是微不足道的。我之前编写过这样的脚本,由于它的长度而不能公开,我将省略,但基本上它涉及在循环中执行以下git命令(如果有任何失败则重新启动循环):

# Find the current head.
head="$(GIT_DIR="$repo" git show-ref --heads --hash master)"
# Get the current version of the file.
GIT_DIR="$repo" git cat-file blob "$head:path/to/file" >"$tmpdir/tempfile"
# [Modify the file if necessary.]
# Write the blob into the repository.
blob="$(GIT_DIR="$repo" git hash-object -w "$tmpdir/tempfile")"
# Read the tree into an index file.
GIT_INDEX_FILE="$index" GIT_DIR="$repo" git read-tree "$head"
# Add the ref of the blob into the index file.
GIT_INDEX_FILE="$index" GIT_DIR="$repo" git update-index --add \
    --cacheinfo 100644 "$blob" path/to/file
# Write the index file into the repo as a tree.
tree="$(GIT_INDEX_FILE="$index" GIT_DIR="$repo" git write-tree)"
# Write a commit to the repo.
commit="$(echo "autocommit" |GIT_DIR="$repo" git comm   it-tree "$tree" -p "$head")"
# Update the head of the repository to be the new commit.
GIT_DIR="$repo" git update-ref refs/heads/master "$commit" "$head"

这是不完整的(我省略了一些重启循环的错误处理代码),但它不仅仅是伪代码。希望它足以提供帮助。与只是克隆存储库相比,这会产生更复杂的脚本,但速度要快得多。使用哪一个取决于您的需求。

顺便说一下,如果存储库在NFS上,则锁定无法正常工作,您必须检查竞争条件(您的引用可能会重置,强制您重新启动整个过程)。

答案 1 :(得分:2)

在git中,提交对象引用树对象。那个树对象然后引用 blob对象。每个blob(通常)是工作副本中的文件。

提交标识符是提交对象的哈希值,它包含树对象的哈希值,树对象本身包含所有blob的哈希值。

因此,为了进行提交,必须知道提交中所有blob的状态。实际上,提交是整个工作副本(技术上,索引)的快照。这意味着您不能忽略X"之外的更改,因为如果您这样做,您的提交将生成一个没有这些文件的工作副本(如果您没有将它们包括在内)树对象)或过期的副本(如果你签出一次,然后假设它们没有改变,将过时的哈希值放入树对象中)。

这就是为什么你不能在git中检查一个子树并忽略它之外的变化。这也是为什么你要求的(在没有查看其他文件状态的情况下进行提交)是不可能的。

但是,我想如果你要试试" git方式"做事 - 克隆一次,然后从那个克隆中多次提交 - 你会很快发现它是一种非常低效的做事方式。

如果做不到这一点,你可以制作你的资产"作为一个单独的存储库(可能是一个git子模块,他们并不需要对开发人员和工作流程进行重大改变",真的)。然后你只需要克隆"资产"存储库在那里提交。

您也可以将修补程序发送到已经是最新的服务器并让它在本地进行提交。这不会涉及克隆回购,因为服务器当然必须对其他文件进行最新更改(它是您要从中获取的来源!)。

相关问题