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

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

Ответ 1

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

Это аннулирует это и все будущие хэши.

Пример:

Если вы хотите изменить даты коммита 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'

Ответ 2

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

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.

Ответ 3

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

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

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

Ответ 4

Просто сделайте 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

Ответ 5

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

Синтаксис:

git redate -c 3

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

enter image description here

Ответ 6

Каждый коммит связан с двумя датами, датой коммиттера и датой автора. Вы можете просмотреть эти даты с:

git log --format=fuller

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

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), затем сохраните и выйдите из редактора.

Теперь вы можете изменить каждый коммит, указав дату автора и дату коммиттера в формате ISO-8601:

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

Первая дата - это дата коммита, вторая - дата автора.

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

git rebase --continue

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

Ответ 7

Основываясь на 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".

Ответ 8

git commit --amend --date="now"

Ответ 9

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

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

Ответ 10

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

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

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

git push --force 

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

Ответ 11

Вот удобный псевдоним, который изменяет время фиксации и автора последней фиксации на время, принятое 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

Следующая функция 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"
}

Ответ 13

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

Ответ 14

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

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

Ответ 15

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

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

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

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

Ответ 16

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

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

Ответ 17

Есть уже много отличных ответов, но когда я хочу изменить дату для нескольких коммитов за один день или через месяц, я не нахожу правильный ответ. Поэтому я создаю новый 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

Ответ 18

Если коммит еще не выдвинут, я могу использовать что-то вроде этого:

git commit --amend --date=" Wed Mar 25 10:05:44 2020 +0300"

после этого git bash открывает редактор с уже примененной датой, поэтому вам нужно просто сохранить его, набрав в командном режиме редактора VI ": wq", и вы можете нажать его