Как можно изменить временную метку старого коммита в Git? - PullRequest
640 голосов
/ 18 января 2009

Ответы на Как изменить существующие невыдвинутые коммиты? описывают способ изменения предыдущих сообщений коммитов, которые еще не были переданы в восходящий поток. Новые сообщения наследуют временные метки оригинальных коммитов. Это кажется логичным, но есть ли способ также переустановить время?

Ответы [ 18 ]

15 голосов
/ 16 мая 2014

Вот удобный псевдоним, который изменяет время фиксации и автора последнего коммита на время, принятое date --date:

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

Использование: git cd <date_arg>

Примеры:

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

Edit: Вот более автоматизированная версия, которая проверяет, что индекс является чистым (без незафиксированных изменений) и повторно использует последнее сообщение о коммите, или в противном случае происходит сбой (защита от ошибок):

[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!"
12 голосов
/ 25 ноября 2017

Я создал этот пакет npm для изменения даты старых коммитов.

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

Пример использования:

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

Вам будет предложено выбрать коммит, который вы хотите изменить, а затем ввести новую дату.

Если вы хотите изменить коммит по конкретному хешу, запустите этот git-change-date --hash=[hash]

10 голосов
/ 08 июня 2014

Следующая функция bash изменит время любого коммита в текущей ветви.

Будьте осторожны, чтобы не использовать, если вы уже нажали коммит или если вы используете коммит в другой ветке.

# 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"
}
8 голосов
/ 18 ноября 2016

Если вы хотите получить точную дату другого коммита (скажем, вы перебазировали отредактированный коммит и хотите, чтобы в нем была дата оригинальной версии пре-ребаса):

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

Это исправляет дату фиксации HEAD, чтобы быть точно датой фиксации a383243 (включайте больше цифр, если есть неоднозначности). Также появится окно редактора, чтобы вы могли редактировать сообщение о коммите.

Это дата автора, о которой вы обычно заботитесь - см. Другие ответы на дату коммиттера.

8 голосов
/ 23 сентября 2015

Чтобы изменить дату автора и дату принятия:

GIT_COMMITTER_DATE="Wed Sep 23 9:40 2015 +0200" git commit --amend --date "Wed Sep 23 9:40 2015 +0200"
5 голосов
/ 05 февраля 2016

Если вы хотите выполнить принятый ответ (https://stackoverflow.com/a/454750/72809) в стандартной командной строке Windows, вам потребуется следующая команда:

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"

Примечания:

  • Может быть возможно разделить команду на несколько строк (Windows поддерживает разделение строк с помощью символа carret ^), но мне это не удалось.
  • Вы можете написать даты ISO, сэкономив много времени на поиске правильного дня недели и общего разочарования по поводу порядка элементов.
  • Если вы хотите, чтобы дата Author и Committer была одинаковой, вы можете просто сослаться на ранее установленную переменную.

Большое спасибо за сообщение в блоге Колина Свингена . Хотя его код не работал для меня, он помог мне найти правильное решение.

1 голос
/ 14 сентября 2017

Уже есть много хороших ответов, но когда я хочу изменить дату для нескольких коммитов в один день или в один месяц, я не могу найти правильный ответ. Поэтому я создаю новый сценарий для этого с объяснением, надеюсь, он кому-нибудь поможет:

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

Дата будет изменена:

AuthorDate: Wed Sep 13 13:39:41 2017 +0800
0 голосов
/ 25 марта 2019

Если коммит еще не отправлен, я могу использовать что-то вроде этого: git commit --amend --date = "Ср 25 марта 10:05:44 2020 +0300" после этого git bash открывает редактор с уже примененной датой, поэтому вам нужно просто сохранить его, набрав в командном режиме редактора VI ": wq", и вы можете нажать его

...