webentwicklung-frage-antwort-db.com.de

Wie kann man den Zeitstempel eines alten Commits in Git ändern?

Die Antworten auf Wie ändere ich vorhandene, nicht weitergeleitete Commits? beschreiben eine Möglichkeit, frühere Commit-Nachrichten zu ändern, die noch nicht weitergeleitet wurden. Die neuen Nachrichten erben die Zeitstempel der ursprünglichen Commits. Das scheint logisch, aber gibt es eine Möglichkeit, die Zeiten auch neu zu setzen?

650
Dhskjlkakdh

Verwenden Sie git filter-branch mit einem Umgebungsfilter, der GIT_AUTHOR_DATE und GIT_COMMITTER_DATE für den spezifischen Hash des Commits festlegt, den Sie reparieren möchten.

Dies macht diese und alle zukünftigen Hashes ungültig.

Beispiel:

Wenn Sie das Datum von commit 119f9ecf58069b265ab22f1f97d2b648faf932e0 ändern möchten, können Sie dies folgendermaßen tun:

git filter-branch --env-filter \
    'if [ $GIT_COMMIT = 119f9ecf58069b265ab22f1f97d2b648faf932e0 ]
     then
         export GIT_AUTHOR_DATE="Fri Jan 2 21:38:53 2009 -0800"
         export GIT_COMMITTER_DATE="Sat May 19 01:01:01 2007 -0700"
     fi'
486
Dustin

Sie können ein interaktives Rebase durchführen und Bearbeiten für das Commit auswählen, dessen Datum Sie ändern möchten. Wenn der Rebase-Prozess angehalten wird, um das von Ihnen eingegebene Commit zu ändern, zum Beispiel:

git commit --amend --date="Wed Feb 16 14:00 2011 +0100"

Danach setzen Sie Ihre interaktive Datenbank fort.

UPDATE (als Antwort auf den Kommentar von studgeek): Ändern des Festschreibungsdatums anstelle des Autorendatums:

GIT_COMMITTER_DATE="Wed Feb 16 14:00 2011 +0100" git commit --amend

In den obigen Zeilen wird eine Umgebungsvariable GIT_COMMITTER_DATE festgelegt, die beim Festschreiben von Änderungen verwendet wird.

Alles wird in Git Bash getestet.

693
Paul Pladijs

Eine bessere Möglichkeit, alle diese Vorschläge in einem Befehl zu behandeln, ist

LC_ALL=C GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"

Dies setzt das Datum der letzten Übergabe und des Erstellers auf "sofort".

361
Luke Ehresman

Mach einfach git commit --amend --reset-author --no-edit. Bei älteren Commits können Sie eine interaktive Rebase durchführen und edit für das Commit auswählen, dessen Datum Sie ändern möchten.

git rebase -i <ref>

Ändern Sie dann das Commit mit --reset-author und --no-edit, um das Autorendatum auf das aktuelle Datum zu ändern:

git commit --amend --reset-author --no-edit

Fahren Sie schließlich mit Ihrer interaktiven Datenbank fort:

git rebase --continue
156

Ich habe ein Skript und ein Homebrew-Paket dafür geschrieben. Super einfach zu installieren, finden Sie auf GitHub PotatoLabs/git-redate Seite.

Syntax:

_git redate -c 3
_

Sie müssen nur _git redate_ ausführen und können alle Daten der letzten 5 Commits bearbeiten (es gibt auch die Option _-c_ für die Anzahl der Commits, die Sie zurückgehen möchten) Standardeinstellung ist 5). Lassen Sie mich wissen, wenn Sie Fragen, Kommentare oder Vorschläge haben!

enter image description here

103
Edmund

Jedem Commit sind zwei Daten zugeordnet, das Committer-Datum und das Autorendatum. Sie können diese Daten anzeigen mit:

git log --format=fuller

Wenn Sie das Autorendatum und das Committer-Datum der letzten 6 Commits ändern möchten, können Sie einfach eine interaktive Rebase verwenden:

git rebase -i HEAD~6

.

pick c95a4b7 Modification 1
pick 1bc0b44 Modification 2
pick de19ad3 Modification 3
pick c110e7e Modification 4
pick 342256c Modification 5
pick 5108205 Modification 6

# Rebase eadedca..5108205 onto eadedca (6 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using Shell
# d, drop = remove commit

Ersetzen Sie für alle Commits, bei denen Sie das Datum ändern möchten, pick durch edit (oder nur e), speichern Sie und beenden Sie Ihren Editor.

Sie können jetzt jedes Commit ändern, indem Sie das Autorendatum und das Committer-Datum im ISO-8601-Format angeben:

GIT_COMMITTER_DATE="2017-10-08T09:51:07" git commit --amend --date="2017-10-08T09:51:07"

Das erste Datum ist das Festschreibungsdatum, das zweite Datum ist das Autorendatum.

