我经常遇到以下情况:
git commit
提交修改。git commit -a --amend
(或git commit --amend path/to/A
)现在,由于自上次构建以来我仅修改了文件A,因此我希望仅重建文件A,但是我始终看到的是A,B和C的全部(即,整个提交触及的所有文件)都将重建。
在我看来git commit --amend
touch
使A,B和C的最后修改的时间戳记/颠簸,即使我只是在提交中添加了对A的修改
这有必要吗?是否可以避免,所以只有A被触摸,只有A被重建?
如果有关系,我的项目是C ++,构建系统是cmake + ninja,但我认为这很重要,因为构建系统依靠上次修改的时间戳来确定要重建的内容是相当标准的。
答案 0 :(得分:1)
git commit
不会触摸工作树中的任何文件。此处是否使用--amend
都没关系。
没有git commit
的{{1}}也不会使用您工作树中的任何文件,但是-a
具有Git,实际上运行了{{1 }}首先,它将从工作树中读取一些文件,以便将它们复制到索引中。然后,无论有没有git commit -a
到git add -u
,无论哪种方式都可以根据索引中的内容构建新的提交。
新提交一旦完成,便具有一些新的,唯一的,从未见过的哈希ID。如果您执行的是普通的-a
(没有git commit
),则存储库中会有一系列提交,每个提交都有自己的唯一哈希ID,并带有 last 提交具有一些哈希ID git commit
的
--amend
(在这里,大写字母代表实际的原始哈希ID,这些ID看起来是随机的,但实际上不是,但是也不可预测。)新的提交获取其新的唯一哈希ID H
,并且在... <-F <-G <-H <-- your-branch (HEAD)
内部,存储的父哈希ID为I
。 Git将新ID写入分支名称,给出:
I
使用H
的区别在于,Git使用 same 构造新的提交,而不是使新的提交...--F--G--H--I <-- your-branch (HEAD)
指向现有的提交--amend
。 I
拥有的父级,在这种情况下为H
。结果是H
被推到一边:
G
现有提交H
保持不变,但似乎消失了:无法从 H
/
...--F--G--I <-- your-branch (HEAD)
开始并向后进行查找。因此H
隐藏它似乎消失了,好像Git已经以某种方式更改了I
。 Git还没有; git log
仍然完整。默认情况下,它仍至少可恢复30天,因为哈希ID存储在Git称为 reflogs 的位置。但是它看起来不见了。
如果您看到各种文件都被重建,那不是因为Git本身接触了源文件。可能有其他东西触及了源文件,或者-我的猜测,只是一个猜测-您的构建系统可能会将它们标记为依赖于特定的Git提交哈希:因为H
与H
具有不同的哈希,而构建工件是I
而非H
的结果,它们现在已过时。
(其他可能性当然包括Git钩子,该钩子会更改文件的时间戳。)
答案 1 :(得分:0)
避免这种情况的一种方法(手动)是在不进行任何修改的情况下进行所有提交,并且在完成更改后,{{3}}挤压提交(您正在修改的提交)