Sonntag, April 5, 2020

Alte Datei mit originalen Zeitstempel für Erstellung / Änderung auschecken

Gibt es eine Möglichkeit zu wissen, oder Holen Sie sich die original-erstellen/modified-Zeitstempel? Danke.

Kommentar zu dem Problem
dies ist ein cleaner Seite, aber sowohl die Frage und die meisten stimmten zu beantworten, sind im Grunde genommen dupliziert: stackoverflow.com/questions/1964470/… Kommentarautor: cregox

InformationsquelleAutor der Frage Scud | 2010-02-01

12 Kommentare

  1. 38

    Ich glaube, dass das nur die aufgezeichneten Zeitstempeln, die in der Git Datenbank sind der Autor und commit-Zeitstempel. Ich sehe nicht, eine option für Git, ändern Sie die Datei – Zeitstempel entsprechen dem letzten commit, und es macht Sinn, dass, wäre dies nicht das Standardverhalten (wenn es Sie denn gab, Makefiles würde nicht richtig funktionieren).

    Könnten Sie ein Skript schreiben um die änderung Datum der Dateien, die die Zeit von dem letzten commit. Es könnte wie folgt Aussehen:

    IFS="
    "
    for FILE in $(git ls-files)
    do
        TIME=$(git log --pretty=format:%cd -n 1 --date=iso -- "$FILE")
        TIME=$(date -j -f '%Y-%m-%d %H:%M:%S %z' "$TIME" +%Y%m%d%H%M.%S)
        touch -m -t "$TIME" "$FILE"
    done
    

    InformationsquelleAutor der Antwort Dietrich Epp

  2. 39

    JA, metastore-oder git-cache-meta – speichern können solche (meta-)Informationen! Git von selbst, ohne Drittanbieter-tools nicht. Metastore oder git-cache-meta speichern können Datei-Metadaten für eine Datei.

    Ist die durch design, als metastore-oder git-cache-meta sind bestimmt für diesen Zweck, wie auch die Unterstützung von backup-utilities und Synchronisations-tools.

    (Sorry, nur ein wenig Spaß spin auf Jakub Antwort)

    InformationsquelleAutor der Antwort B T

  3. 29

    KEINE, Git einfach nicht speichern, solche (meta-)Informationen, es sei denn, Sie verwenden Sie tools von Drittanbietern, wie metastore oder git-cache-meta. Das einzige, Zeitstempel gespeichert werden, ist die Zeit, patch/änderung erstellt wurde (Autor die Zeit), und die Zeit commit erstellt wurde (committer Zeit).

    Das so gewollt ist, wie Git version control system, nicht für ein backup-Dienstprogramm oder Synchronisations-tool.

    InformationsquelleAutor der Antwort Jakub Narębski

  4. 9

    Diesem python-Skript helfen: für jede Datei gilt der Zeitstempel des letzten commit, in dem die Datei geändert wurde:

    • Core-Funktionalität, mit –help, debug-Meldungen. Ausgeführt werden können die überall in der Arbeit Baum
    • Vollwertiges beast, mit vielen Optionen. Unterstützt alle repository-layout.

    Unten ist eine wirklich bare-bones-version von das Skript. Für die tatsächliche Nutzung-ich empfehle, eines der robusteren Versionen vor:

    #!/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
    

    Alle Versionen Parsen der vollen log erzeugt von einem einzigen git whatchanged – Befehl, der mehrere hundert mal schneller als lopping für jede Datei. Unter 4 Sekunden für git (24,000 verpflichtet, 2.500 Dateien) und weniger als 1 minute für den linux-kernel (rund 40.000 Dateien, die 300.000 verpflichtet)

    InformationsquelleAutor der Antwort MestreLion

  5. 5

    Diese hat er trick für mich auf ubuntu (was OSX fehlt ist das „-j“ – flag date(1))

    for FILE in $(git ls-files)
    do
        TIME=$(git log --pretty=format:%cd -n 1 --date=iso $FILE)
        TIME2=`echo $TIME | sed 's/-//g;s///;s/://;s/:/\./;s/.*//'`
        touch -m -t $TIME2 $FILE
    done 
    

    InformationsquelleAutor der Antwort eludom

  6. 2

    Ich habe skirmishing mit git und Zeitstempel für einige Zeit schon.

    Getestet, einige Ihrer Ideen und meine eigene schrecklich riesigen und Vorgänger – /ram heavy-Skripts, bis ich gefunden (auf einige git-wiki) ein Skript in perl, die macht fast das, was ich wollte.
    https://git.wiki.kernel.org/index.php/ExampleScripts

    Und was ich wollte ist, um in der Lage sein, zu bewahren die Letzte änderung der Dateien auf commit-Termine.

    Also nach einigen Neueinstellung das Skript ist in der Lage zu ändern, Erstellung und änderung Datum 200k Dateien in rund 2-3min.

    #!/usr/bin/perl
    my %attributions;
    my $remaining = 0;
    
    open IN, "git ls-tree -r --full-name HEAD |" or die;
    while (<IN>) {
        if (/^\S+\s+blob \S+\s+(\S+)$/) {
            $attributions{$1} = -1;
        }
    }
    close IN;
    
    $remaining = (keys %attributions) + 1;
    print "Number of files: $remaining\n";
    open IN, "git log -r --root --raw --no-abbrev --date=raw --pretty=format:%h~%cd~ |" or die;
    while (<IN>) {
        if (/^([^:~]+)~([^~]+)~$/) {
            ($commit, $date) = ($1, $2);
        } elsif (/^:\S+\s+1\S+\s+\S+\s+\S+\s+\S\s+(.*)$/) {
            if ($attributions{$1} == -1) {
                $attributions{$1} = "$date";
                $remaining--;
    
                utime $date, $date, $1;
                if ($remaining % 1000 == 0) {               
                    print "$remaining\n";
                }
                if ($remaining <= 0) {
                    break;
                }
            }
        }
    }
    close IN;
    

    Davon aus, dass Ihre repositories haben nicht 10k+ Dateien soll dies in Sekunden ausgeführt werden, so können Sie Haken Sie es an der Kasse, ziehen oder anderen git grundlegenden Haken.

    InformationsquelleAutor der Antwort Lukasz Kruszyna

  7. 1

    Hier ist meine Lösung, die berücksichtigt, dass Pfade mit Leerzeichen:

    #! /bin/bash
    
    IFS=$'\n'
    list_of_files=($(git ls-files | sort))
    unset IFS
    
    for file in "${list_of_files[@]}"; do
      file_name=$(echo $file)
    
      ## When you collect the timestamps:
      TIME=$(date -r "$file_name" -Ins)
    
      ## When you want to recover back the timestamps:
      touch -m -d $TIME "$file_name"
    done
    

    Beachten Sie, dass dies nicht die Zeit nehmen, die git log Berichte, es ist die Zeit durch das system mitgeteilt. Wenn Sie möchten, dass die Zeit da wurden die Dateien commited verwenden git log Lösung statt date -r

    InformationsquelleAutor der Antwort Lilian A. Moraru

  8. 1

    Native git hat nicht die Funktionalität, aber es kann erreicht werden durch hook-Skripte oder tools von Drittanbietern.

    Ich habe versucht metastore. Es ist sehr schnell, aber ich mag es nicht installieren zu müssen, und die Metadaten werden nicht gespeichert im nur-text-format. git-cache-meta ist ein einfaches Werkzeug, ich habe es versucht, aber es ist sehr langsam für große Pensionsgeschäfte (repo-mit Zehntausenden von Dateien, dauert es Minuten, aktualisieren Sie die Metadaten-Datei) und könnte die cross-Plattform-Kompatibilität Probleme. setgitperms und andere Ansätze haben auch Ihre Mängel, die ich nicht mag.

    Endlich machte ich ein hook-Skript für diese Aufgabe: git-store-meta. Es hat sehr leichte Abhängigkeit (*nix-shell sort, und perl, die erforderlich ist, gespeichert, und Optional chown, chgrp und touch), so dass nichts zusätzliches installiert sein für eine Plattform, die ausgeführt werden kann git, wünschenswert performance (für ein repo mit Zehntausenden von Dateien, es dauert < 10 Sekunden aktualisieren Sie die Metadaten-Datei; obwohl mehr zu schaffen), speichert die Daten in nur-text-format, und die Metadaten, um „gerettet“ oder „geladen“ ist anpassbare.

    Es hat funktionierte gut für mich. Versuchen Sie dies, wenn Sie nicht zufrieden sind mit metastore, git-cache-meta-und anderen Ansätze.

    InformationsquelleAutor der Antwort Danny Lin

  9. 0

    Mit GNU-tools.

    s=$(git ls-files  | wc -l); 
    git ls-files -z  |
     xargs -0 -I{} -n1 bash -c \
    "git log --date=format:%Y%m%d%H%M.%S '--pretty=format:touch -m -t %cd \"{}\"%n' -n1 -- {}"|
     pv -l -s$s |
     parallel -n1 -j8
    
     967  0:00:05 [ 171 /s] [=====================================>  ] 16% 
    

    .

    $ git --version ; xargs --version | sed 1q ; ls --version | sed 1q;
      parallel --version  | sed 1q;  pv --version | sed 1q; sh --version | sed 1q 
    git version 2.13.0
    xargs (GNU findutils) 4.6.0
    ls (GNU coreutils) 8.25
    GNU parallel 20150522
    pv 1.6.0 - Copyright 2015 Andrew Wood <[email protected]>
    GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
    

    InformationsquelleAutor der Antwort Ярослав Рахматуллин

  10. 0

    Gibt es einige Unklarheiten in meiner (und anderer) interpretation der OP darüber, ob dies bedeutet, dass die commit-Zeitpunkt oder etwas anderes, aber in der Annahme, es bedeutet commit-Zeit, dann ist dieses simple one-liner funktioniert in linux (basierend auf der Antwort-snippet von Dietrich Epp):

    git ls-files | xargs -I{} bash -c 'touch "{}" [email protected]$(git log -n1 --pretty=format:%ct -- "{}")'
    

    Aber es gibt noch mehr anspruchsvolle Antworten (einschließlich git hooks), die mit aus einem Kommentar auf die ursprüngliche Frage von cregox.

    InformationsquelleAutor der Antwort mza

Kostenlose Online-Tests