Dann gehe zum nächsten Commit mit:

git rebase --continue

Wiederholen Sie den Vorgang, bis Sie alle Ihre Commits geändert haben. Überprüfen Sie Ihren Fortschritt mit git status.

79
Ortomala Lokni

Aufbauend auf theosp 's answer schrieb ich ein Skript mit dem Namen git-cdc (zum Festschreiben des Änderungsdatums), das ich in mein PATH einfügte.

Der Name ist wichtig: git-xxx Überall in Ihrem PATH können Sie Folgendes eingeben:

git xxx
# here
git cdc ... 

Dieses Skript ist in der Bash-Version, auch unter Windows (da Git es aus seiner msys-Umgebung aufruft).

#!/bin/bash
# commit
# date YYYY-mm-dd HH:MM:SS

commit="$1" datecal="$2"
temp_branch="temp-rebasing-branch"
current_branch="$(git rev-parse --abbrev-ref HEAD)"

date_timestamp=$(date -d "$datecal" +%s)
date_r=$(date -R -d "$datecal")

if [[ -z "$commit" ]]; then
    exit 0
fi

git checkout -b "$temp_branch" "$commit"
GIT_COMMITTER_DATE="$date_timestamp" GIT_AUTHOR_DATE="$date_timestamp" git commit --amend --no-edit --date "$date_r"
git checkout "$current_branch"
git rebase  --autostash --committer-date-is-author-date "$commit" --onto "$temp_branch"
git branch -d "$temp_branch"

Damit können Sie Folgendes eingeben:

git cdc @~ "2014-07-04 20:32:45"

Das würde das Autor/Festschreibungsdatum der Festschreibung vor HEAD (@~) auf das angegebene Datum zurücksetzen.

git cdc @~ "2 days ago"

Das würde das Datum des Autors/Festschreibens des Festschreibens vor HEAD (@~) auf dieselbe Stunde, jedoch vor 2 Tagen, zurücksetzen.


Ilya Semenov erwähnt in den Kommentaren :

