Auschecken alter Dateien MIT ursprünglichen Erstellungs-/Änderungszeitstempeln

Lesezeit: 10 Minuten

Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
Scud

Gibt es eine Möglichkeit, die ursprünglichen Erstellungs-/Änderungszeitstempel zu erfahren oder zu erhalten?

  • Dies ist eine sauberere Seite, aber sowohl die Frage als auch die am häufigsten gewählte Antwort werden im Grunde dupliziert: stackoverflow.com/questions/1964470/…

    – Cregox

    25. Juli 2013 um 20:51 Uhr

  • git.wiki.kernel.org/index.php/…

    – bekloppter Typ

    29. Dezember 2017 um 6:29 Uhr

  • Beantwortet das deine Frage? Was ist das Äquivalent von use-commit-times für git?

    – Trilarion

    15. Dezember 2020 um 10:51 Uhr

  • Die Antworten zu Git-Klon ändert die Änderungszeit der Datei kann praktischer und auf den Punkt gebracht werden (Befehlszeilen-Einzeiler und ähnliches).

    – Peter Mortensen

    23. Oktober 2021 um 12:34 Uhr


1646639292 705 Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
BT

JAWOHLMetastore oder Git-Cache-Meta kann solche (Meta-)Informationen speichern! Git allein, ohne Tools von Drittanbietern, kann das nicht. Metastore oder git-cache-meta kann beliebige Dateimetadaten für eine Datei speichern.

Das ist beabsichtigt, da Metastore oder Git-Cache-Meta genau für diesen Zweck vorgesehen sind, sowie unterstützende Backup-Dienstprogramme und Synchronisierungstools.

  • Du hast sogar seine Großbuchstaben nachgeahmt! Wenn Sie auch den Fettdruck anwenden, werden Sie sicher noch mehr Upvotes erhalten. 😉

    – Michael Scheper

    2. April 2014 um 23:07 Uhr

  • Ich bin also ein bisschen verärgert, hauptsächlich weil diese beiden Tools (nach einigem Eintauchen in sie) den Ball auf spektakuläre Weise auf macOS fallen lassen. Sie sind aus Linux vollständig nicht portierbar. git-cache-meta setzt auf GNU find‘S -printf Erweiterung, und ich bin mir fast sicher, dass Metastore (als C-Projekt) noch mehr Arbeit macht, es portabel zu machen. Ziemlich schade. Ich werde hier wieder posten, wenn ich herausfinde, dass sich diese Situation ändert.

    – Steven Lu

    6. Mai 2018 um 5:24 Uhr


  • Es gibt jetzt Git-Metawelches ist git-cache-meta verwandelte sich in ein Repository mit Updates; Jetzt kann es als Git-Hook installiert werden, sodass Metadaten bei jedem Commit automatisch gespeichert werden!

    – dani ‘SO lern Wert Neulinge’

    20. Oktober 2021 um 15:33 Uhr


Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
Dietrich Ep

Ich glaube, dass die einzigen in der Git-Datenbank aufgezeichneten Zeitstempel die Autoren- und Commit-Zeitstempel sind. Ich sehe keine Option für Git, um den Zeitstempel der Datei so zu ändern, dass er mit dem letzten Commit übereinstimmt, und es ist sinnvoll, dass dies nicht das Standardverhalten wäre (denn wenn dies der Fall wäre, würden Makefiles nicht richtig funktionieren).

Sie könnten ein Skript schreiben, um das Änderungsdatum Ihrer Dateien auf die Zeit des letzten Commit zu setzen. Es könnte etwa so aussehen:

