Как изменить временную метку старой фиксации в Git?

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

535
задан Dhskjlkakdh 18 янв. '09 в 9:13
источник поделиться
17 ответов

Используйте git filter-branch с фильтром env, который устанавливает GIT_AUTHOR_DATE и GIT_COMMITTER_DATE для конкретного хэша коммита, который вы хотите исправить.

Это приведет к недействительности этого и всех будущих хэшей.

Пример:

Если вы хотите изменить даты commit 119f9ecf58069b265ab22f1f97d2b648faf932e0, вы можете сделать это примерно так:

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'
392
ответ дан Dustin 18 янв. '09 в 9:48
источник поделиться

Вы можете выполнить интерактивную перезагрузку и выбрать править для фиксации, чью дату вы хотите изменить. Когда процесс переустановки прекращается для внесения изменений в коммит, который вы вводите, например:

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

Затем вы продолжите свою интерактивную перезагрузку.

UPDATE (в ответ на комментарий studgeek): изменить дату фиксации вместо даты автора:

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

В приведенных выше строках задана переменная среды GIT_COMMITTER_DATE, которая используется в изменении commit.

Все протестировано в Git Bash.

586
ответ дан Paul Pladijs 16 февр. '11 в 16:50
источник поделиться

Лучшим способом обработки всех этих предложений в одной команде является

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

Это установит последнюю фиксацию фиксации и дату автора "прямо сейчас".

327
ответ дан Luke Ehresman 14 марта '12 в 14:32
источник поделиться

Просто сделайте git commit --amend --reset-author --no-edit. Для более старых коммитов вы можете выполнить интерактивную перезагрузку и выбрать edit для фиксации, чью дату вы хотите изменить.

git rebase -i <ref>

Затем измените фиксацию с помощью --reset-author и --no-edit, чтобы изменить дату автора на текущую дату:

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

Наконец, продолжите свою интерактивную перезагрузку:

git rebase --continue
113
ответ дан Miguel de Val-Borro 21 июля '15 в 16:25
источник поделиться

Я написал для этого пакет script и Homebrew. Супер прост в установке, вы можете найти его на GitHub PotatoLabs/git-redate.

Синтаксис:

  git redate -c 3
Код>

Вам просто нужно запустить git redate, и вы сможете редактировать все даты в vim из последних 5 коммитов (есть также опция -c для количества фиксаций вы хотите вернуться назад, он по умолчанию равен 5). Сообщите мне, есть ли у вас какие-либо вопросы, комментарии или предложения!

введите описание изображения здесь

50
ответ дан Edmund 17 окт. '16 в 23:24
источник поделиться

Если вы хотите изменить дату последних 6 коммитов, вы можете просто использовать интерактивную rebase:

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 log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

Для всех коммитов, где вы хотите изменить дату, замените pick на edit (или просто e), затем сохраните и закройте редактор.

Теперь вы можете изменить каждый фиксатор, установить текущую дату с помощью:

git commit --amend --date=now

или если вы хотите указать дату в формате ISO-8601:

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

Затем перейдите к следующему фиксации с помощью:

git rebase --continue

Повторяйте процесс до тех пор, пока вы не измените все свои фиксации. Проверьте свою прогрессию с помощью git status.

43
ответ дан Ortomala Lokni 02 февр. '17 в 11:50
источник поделиться

Основываясь на theosp answer, я написал script под названием git-cdc (для фиксация даты изменения), который я ввел в свой PATH.

Важное значение: git-xxx в любом месте вашего PATH позволяет ввести:

git xxx
# here
git cdc ... 

Что script находится в bash, даже в Windows (поскольку Git будет вызывать его из msys)

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

С этим вы можете ввести:

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

Это будет reset дата автора/фиксации фиксации до HEAD (@~) до указанной даты.

git cdc @~ "2 days ago"

Это будет reset дата автора/фиксации фиксации перед HEAD (@~) в тот же час, но 2 дня назад.


Илья Семенов упоминает в комментариях:

Для OS X вы также можете установить GNU coreutils (brew install coreutils), добавить его в PATH (PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"), а затем использовать синтаксис "2 days ago".

40
ответ дан VonC 05 июля '14 в 12:29
источник поделиться

Это изменяет дату (временную метку) для последнего фиксации

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

24
ответ дан Nishant 02 июня '15 в 16:04
источник поделиться

если это предыдущая последняя фиксация.

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

если вы уже нажимаете на orgin и можете принудительно использовать:

git push --force 

если вы не можете принудительно нажать и если он нажат, вы не можете изменить фиксацию!,

14
ответ дан Sérgio 25 апр. '16 в 3:34
источник поделиться

Вот удобный псевдоним, который изменяет время фиксации и автора последней фиксации на время, принятое 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!"
14
ответ дан eold 16 мая '14 в 8:41
источник поделиться

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

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

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

Что для даты автора, которую обычно интересует, - см. другие ответы для даты коммиттера.

8
ответ дан Mr_and_Mrs_D 18 нояб. '16 в 14:17
источник поделиться

Следующая функция 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 "$commit" ]]; 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
ответ дан theosp 08 июня '14 в 13:10
источник поделиться

Чтобы изменить дату автора и дату фиксации:

GIT_COMMITTER_DATE="Wed Sep 23 9:40 2015 +0200" git commit --amend --date "Wed Sep 23 9:40 2015 +0200"
6
ответ дан Jan H 23 сент. '15 в 10:41
источник поделиться

Если вы хотите выполнить принятый ответ (qaru.site/questions/5133/...) в стандартной командной строке 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 была одинаковой, вы можете просто ссылаться на ранее установленную переменную.

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

4
ответ дан Peter 05 февр. '16 в 11:58
источник поделиться

Я создал этот пакет 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]

4
ответ дан Kareem Elbahrawy 25 нояб. '17 в 1:20
источник поделиться

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

#!/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
1
ответ дан detective0922 14 сент. '17 в 13:24
источник поделиться
git commit --amend --date="now"
0
ответ дан Harald Nordgren 07 апр. '18 в 18:16
источник поделиться

Другие вопросы по меткам или Задайте вопрос