Comment changer l'horodatage d'un vieux commit en Git?
Les réponses à Comment modifier l'existant, unpushed s'engage? décrit une façon de modifier les messages de propagation précédents qui n'ont pas encore été poussés en amont. Les nouveaux messages héritent des horodateurs des propagations originales. Cela semble logique, mais y a-t-il un moyen de modifier les horaires?
17 réponses
utilisez git filter-branch
avec un filtre env qui définit GIT_AUTH_DATE et GIT_COMMITTER_DATE pour le hachage spécifique de la propagation que vous cherchez à corriger.
cela invalidera cela et tous les coups de fouet futurs.
exemple:
si vous voulez changer les dates de commit 119f9ecf58069b265ab22f1f97d2b648faf932e0
, vous pouvez le faire avec quelque chose comme ceci:
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'
vous pouvez faire une rebase interactive et choisir éditer pour le commit dont vous souhaitez modifier la date. Lorsque le processus rebase s'arrête pour modifier le commit, Tapez par exemple:
git commit --amend --date="Wed Feb 16 14:00 2011 +0100"
ensuite, vous continuez votre rebase interactive.
mise à jour (en réponse au commentaire de studgeek): pour changer la date d'engagement au lieu de la date de l'auteur:
GIT_COMMITTER_DATE="Wed Feb 16 14:00 2011 +0100" git commit --amend
les lignes ci-dessus définissent une variable D'environnement GIT_COMMITTER_DATE qui est utilisée dans amend commit.
tout est testé en Git Bash.
une meilleure façon de traiter toutes ces suggestions en une seule commande est
LC_ALL=C GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
cela va mettre la date de propagation et d'auteur du dernier commit à" right now."
Just do git commit --amend --reset-author --no-edit
. Pour les commits plus anciens, vous pouvez faire un rebase interactif et choisir edit
pour le commit dont vous voulez modifier la date.
git rebase -i <ref>
puis modifier le commit avec --reset-author
et --no-edit
pour changer la date de l'auteur à la date actuelle:
git commit --amend --reset-author --no-edit
enfin continuer avec votre rebase interactive:
git rebase --continue
j'ai écrit un script et un paquet Homebrew pour ça. Très facile à installer, vous pouvez le trouver sur GitHub PotatoLabs/git-redate
page.
syntaxe:
git redate -c 3
il suffit d'exécuter git redate
et vous pourrez éditer toutes les dates dans vim des 5 dernières propagations (il y a aussi une option -c
pour combien de propagations vous voulez revenir en arrière, il suffit par défaut à 5). Laissez-moi savoir si vous avez des questions, des commentaires, ou des suggestions!
chaque commit est associé à deux dates, la date du commettant et la date de l'auteur. Vous pouvez voir ces dates avec:
git log --format=fuller
si vous voulez changer la date d'auteur et la date de committer des 6 dernières propagations, vous pouvez simplement utiliser un rebase interactif:
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
pour toutes les propagations où vous voulez changer la date, remplacer pick
par edit
(ou tout simplement e
), puis enregistrer et quitter votre éditeur.
vous pouvez maintenant modifier chaque commit en spécifiant la date de l'auteur et la date du committer au format ISO-8601:
GIT_COMMITTER_DATE="2017-10-08T09:51:07" git commit --amend --date="2017-10-08T09:51:07"
la première date est la date d'engagement, la seconde est la date de l'auteur.
puis passer à la prochaine commit avec:
git rebase --continue
répétez le processus jusqu'à ce que vous modifiez toutes vos propagations. Vérifiez votre progression avec git status
.
en me basant sur theosp 's answer , j'ai écrit un script appelé git-cdc
(pour changer la date de propagation) que j'ai mis dans mon PATH
.
le nom est important: git-xxx
n'importe où dans votre PATH
vous permet de taper:
git xxx
# here
git cdc ...
ce script est en bash, même sur Windows (puisque Git l'appellera de son msys environment )
#!/bin/bash
# commit
# date YYYY-mm-dd HH:MM:SS
commit="" datecal=""
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"
avec cela, vous pouvez taper:
git cdc @~ "2014-07-04 20:32:45"
qui réinitialiserait la date auteur/commit de la propagation avant la tête ( @~
) à la date spécifiée.
git cdc @~ "2 days ago"
qui aurait réinitialisé la date auteur/commit du commit avant la tête ( @~
) à la même heure, mais il y a 2 jours.
Ilya Semenov mentions dans les commentaires :
pour OS X, vous pouvez aussi installer GNU
coreutils
(brew install coreutils
), l'ajouter àPATH
(PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
) et ensuite utiliser la syntaxe2 days ago
".
cela change la date (horodatage) pour la dernière commit
git commit --amend --date "Thu May 28 18:21:46 2015 +0530"
s'il s'agit de la dernière propagation antérieure.
git rebase -i HEAD~2
git commit --amend --date=now
si vous poussez déjà à l'origine et pouvez utiliser la force:
git push --force
si vous ne pouvez pas forcer la poussée et si elle est poussée, vous ne pouvez pas changer la propagation! .
voici un alias pratique qui change les temps de propagation et d'auteur de la dernière propagation à un temps accepté par date --date
:
[alias]
cd = "!d=\"$(date -d \"\")\" && shift && GIT_COMMITTER_DATE=\"$d\" \
git commit --amend --date \"$d\""
Utilisation: git cd <date_arg>
exemples:
git cd now # update the last commit time to current time
git cd '1 hour ago' # set time to 1 hour ago
Edit: Voici une version plus automatisée qui vérifie que l'index est propre (pas de changements non engagés) et réutilise le dernier message de propagation, ou échoue autrement (preuve évidente):
[alias]
cd = "!d=\"$(date -d \"\")\" && 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!"
Si vous voulez obtenir la date exacte d'un autre commit (dire vous rebase édité un commit et veux avoir la date de la pré-rebase version):
git commit --amend --date="$(git show -s --format=%ai a383243)"
cette correction corrige la date de la tête commit pour être exactement la date de commit a383243 (inclure plus de chiffres s'il y a des ambiguïtés). Il affichera également une fenêtre Editeur pour que vous puissiez éditer le message de propagation.
C'est pour la date de l'auteur qui est ce que vous aimez habituellement - voir d'autres réponses pour la date de committer.
la fonction bash suivante changera l'Heure de n'importe quelle propagation sur la branche courante.
attention à ne pas utiliser si vous avez déjà poussé la validation ou si vous utilisez l'engagement dans une autre branche.
# 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="" date_timestamp=""
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"
}
pour changer à la fois la date de l'auteur et la date de l'engagement:
GIT_COMMITTER_DATE="Wed Sep 23 9:40 2015 +0200" git commit --amend --date "Wed Sep 23 9:40 2015 +0200"
j'ai créé ce paquet npm pour changer la date des anciennes propagations.
https://github.com/bitriddler/git-change-date
Exemple D'Utilisation:
npm install -g git-change-date
cd [your-directory]
git-change-date
, Vous serez invité à choisir le commit que vous voulez modifier, puis entrez la nouvelle date.
si vous voulez changer un commit par hachage spécifique, exécutez ce git-change-date --hash=[hash]
si vous voulez effectuer la réponse acceptée ( https://stackoverflow.com/a/454750/72809 ) dans la ligne de commande standard de Windows, vous avez besoin de la commande suivante:
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"
Notes:
- il est peut-être possible de diviser la commande sur plusieurs lignes (Windows supporte la division de ligne avec le symbole carret
^
), mais je n'ai pas réussi. - vous pouvez écrire des dates ISO, beaucoup de temps à trouver le bon jour de la semaine et le mécontentement général sur l'ordre des éléments.
- si vous voulez que la date de L'auteur et du Committer soit la même, vous pouvez simplement faire référence à la variable précédemment définie.
Merci beaucoup à un post de blog par Colin Svingen . Même si son code ne fonctionnait pas pour moi, il m'a aidé à trouver la bonne solution.
il y a déjà beaucoup de bonnes réponses, mais quand je veux changer la date pour plusieurs commits en un jour ou en un mois, je ne trouve pas de réponse appropriée. Donc je crée un nouveau script pour cela avec explication, en espérant qu'il aidera quelqu'un:
#!/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
la date sera changée:
AuthorDate: Wed Sep 13 13:39:41 2017 +0800