3

Can someone please help me understand why when switching branches with Git that the modified date in the Mac OS file system does not change? For example, I have a file in repo called test.txt that is part of both the Master and Test branches.

In the master branch I edit and commit the file and then switch to the Test branch. Since Git manipulates the file system, I would expect at that point that the date modified would change to the modified date of the version of the file in the active branch.

dtburgess
  • 613
  • 5
  • 19
  • Your expectation is incorrect. When you check out a branch, Git retrieves the version of the file from its storage and copies it into your project's working directory. At that moment, your OS sets the timestamp of the file in your working directory to the current date and time of your system. – jub0bs Aug 01 '14 at 17:45
  • 1
    In other words, `git` uses timestamps to check if a file has been modified since it was last checked out, but pretty much ignores them otherwise, and, in particular, does not store the timestamp with each file. – twalberg Aug 01 '14 at 18:08

1 Answers1

4

Your expectation is incorrect. Git doesn't record a file's timestamp at the time of commit.

Moreover, if the checkout operation requires Git to retrieve a different version of the file and copy it to your project's working tree, your operating system will update the timestamp of the file in the working tree to reflect the current date and time shown by your system clock.

Check things for yourself by performing the following experiment.

First set things up:

cd ~/Desktop
mkdir git_test
cd git_test
git init

Create a file, start tracking it and create a first commit (on master).

touch README.md
git add README.md
git commit -m "add README to project"

Now inspect the timestamp of the README.md file with

ls -la

Write that time down; in my case, the time is 19:00; let's call that "time1". At this stage, wait for at least 60 seconds. Then create and check out a new branch called other:

git checkout -b other

Edit README.md; for instance:

printf "This is the project's README\n" > README.md

Now stage the file and create a second commit (on other):

git add README.md
git commit -m "edit README"

Do ls -la again, and write down timestamp of README.md; in my case, the time is 19:02; let's call that "time2".

At this stage, the commit graph (try git log --graph --all --decorate) should look as follows:

* other, HEAD
|
* master

Now check out master again and inspect the timestamp of the README file in your working directory.

git checkout master
ls -la

Now, contrary to what you expect, the timestamp of README.md does not match time1, but the current clock time. Wait at least another 60 seconds before checking out other again and check the timestamp:

git checkout other
ls -la

Again in this case, contrary to what you expect, the timestamp of README.md does not match time2, but the current clock time.


Edit: Here's a shorter experiment demonstrating that Git doesn't bake the timestamp of a file into the SHA-1 hash of the corresponding blob.

printf "hello\n" > greetings.txt
git hash-object greetings.txt

Write down the hash value returned. Wait a bit.

touch greetings.txt
git hash-object greetings.txt

Even though touch greetings.txt changed the timestamp of greetings.txt in your filesystemm the hash value should be the same as the first time you invoked git hash-object.

jub0bs
  • 60,866
  • 25
  • 183
  • 186