]> git.phdru.name Git - git-scripts.git/commitdiff
Add set-commit-date.py
authorOleg Broytman <phd@phdru.name>
Sun, 20 Mar 2016 16:42:46 +0000 (19:42 +0300)
committerOleg Broytman <phd@phdru.name>
Sun, 20 Mar 2016 16:50:07 +0000 (19:50 +0300)
Find commit date/time for every commit, list files in the commit
and set the file's modification time to the date/time of the latest commit.

This is much faster than set-commit-date for big repositories.

set-commit-date-recursive
set-commit-date.py [new file with mode: 0755]

index c8a2f0af3b7d4b95d1147c3ec27e177a274406a4..c70cff5b840d039eed7f5ea471a9052d4432014a 100755 (executable)
@@ -4,5 +4,5 @@
 
 prog_dir="`dirname \"$0\"`" &&
 
-"$prog_dir"/set-commit-date && \
-exec git submodule foreach "$prog_dir"/set-commit-date
+"$prog_dir"/set-commit-date.py && \
+exec git submodule foreach "$prog_dir"/set-commit-date.py
diff --git a/set-commit-date.py b/set-commit-date.py
new file mode 100755 (executable)
index 0000000..70e3932
--- /dev/null
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+
+# Find commit date/time for every commit, list files in the commit
+# and set the file's modification time to the date/time of the latest commit.
+
+# 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
+
+import os
+import subprocess
+
+separator = '----- GIT LOG SEPARATOR -----'
+
+git_log = subprocess.Popen(['git', 'log', '-m', '--first-parent',
+                            '--name-only', '--no-color',
+                            '--format=%s%%n%%ct' % separator],
+                           stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+filenames = set()
+# stages: 1 - start of commit, 2 - timestamp, 3 - empty line, 4 - files
+stage = 1
+while True:
+    line = git_log.stdout.readline().strip()
+    if (stage in (1, 4)) and (line == separator):  # Start of a commit
+        stage = 2
+    elif stage == 2:
+        stage = 3
+        time = int(line)
+    elif stage == 3:
+        if line == separator:  # Null-merge (git merge -s ours), no files
+            stage = 2
+            continue
+        stage = 4
+        assert line == '', line
+    elif not line:
+        break
+    elif stage == 4:
+        filename = line
+        if filename not in filenames:
+            filenames.add(filename)
+            if os.path.exists(filename):
+                os.utime(filename, (time, time))
+    else:
+        raise ValueError("stage: %d, line: %s" % (stage, line))
+
+git_log.wait()
+git_log.stdout.close()