3

I have my remote repository on win server 2003 and after cloninig project from etalon all dates of file creation became dates of cloning. This is OK, but I need to restore dates of creation for files as dates of the first file commit. As I know there is some ways to use post-* scripts such as post-receive. Main idea:

  1. receive files by git clone/pull

  2. post-receive script modifyes file attributes (created/updated) according to the first file commit date for created and last file commit date for updated.

Any ideas how to write it (may be another way)?

Eugene Hoza
  • 621
  • 1
  • 6
  • 19
  • 2
    Seems a bit like http://stackoverflow.com/questions/2179722/git-checking-out-old-file-with-original-create-modified-timestamps, althoug make sure to read http://stackoverflow.com/questions/1964470/whats-the-equivalent-of-use-commit-times-for-git – VonC Sep 27 '11 at 14:00

3 Answers3

3

Since you're in Windows, this python script may help: for each file applies the timestamp of the most recent commit where the file was modified:

Below is a really bare-bones version of the script. For actual usage I strongly suggest one of the more robust versions above:

#!/usr/bin/env python
# Bare-bones version. Current dir must be top-level of work tree.
# Usage: git-restore-mtime-bare [pathspecs...]
# By default update all files
# Example: to only update only the README and files in ./doc:
# git-restore-mtime-bare README doc

import subprocess, shlex
import sys, os.path

filelist = set()
for path in (sys.argv[1:] or [os.path.curdir]):
    if os.path.isfile(path) or os.path.islink(path):
        filelist.add(os.path.relpath(path))
    elif os.path.isdir(path):
        for root, subdirs, files in os.walk(path):
            if '.git' in subdirs:
                subdirs.remove('.git')
            for file in files:
                filelist.add(os.path.relpath(os.path.join(root, file)))

mtime = 0
gitobj = subprocess.Popen(shlex.split('git whatchanged --pretty=%at'),
                          stdout=subprocess.PIPE)
for line in gitobj.stdout:
    line = line.strip()
    if not line: continue

    if line.startswith(':'):
        file = line.split('\t')[-1]
        if file in filelist:
            filelist.remove(file)
            #print mtime, file
            os.utime(file, (mtime, mtime))
    else:
        mtime = long(line)

    # All files done?
    if not filelist:
        break
MestreLion
  • 12,698
  • 8
  • 66
  • 57
1

Python3 version, File must be run on same git directory:

#!/usr/bin/env python
# Bare-bones version. Current dir must be top-level of work tree.
# Usage: git-restore-mtime-bare [pathspecs...]
# By default update all files
# Example: to only update only the README and files in ./doc:
# git-restore-mtime-bare README doc

import subprocess, shlex
import sys, os.path

filelist = set()
for path in (sys.argv[1:] or [os.path.curdir]):
    if os.path.isfile(path) or os.path.islink(path):
        filelist.add(os.path.relpath(path))
    elif os.path.isdir(path):
        for root, subdirs, files in os.walk(path):
            if '.git' in subdirs:
                subdirs.remove('.git')
            for file in files:
                filelist.add(os.path.relpath(os.path.join(root, file)))

mtime = 0
gitobj = subprocess.Popen(shlex.split('git whatchanged --pretty=%at'),
                          stdout=subprocess.PIPE)
for line in gitobj.stdout:
    line = line.decode('ascii').strip()
    if not line: continue

    if line.startswith(':'):
        file = os.path.normpath(line.split('\t')[-1])
        if file in filelist:
            filelist.remove(file)
            #print mtime, file
            os.utime(file, (mtime, mtime))
    else:
        mtime = int(line)

    # All files done?
    if not filelist:
        break
Braian
  • 93
  • 7
0

Line:

file = line.split('\t')[-1]

should be changed:

file = os.path.normpath(line.split('\t')[-1])

Because if you clone repository from linux to windows it will be different path separators and condition if file in filelist wil not work

Linuxss
  • 101
  • 3