Reputation: 11848
I have two files, file1
and file2
. I modified file1
and didn't touch file2
. After commit, CI started which checks modification dates of file1
and file2
. If file2
is older, build tool generates its own version of file2
from file1
and compares the results (generated file2
and file2
which is in repo). If there is no match the error is generated.
I don't want to modify file2
and have no way to modify the build pipeline. The question is, how to commit only timestamp modification of file2
so CI doesn't touch it? I want to make file2
newer than file1
.
Please don't ask why CI is configured in such way. This is a big project with lot of contributors.
Upvotes: 2
Views: 708
Reputation: 488453
Git does not store file timestamps.
The unit of storage in Git is the commit. A commit (as a whole) has a timestamp. In fact, each commit has two timestamps, namely the author timestamp and the committer timestamp. These two timestamps are part of the commit's metadata. And, of course, a commit stores a snapshot of all of your files. But that's all of your files, without timestamps.
This means that the answer to the question in your title is a resounding no. Even if Git itself set timestamps on files (it doesn't), you could not make it set the timetsamp on file2
without it also setting that on file1
(because either you'd set all the timestamps on all files from the author or committer timestamp, or—as Git actually works today—you'd set none of them on any files). There are only the two timestamps in the commit, and if you're going to apply them, how do you know which file(s) should get them?
The way the underlying operating system sees timestamp updates on your files in your work-tree is this: when your Git conducts a git checkout
or git switch
to move from whatever commit you have out now to whatever other commit you'd like to have out, your Git observes that this requires replacing the contents of some files (and perhaps removing some files and creating some files). So Git replaces the contents of those files, and/or removes and/or creates some files as required. This action causes your operating system to change the timestamps on those files.
A CI build system may or may not work the same way. Some CI systems might keep a work-tree full of files from a previous build; others might not.1 In any case, you cannot get Git to set date-stamps like this.2 You will have to find some other way to deal with your CI system.
(If your CI system has a standard work-tree, you can get it to update its in-work-tree copy of file2
by ... changing file2
so that Git must extract it when changing commits. But this is what you said you did not want.)
1It seems pretty common, in these build systems, to not keep a work-tree, and instead, to run a git diff
to compare file content from a previously-built, but long since removed, work-tree to that in a proposed new build that has been extracted into a fresh work-tree. If the file contents of particular files have changed, those files get re-built. Some Jenkins setups do this manually for instance. Bazel apparently formalizes this by computing hash checksums and comparing the checksums: if a checksum matches a previous build, it just re-uses the previous build's artifacts.
2People have written various Git hooks that go through and whack on file ownership and/or permissions, e.g., based on the contents of a committed file. This technique could also be used to set the OS's timestamps. But such a script would in general just be part of the CI system.
Upvotes: 2
Reputation: 3495
I give you 2 method:
The first is the following and is clear and safe:
git rm --cached <file>
git add <file>
This should put the new file into the index regardless of what was previously there.
The second is the following (but pay attention this is only a workaround):
touch file.dat
git add file.dat
basically, force git to recognize that the file might be changed so that it acutally checks if it has really been changed.
Upvotes: 0