git rebase ohne Änderung der Commit-Zeitstempel

Wäre es sinnvoll, git rebase während die Commit-Zeitstempel erhalten git rebase ?

Ich glaube, eine Konsequenz wäre, dass der neue Zweig nicht unbedingt chronologisch festgeschrieben werden muss. Ist das theoretisch überhaupt möglich? (zB mit Klempnerbefehlen; nur neugierig hier)

Wenn es theoretisch möglich ist, ist es dann in der Praxis mit Rebase möglich, die Zeitstempel nicht zu ändern?

Angenommen, ich habe den folgenden Baum:

 master  | : : : oldbranch  : / oldcommit  

Jetzt, wenn ich Oldbranch auf master rebase, oldbranch das Datum des Commits von Feb 1984 zu Jun 2010. Ist es möglich, dieses Verhalten zu ändern, so dass der Commit-Zeitstempel nicht geändert wird? Am Ende würde ich erhalten:

  oldbranch  / master  | : 

Würde das überhaupt Sinn machen? Ist es in Git sogar erlaubt, eine Historie zu haben, in der ein altes Commit ein neueres Commit als Elternteil hat?

   

Update Juni 2014: David Fraser erwähnt in den Kommentaren eine Lösung, die auch in ” Timestamps während Rebasting Git Branch ändern ” beschrieben ist, unter Verwendung der Option --committer-date-is-author-date (eingeführt im Jan. 2009 in Commit 3f01ad6)

Beachten Sie, dass die --committer-date-is-author-date den Zeitstempel des Autors zu --committer-date-is-author-date scheint und dass der Zeitstempel des --committer-date-is-author-date mit dem ursprünglichen Zeitstempel des Autors identisch ist, was der OP Olivier Verdier wollte.

Ich fand das letzte Commit mit dem richtigen Datum und tat:

 git rebase --committer-date-is-author-date SHA 

Sieh git am :

 --committer-date-is-author-date 

Standardmäßig zeichnet der Befehl das Datum aus der E-Mail-Nachricht als das Autorisierungsdatum des Commits auf und verwendet den Zeitpunkt der Erstellung des Commits als Committer-Datum.
Dadurch kann der Benutzer über das Committer-Datum lügen, indem er denselben Wert wie das Autorendatum verwendet .


(Ursprüngliche Antwort, Juni 2012)

Sie könnten versuchen, für eine nicht interaktive Rebase

 git rebase --ignore-date 

(von dieser SO Antwort )

Dies wird an git am , die erwähnt:

  --ignore-date 

Standardmäßig zeichnet der Befehl das Datum aus der E-Mail-Nachricht als das Autorisierungsdatum des Commits auf und verwendet den Zeitpunkt der Erstellung des Commits als Committer-Datum.
Dies ermöglicht dem Benutzer, über das Datum des Autors zu lügen, indem er denselben Wert wie das Datum des Täters verwendet.

Für git rebase ist diese Option “Inkompatibel mit der Option –interactive”.

Da Sie den Zeitstempel des alten Commit-Datums (mit git filter-branch ) nach Belieben ändern können, können Sie Ihren Git-Verlauf mit der gewünschten Commit-Datumsreihenfolge organisieren, sogar in die Zukunft! .


Wie Olivier in seiner Frage erwähnt, wird das Autorendatum nie durch eine Rebase geändert;
Aus dem Pro Git Buch :

  • Der Autor ist die Person, die das Werk ursprünglich geschrieben hat,
  • in der Erwägung, dass der Täter die Person ist, die das Werk zuletzt angewendet hat.

Wenn Sie also einen Patch an ein Projekt senden und eines der coremitglieder den Patch anwendet, erhalten Sie beide ein Guthaben.

Um besonders klar zu sein, in diesem Fall, wie Olivier sagt:

Das --ignore-date macht das Gegenteil von dem, was ich erreichen wollte !
Es löscht nämlich den Zeitstempel des Autors und ersetzt ihn durch die Zeitstempel der Commits!
Also die richtige Antwort auf meine Frage ist:
Tun Sie nichts, da git rebase die Zeitstempel der Autoren standardmäßig nicht ändert.


Wenn Sie die Commit-Daten bereits vermasselt haben (vielleicht mit einer Rebase) und sie auf die entsprechenden Autorendaten zurücksetzen möchten, können Sie Folgendes ausführen:

git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'

Eine entscheidende Frage von Von C hat mir geholfen, zu verstehen, was vor sich geht: Wenn Sie sich zurückziehen, ändert sich der Zeitstempel des Commiters, aber nicht der Zeitstempel des Autors , was plötzlich alles einen Sinn ergibt. Meine Frage war also nicht präzise genug.

Die Antwort ist, dass Rebase tatsächlich die Zeitstempel des Autors nicht verändert (Sie müssen dafür nichts tun), was mir perfekt passt.

Standardmäßig legt Git-Rebase den Zeitstempel des Commiters auf den Zeitpunkt fest, an dem der neue Commit erstellt wird, behält jedoch den Zeitstempel des Autors bei. In den meisten Fällen ist dies das gewünschte Verhalten, aber in einigen Szenarien möchten wir auch den Zeitstempel des Commiters nicht ändern. Wie können wir das erreichen? Nun, hier ist der Trick, den ich normalerweise mache.

Stellen Sie zunächst sicher, dass jedes der Commits, die Sie rebasen möchten, über eine eindeutige Commit-Nachricht und einen Autor-Zeitstempel verfügt (Dies ist der Punkt, an dem der Trick Verbesserungen benötigt, derzeit jedoch meinen Bedürfnissen entspricht).

Notieren Sie vor dem Rebase den Zeitstempel des Committers, den Zeitstempel des Autors und die Commit-Nachricht aller Commits, die in eine Datei umgebildet werden.

 #NOTE: BASE is the commit where your rebase begins git log --pretty='%ct %at %s' BASE..HEAD > hashlog 

Dann lass die tatsächliche Rebase stattfinden.

Schließlich ersetzen wir den Zeitstempel des aktuellen Commiters durch den in der Datei aufgezeichneten, wenn die Commit-Nachricht dieselbe ist, indem git filter-branch .

  git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%at %s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_COMMITTER_DATE=$__date || cat' 

Wenn etwas schief geht, git reflog einfach git reflog oder alle refs/original/ refs.

Außerdem können Sie dem Zeitstempel des Autors ähneln.

Wenn beispielsweise der Zeitstempel des Autors einiger Commits nicht in Ordnung ist und diese Commits nicht neu angeordnet werden sollen, möchten wir nur, dass der Timestamp des Autors der Reihe nach angezeigt wird. Dann helfen die folgenden Befehle.

 git log --pretty='%at %s' COMMIT1..COMMIT2 > hashlog join -1 1 -2 1 < (cat hashlog | cut -f 1 | sort -nr | awk '{ print NR" "$1 }') <(cat hashlog | awk '{ print NR" "$0 }') | cut -d" " -f2,4- > hashlog_ mv hashlog_ hashlog git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_AUTHOR_DATE=$__date || cat'