如何将未更改的文件添加到git索引中

3
我正在编写一个工具,需要在Git仓库中保留(生成的)文件历史记录。
其中之一的要求是,我必须能够获取特定提交中生成的内容,并将其重现到另一个分支中。
表面上看,这非常类似于cherry-pick,但有些微妙之处使得它有点不同。
每个提交都会在工作树中生成一组文件。一些文件可能已经存在于工作树中,而且很多时候,生成的内容与工作树中的版本没有变化。
稍后,我必须能够将先前提交生成的文件列表(无论内容是否改变)复制到另一个分支。
我的第一个问题是:即使文件内容没有更改,我是否可以将文件添加到git索引中(并最终提交)? 如果我必须在git内部进行操作,那也没关系。我只需要确保它不会破坏其他git工具的git仓库。
我使用Java和开源jGit库与Git仓库进行交互,因此我的第二个问题是,jGit是否支持此功能?
如果是的话,那么一些API指针将非常感谢。
谢谢。
4个回答

3
回答你的明确问题 - 如果文件存在于先前的提交中,并且其内容没有改变(尽管其元数据可能已经改变),那么该文件已经在索引中。在提交后立即,索引包含该提交的精确内容。添加/删除更改会对索引进行适当的修改以准备进行下一次提交。与其他一些答案/评论相反,git不存储更改 - 它存储工作目录的完整快照(或者至少是其中未被忽略和未跟踪的部分)。它在需要时计算更改,但它不存储它们(至少从git前端的角度来看 - 底层对象数据库将使用增量来减少所需的空间量,但它使用的增量可能不是连续版本之间的增量,甚至可能不是同一文件的两个版本之间的增量,如果您有非常相似的文件)。
回答您想要做的事情,您可能需要研究git reset --merge。如果这不是您想要的,您可以执行以下操作,它将更改当前工作目录以匹配特定提交,然后将该状态作为新提交进行提交 - 本质上复制由源提交表示的快照,该提交可能位于不同的分支上或可能早于当前分支,并创建一个看起来与其完全相同的新提交,除了被认为是父提交的内容:
git rm -r *
git archive --format=tar <commit> | tar xpf -
git add -A .
git commit -m "snapshot copy of commit <commit>"

您还可以使用git archive --format=zip <commit> -o /tmp/somefile.zip; unzip /tmp/somefile.zip,但我更喜欢使用tar格式,因为您可以直接进行管道处理...


你有没有一个链接可以说明git是如何存储整个工作树的“快照”,而不是更改,并将其转换为增量(更改)的呢?谢谢。 - Sukima
1
这三个都是一个不错的起点:[1](http://git-scm.com/doc),[2](http://git-scm.com/book),[3](http://eagain.net/articles/git-for-computer-scientists/)。当然,还有许多其他资源可以通过谷歌搜索找到... - twalberg

1

看起来 git update-index 是专门用于操作索引的。你可以在 它的文档 中找到需要的内容。


1
Git不是存储文件而是存储变更。最好使用更适合文件存储和时间戳的东西(数据库)来代替版本控制。
为了强制在git中实现你想要的想法,我唯一能想到的就是让生成器向文件添加构建号或唯一的MD5 + 种子(time.now),这样git会看到一个变化,然后进行提交。
但是再次强调,这真的像是解决方案与问题不匹配。您确定使用版本控制系统记录生成器脚本运行是正确的工具吗?

1
首先我必须同意git很可能不是正确的选择。
这篇答案的其余部分介于实验和丑陋的黑客世界之间。
首先在你的代码库中建立一个文件,它将包含你的文件结构,例如repo_files
然后你可以实现一个钩子来将新文件添加到repo_files中。
因此,在任何时候,你都可以知道代码库以及所需的空文件。
有了这些实现,你可以编写一些自定义的git命令来做你需要的事情。
例如:
  • generate_repo_files用于填充repo_files文件
  • commit_empty_file只会将文件添加到repo_files
  • checkout_with_files将执行检出并触摸缺失的文件
  • remove_files将从repo_files中删除空文件

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