Unter OS X können Sie auch GNU coreutils (brew install coreutils) installieren, zu PATH (PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH") hinzufügen und dann "2 days ago" Syntax.

42
VonC
git commit --amend --date="now"
31
Harald Nordgren

Dies ändert das Datum (Zeitstempel) für das letzte Festschreiben

git commit --amend --date "Thu May 28 18:21:46 2015 +0530"

26
Nishant

wenn es sich um das vorherige letzte Commit handelt.

git rebase  -i HEAD~2
git commit --amend --date=now

wenn Sie bereits Push to Orgin und verwenden können:

git Push --force 

wenn Sie das Push nicht erzwingen können und es gedrückt wird, können Sie das Commit nicht ändern! .

18
Sérgio

Hier ist ein praktischer Alias, der sowohl die Festschreibungs- als auch die Autorenzeit der letzten Festschreibung in eine von date --date akzeptierte Zeit ändert:

[alias]
    cd = "!d=\"$(date -d \"$1\")\" && shift && GIT_COMMITTER_DATE=\"$d\" \
            git commit --amend --date \"$d\""

Verbrauch: git cd <date_arg>

Beispiele:

git cd now  # update the last commit time to current time
git cd '1 hour ago'  # set time to 1 hour ago

Edit: Hier ist eine stärker automatisierte Version, die prüft, ob der Index sauber ist (keine nicht festgeschriebenen Änderungen) und die letzte Festschreibungsnachricht wiederverwendet oder anderweitig fehlschlägt (narrensicher):

[alias]
    cd = "!d=\"$(date -d \"$1\")\" && shift && \
        git diff-index --cached --quiet HEAD --ignore-submodules -- && \
        GIT_COMMITTER_DATE=\"$d\" git commit --amend -C HEAD --date \"$d\"" \
        || echo >&2 "error: date change failed: index not clean!"
15
eold

Ich habe dieses npm-Paket erstellt, um das Datum alter Commits zu ändern.

https://github.com/bitriddler/git-change-date

Beispielnutzung:

npm install -g git-change-date
cd [your-directory]
git-change-date

Sie werden aufgefordert, das Commit auszuwählen, das Sie ändern möchten, und dann das neue Datum einzugeben.

Wenn Sie ein Commit durch einen bestimmten Hash ändern möchten, führen Sie diesen git-change-date --hash=[hash] aus.

13

Die folgende Bash-Funktion ändert die Zeit eines Commits für den aktuellen Zweig.

Achten Sie darauf, nicht zu verwenden, wenn Sie das Commit bereits übertragen haben oder wenn Sie das Commit in einem anderen Zweig verwenden.

# rewrite_commit_date(commit, date_timestamp)
#
# !! Commit has to be on the current branch, and only on the current branch !!
# 
# Usage example:
#
# 1. Set commit 0c935403 date to now:
#
#   rewrite_commit_date 0c935403
#
# 2. Set commit 0c935403 date to 1402221655:
#
#   rewrite_commit_date 0c935403 1402221655
#
rewrite_commit_date () {
    local commit="$1" date_timestamp="$2"
    local date temp_branch="temp-rebasing-branch"
    local current_branch="$(git rev-parse --abbrev-ref HEAD)"

    if [[ -z "$date_timestamp" ]]; then
        date="$(date -R)"
    else
        date="$(date -R --date "@$date_timestamp")"
    fi

    git checkout -b "$temp_branch" "$commit"
    GIT_COMMITTER_DATE="$date" git commit --amend --date "$date"
    git checkout "$current_branch"
    git rebase "$commit" --onto "$temp_branch"
    git branch -d "$temp_branch"
}
10
theosp

So ändern Sie sowohl das Autorendatum als auch das Festschreibungsdatum:

GIT_COMMITTER_DATE="Wed Sep 23 9:40 2015 +0200" git commit --amend --date "Wed Sep 23 9:40 2015 +0200"
9
Jan H

Wenn Sie das genaue Datum eines anderen Commits abrufen möchten (sagen wir, Sie haben ein Commit bearbeitet und möchten, dass es das Datum der ursprünglichen Pre-Rebase-Version hat):

git commit --amend --date="$(git show -s --format=%ai a383243)"

Dies korrigiert das Datum des HEAD Commits auf gena das Datum des Commits a383243 (bei Unklarheiten weitere Ziffern einfügen). Außerdem wird ein Editorfenster geöffnet, in dem Sie die Festschreibungsnachricht bearbeiten können.

Das ist das Autorendatum, für das Sie sich normalerweise interessieren - siehe andere Antworten für das Committer-Datum.

8
Mr_and_Mrs_D

Wenn Sie die akzeptierte Antwort ( https://stackoverflow.com/a/454750/72809 ) in der Standard-Windows-Befehlszeile ausführen möchten, benötigen Sie den folgenden Befehl:

git filter-branch -f --env-filter "if [ $GIT_COMMIT = 578e6a450ff5318981367fe1f6f2390ce60ee045 ]; then export GIT_AUTHOR_DATE='2009-10-16T16:00+03:00'; export GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; fi"

Anmerkungen:

  • Es ist möglicherweise möglich, den Befehl auf mehrere Zeilen aufzuteilen (Windows unterstützt das Aufteilen von Zeilen mit dem Carret-Symbol ^), aber es gelang mir nicht.
  • Sie können ISO-Daten schreiben, wodurch Sie viel Zeit sparen, wenn Sie den richtigen Wochentag finden, und allgemeine Frustration über die Reihenfolge der Elemente.
  • Wenn Sie möchten, dass Autor und Committer-Datum identisch sind, können Sie einfach auf die zuvor festgelegte Variable verweisen.

Vielen Dank an einen Blogbeitrag von Colin Svingen . Obwohl sein Code für mich nicht funktionierte, half er mir, die richtige Lösung zu finden.

5
Peter

Es gibt bereits viele gute Antworten, aber wenn ich das Datum für mehrere Festschreibungen an einem Tag oder in einem Monat ändern möchte, finde ich keine richtige Antwort. Deshalb erstelle ich ein neues Skript mit Erklärungen und hoffe, dass es jemandem hilft:

#!/bin/bash

# change GIT_AUTHOR_DATE for commit at Thu Sep 14 13:39:41 2017 +0800
# you can change the data_match to change all commits at any date, one day or one month
# you can also do the same for GIT_COMMITTER_DATE

git filter-branch --force --env-filter '

date_match="^Thu, 14 Sep 2017 13+"              

# GIT_AUTHOR_DATE will be @1505367581 +0800, Git internal format 
author_data=$GIT_AUTHOR_DATE;                   
author_data=${author_data#@}                  
author_data=${author_data% +0800}                # author_data is 1505367581     

oneday=$((24*60*60))

# author_data_str will be "Thu, 14 Sep 2017 13:39:41 +0800", RFC2822 format
author_data_str=`date -R -d @$author_data`      

if [[ $author_data_str =~ $date_match ]];
then
    # remove one day from author_data
    new_data_sec=$(($author_data-$oneday))
    # change to git internal format based on new_data_sec
    new_data="@$new_data_sec +0800"             
    export GIT_AUTHOR_DATE="$new_data"
fi
' --tag-name-filter cat -- --branches --tags

Das Datum wird geändert:

AuthorDate: Wed Sep 13 13:39:41 2017 +0800
1
detective0922

Wenn Commit noch nicht gepusht ist, kann ich so etwas verwenden: Um es zu speichern, geben Sie im VI-Editor den Befehlsmodus ": wq" ein und Sie können es pushen

0
Alex Tsumarau