From 5513a663e5a0665fb5ba30c1ce7056468376e679 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sun, 20 Mar 2016 19:42:46 +0300 Subject: [PATCH] Add set-commit-date.py 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 | 4 ++-- set-commit-date.py | 45 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100755 set-commit-date.py diff --git a/set-commit-date-recursive b/set-commit-date-recursive index c8a2f0a..c70cff5 100755 --- a/set-commit-date-recursive +++ b/set-commit-date-recursive @@ -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 index 0000000..70e3932 --- /dev/null +++ b/set-commit-date.py @@ -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() -- 2.39.5