# No arguments? Recursively list all git-controlled files in $PWD and start over
if [ $# = 0 ]; then
  git ls-files -z |xargs -0 sh "$0"
  exit $?
fi

for file in "[email protected]"; do
  time="$(git log --pretty=format:%cd -n 1 \
                  --date=format:%Y%m%d%H%M.%S --date-order -- "$file")"
  if [ -z "$time" ]; then
    echo "ERROR: skipping '$file' -- no git log found" >&2
    continue
  fi
  touch -m -t "$time" "$file"
done

Dies akzeptiert bestimmte Dateien als Argumente oder aktualisiert jede git-gesteuerte Datei im aktuellen Verzeichnis oder seinen untergeordneten Dateien. Dies geschieht auf eine Weise, die seitdem Leerzeichen und sogar Zeilenumbrüche in Dateinamen zulässt git ls-files -z gibt eine nullterminierte Dateiliste aus und xargs -0 zerlegt nullterminierte Listen in Argumente.

Dies kann eine Weile dauern, wenn Sie viele Dateien haben.

  • Es gibt mehrere Probleme mit diesem Snippet: 1 – Es schlägt fehl, wenn es Leerzeichen in Dateinamen gibt; 2 – Kann bei Projekten mit mehr als ein paar tausend Dateien fehlschlagen; 3 – Leistung ist absolut miserabel jedes mittelgroße Projekt mit ein paar tausend Commits (selbst mit wenigen Dateien)

    – MestreLion

    8. November 2012 um 7:30 Uhr

  • +1 funktioniert vielleicht nicht für jeden möglichen Fall, aber es ist eine gute einfache Antwort.

    – qwerty9967

    19. März 2013 um 17:17 Uhr

  • Ist die Frage des OP nicht, wie die geänderten Zeitstempel der Originaldatei beibehalten werden können, und nicht der Commit-Zeitstempel an den Dateien befestigt werden soll?

    – BT

    11. Juli 2013 um 0:38 Uhr

  • Das Entwerfen eines VCS rund um Make ist kurzsichtig. Ich denke, das ist ein Fehler von Git. Also wirklich nicht Sinn machen, dass es kein Standardverhalten ist. Make-Dateien sollten auf den Dateiinhalten ausgeführt werden, nicht auf Zeitstempeln. Die Datei zu hashen und zu sehen, ob der Hash mit dem übereinstimmt, was Sie erstellt haben, ist viel robuster.

    – BT

    11. Juli 2013 um 0:58 Uhr


  • Ich stimme BT und Teilen deines Kommentars Dietrich zu. Was BT mit dem OP gemeint hat, ist, dass Ihre Antwort es nicht wirklich erlaubt, die ursprüngliche Zeit der Datei beizubehalten. Stattdessen werden sie durch die ursprüngliche Checkout-Zeit ersetzt. Nicht dasselbe… Damit, ich denke, er hat eindeutig gesagt, dass Ihr Beitrag sachliche Fehler enthält. Und ich kann sehen, woher die Entscheidung kam, keine Zeitstempel zu speichern, wie Sie zeigen. Ich denke auch, dass BT ein bisschen auf diese Argumentation zurückgreift. Dem stimme ich wieder BT zu – keine guten Gründe, es überhaupt nicht zu können. Jeder andere VCS kann das.

    – Cregox

    19. Juli 2013 um 21:36 Uhr


1646639293 425 Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
Jakub Narębski

NEINGit einfach speichert solche (Meta-)Informationen nichtes sei denn, Sie verwenden Tools von Drittanbietern wie Metastore oder git-cache-meta. Der einzige Zeitstempel, der gespeichert wird, ist die Zeit, zu der ein Patch/eine Änderung erstellt wurde (Zeitpunkt des Autors), und die Zeit, zu der das Commit erstellt wurde (Zeitpunkt des Committers).

Das ist beabsichtigt, da Git ein Versionskontrollsystem ist, kein Backup-Dienstprogramm oder Synchronisierungstool.

  • Gibt es einen Metastore-Build für Win32? oder sollte man Skripte/Hooks für Windows neu erstellen? Franklt, ich brauche keine anderen Attribute, nur Zeit

    – Arioch ‘Die

    23. Oktober 2012 um 13:18 Uhr

  • Ich denke, Ihre Antwort lautet eigentlich “JA! Metastore oder Git-Cache-Meta können das für Sie tun!” Ich denke, es ist der Unterschied zwischen defätistischen und optimistischen Einstellungen.

    – BT

    11. Juli 2013 um 0:30 Uhr

  • Außerdem, wie ich gehört habe, Basar und Quecksilber sind auch “Versionskontrollsysteme”, die Metainformationen speichern. Es ist nichts falsch daran, dies zu tun.

    – Cregox

    19. Juli 2013 um 21:30 Uhr

  • Klarstellung: Git speichert zwei Zeitstempel für jede Datei: das Autordatum (was Jakub meiner Meinung nach mit „Zeitpatch“ meint) und das Committer-Datum. Ersteres ist der Zeitpunkt, zu dem die Datei zum ersten Mal festgeschrieben wurde, und letzteres ist der Zeitpunkt, zu dem die Datei zuletzt festgeschrieben wurde.

    – Michael Scheper

    2. April 2014 um 23:42 Uhr

  • „Das ist beabsichtigt, da Git ein Versionskontrollsystem ist, kein Backup-Dienstprogramm oder Synchronisierungstool.“ Das ist ein nicht sequitur: Ignorieren von Metadaten (insbesondere Daten, die eng mit Versionen verbunden sind) hat nichts damit zu tun, ein VCS oder ein Backup-Tool zu sein. Außerdem hat jedes VCS eine große inhärente Funktionsüberschneidung mit Backup-Tools: Beide streben danach, wichtige vergangene Zustände zu bewahren. Schließlich ignoriert selbst Git nicht alle Metadaten (z. B. verfolgt es das Ausführungsbit), obwohl es ein VCS ist. Es immer noch ist von Natur aus, aber aus einem anderen Grund: Gits ausschließlicher Fokus auf Inhalte.

    – Gr.

    19. September 2019 um 13:12 Uhr


1646639293 660 Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
MestreLion

AKTUALISIEREN: TL;DR: Git selbst speichert keine Originalzeiten, aber einige Lösungen umgehen dies durch verschiedene Methoden. git-restore-mtime Ist einer von ihnen.

Ubuntu und Debian: sudo apt install git-restore-mtime
Fedora, Red Hat Enterprise Linux (RHEL) und CentOS: sudo yum install git-tools

Siehe meine andere Antwort für weitere Details.

Vollständiger Haftungsausschluss: Ich bin der Autor von git-tools


Dieses Python-Skript kann helfen: Für jede Datei wendet es den Zeitstempel des letzten Commits an, bei dem die Datei geändert wurde:

  • Kernfunktionalität, mit –help, Debug-Meldungen. Kann überall innerhalb des Arbeitsbaums ausgeführt werden
  • Vollwertige Bestie, mit vielen Optionen. Unterstützt jedes Repository-Layout.

Unten ist ein Ja wirklich Bare-Bones-Version des Skripts. Für die tatsächliche Verwendung empfehle ich dringend eine der robusteren Versionen oben:

#!/usr/bin/env python
# Bare-bones version. The current directory 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 analysieren das vollständige Protokoll, das von einer einzigen generiert wird git whatchanged Befehl, der hundertmal schneller ist als das Loppen für jede Datei. Sie beträgt weniger als vier Sekunden für Git (24.000 Commits, 2.500 Dateien) und weniger als eine Minute für den Linux-Kernel (40.000 Dateien und 300.000 Commits).

Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
entkommen

Dies hat den Trick für mich auf Ubuntu getan (dem das Flag “-j” von OS X am Datum (1) fehlt):

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

1646639294 798 Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
Lukasz Kruszyna

Ich habe schon seit einiger Zeit mit Git und Dateizeitstempeln gekämpft.

Ich habe einige Ihrer Ideen getestet und meine eigenen schrecklich großen und Vorgänger-/RAM-lastigen Skripte erstellt, bis ich (in einem Git-Wiki) ein Skript in Perl gefunden habe, das fast das tut, was ich wollte.
https://git.wiki.kernel.org/index.php/ExampleScripts

Und was ich wollte, ist in der Lage zu sein, die letzte Änderung von Dateien basierend auf Commit-Daten beizubehalten.

Nach einigen Anpassungen ist das Skript also in der Lage, das Erstellungs- und Änderungsdatum von zu ändern 200.000 Dateien herum 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;

Unter der Annahme, dass Ihre Repositories nicht mehr als 10.000 Dateien enthalten, sollte die Ausführung Sekunden dauern, sodass Sie sie an den Checkout, Pull oder andere grundlegende Git-Hooks anschließen können.

1646639294 726 Auschecken alter Dateien MIT ursprunglichen Erstellungs Anderungszeitstempeln
Peter Mortensen

Natives Git verfügt nicht über diese Funktionalität, kann aber durch Hook-Skripte oder Tools von Drittanbietern erreicht werden.

ich habe es versucht metastore. Es ist sehr schnell, aber ich mag die Notwendigkeit einer Installation nicht und dass Metadaten nicht im Klartextformat gespeichert werden. git-cache-meta ist ein einfaches Tool, das ich ausprobiert habe, aber es ist extrem langsam für große Repositorys (bei einem Repository mit Zehntausenden von Dateien dauert es Minuten, um die Metadatendatei zu aktualisieren) und könnte plattformübergreifende Kompatibilitätsprobleme haben. setgitperms und andere Ansätze haben auch ihre Schwächen, die mir nicht gefallen.

Endlich habe ich ein Hook-Skript für diesen Job erstellt: git-store-meta. Es hat sehr leichte Abhängigkeit (*Nix Schale, sortund perldie von Git benötigt wird, und optional chown, chgrp und touch), damit für eine Git-fähige Plattform nichts zusätzlich installiert werden muss, wünschenswerte Leistung (Bei einem Repository mit Zehntausenden von Dateien dauert es weniger als 10 Sekunden, um die Metadatendatei zu aktualisieren; die Erstellung dauert jedoch länger), speichert Daten in reines Textformatund welche Metadaten “gespeichert” oder “geladen” werden sollen anpassbar.

Bei mir hat es gut funktioniert. Versuchen Sie dies, wenn Sie mit Metastore, Git-Cache-Meta und anderen Ansätzen nicht zufrieden sind.

  • Ich habe das ausprobiert, und das funktioniert tatsächlich, danke! Das einzige kleine Problem ist, dass die --install Haken scheinen nicht zu funktionieren, bis ich sie manuell ausführe git-store-meta.pl --store das erste Mal.

    – Milind R

    22. Februar 2021 um 14:51 Uhr


  • @MilindR Dies ist beabsichtigt, da git-store-meta niemals wissen kann, wie für ein automatisches Update gespeichert werden soll, wenn kein vorheriger Speicher ausgeführt wurde.

    – Danny Lin

    23. Februar 2021 um 15:29 Uhr

  • Ach du meinst die zu speichernden Felder! Wie wäre es mit einem --init Flag, nach dem die Hooks normal funktionieren können? Nur ein Vorschlag…

    – Milind R

    25. Februar 2021 um 10:51 Uhr

964110cookie-checkAuschecken alter Dateien MIT ursprünglichen Erstellungs-/Änderungszeitstempeln

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy