]> git.phdru.name Git - git-scripts.git/blob - set-commit-date.py
Feat(ls-assumed): Recognize files with skip-worktree bit
[git-scripts.git] / set-commit-date.py
1 #! /usr/bin/env python
2
3 # Find commit date/time for every commit, list files in the commit
4 # and set the file's modification time to the date/time of the latest commit.
5
6 # Adapted from https://git.wiki.kernel.org/index.php/ExampleScripts#Setting_the_timestamps_of_the_files_to_the_commit_timestamp_of_the_commit_which_last_touched_them  # noqa
7
8 import os
9 import subprocess
10
11 separator = '----- GIT LOG SEPARATOR -----'
12
13 git_log = subprocess.Popen(['git', 'log', '-m', '--first-parent',
14                             '--name-only', '--no-color',
15                             '--format=%s%%n%%ct' % separator],
16                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
17                            universal_newlines=True)
18 filenames = set()
19 # stages: 1 - start of commit, 2 - timestamp, 3 - empty line, 4 - files
20 stage = 1
21 while True:
22     line = git_log.stdout.readline()
23     if not line:  # EOF
24         break
25     line = line.strip()
26     if (stage in (1, 4)) and (line == separator):  # Start of a commit
27         stage = 2
28     elif stage == 2:
29         stage = 3
30         time = int(line)
31     elif stage == 3:
32         if line == separator:  # Null-merge (git merge -s ours), no files
33             stage = 2
34             continue
35         stage = 4
36         assert line == '', line
37     elif stage == 4:
38         filename = line
39         if filename not in filenames:
40             filenames.add(filename)
41             if os.path.exists(filename):
42                 os.utime(filename, (time, time))
43     else:
44         raise ValueError("stage: %d, line: %s" % (stage, line))
45
46 git_log.wait()
47 git_log.stdout.close()