Gitで古いコミットのタイムスタンプを変更するにはどうすればよいですか?


747

既存のプッシュされていないコミットを変更する方法への答えは?まだ上流にプッシュされていない以前のコミットメッセージを修正する方法を説明します。新しいメッセージは、元のコミットのタイムスタンプを継承します。これは理にかなっているようですが、時間を再設定する方法はありますか?



34
git commit --amend --reset-author
エリックM.

回答:


535

使用git filter-branchENVフィルタでは、セットがあることGIT_AUTHOR_DATEGIT_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'

4
「日付フォーマット」を参照してください。kernel.org/pub/software/scm/git/docs/git
ダスティン

8
これ正しい値が見つかりましたが、これらの変数を設定しただけでは、実際には古いコミットの日付に影響を与えるようには見えませんでした。
IQAndreas 2014年

36
「これはそのハッシュと将来のすべてのハッシュを無効にします」とはどういう意味ですか?
EpicDavi 2014年

16
EpicDavi:つまり、リモートリポジトリに強制的にプッシュする必要があり、コミットまたは将来のコミットをプルしたユーザーは、リセットしてプルするか、ゼロから削除してクローンを作成する必要があります。私の知る限り、これを回避する方法はありません。
EriF89

4
ただ、初心者のためのメモとして、短いハッシュは、if文での作業は、長いSHA-1を使用していません
40detectives

780

インタラクティブなリベースを行い、日付を変更したいコミットの編集を選択できます。たとえば、入力したコミットを修正するためにリベースプロセスが停止した場合:

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

その後、インタラクティブなリベースを続行します。

更新(studgeekのコメントに応じて):作成者の日付の代わりにコミット日付を変更するには、

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

上記の行は、comend commitで使用される環境変数GIT_COMMITTER_DATEを設定します。

すべてGit Bashでテストされています。


22
@nschum --date = ""および--data "non-date-text"はすべて、現在の日付を使用して同じ結果になります。
Paul Pladijs、

12
gitバージョン1.7.7.1で--date = "now"を使用すると致命的:無効な日付形式:now
Aragorn

4
その日あなたが望む変化に最新のコミットされてコミットすると、あなたは何をする必要はありませんrebase、あなただけ行うことができますgit commit --amend
同名の

7
GIT_COMMITTER_DATE = ""をエクスポートする代わりに、GIT_COMMITTER_DATEの設定を解除してみてください。
Mark E. Haase

2
自動スクリプトで使用できるように、-no-editを使用しています!+ var fixedDate = strftime(new Date(), "%c"); + var result = shelljs.exec("git commit --amend --date=\"" + fixedDate + "\" --no-edit");
Marcello de Sales、

392

これらすべての提案を1つのコマンドで処理するより良い方法は、

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

これにより、最後のコミットのコミットと作成者の日付が「今」に設定されます。


22
これは、インタラクティブなリベース中に特定のコミットを編集するのに最適です。
friederbluemle 2013

2
シェルにエイリアスを追加することもできます
kaleissin

14
Gitは日付形式をロケールに対応していないようです。完全に正しくするには、次のようにする必要があります。LANG= GIT_COMMITTER_DATE="`date`" git commit --amend --date "`date`"
MichałGóralMay

ブランチをリベースしてスカッシュするときにそれを行うので、タイムスタンプが更新された単一のコミットが作成されます。
Luke Ehresman、2016

12
あなたも行うことができます--date "now"。Git> = 2はそれを解釈します。
wisbucky 2018年

189

ただしてください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
良いコール使用上--reset-author、それはgitの1.6.6の新機能(REF gitlog.wordpress.com/2010/01/13/git-1-6-6
ティム・アベル

1
これは、リベースされたPRのコミットを正しい順序でGithubに表示するためにうまく機能します。それらはタイムスタンプでコミットし、このトリックがないと、タイムスタンプはすべて同じになる可能性があるためです。
Nathan Long

4
メモ--reset-authorは、作成者と作成者日付の両方を現在にリセットします。
wisbucky 2018年

これにより「コミッター日」も同時に変更されますか?
luochen1990

134

このためのスクリプトとHomebrewパッケージを作成しました。インストールは非常に簡単で、GitHub PotatoLabs/git-redateページで見つけることができます。

構文:

git redate -c 3

実行git redateする必要があるだけで、最新の5つのコミットのvimですべての日付を編集できます(-c戻りたいコミットの数のオプションもあり、デフォルトは5です)。質問、コメント、提案がある場合はお知らせください!

ここに画像の説明を入力してください


2
nanoではなくvimを使用しなければならなかったとしても、素晴らしいことです
howdoyouturnthison 2017年

素晴らしいスクリプトをありがとう@Edmund git redate -cを実行した後、viで編集する日付が表示されませんでした。私が見るのは%cIだけです| XXXXXXXXXXXXXXXX | 最初のコミット。手伝ってくれませんか?ありがとう
Kiem Nguyen

@KiemNguyen git redate(-cなし)を試してみませんか?
bigpotato

4
ここでMinaと@howdoyouturnthisonに完全に同意します。EDITOR環境変数を使用して、エディターに依存しないようにしてください。(私はLinuxではなく、macです...)
ympostor

3
@Edmundに感謝!念のため、スクリプトでCOMMITSのデフォルト値の処理に問題があります。設定されていない場合、次のコードは最後のコミットに(私が推測/見つけた)だけにフィルターを適用します。"git filter-branch -f --env-filter" $ ENVFILTER "HEAD〜$ COMMITS..HEAD> / dev / null"
Grigory Entin '30

103

各コミットは、コミッターの日付と作成者の日付の2つの日付に関連付けられています。これらの日付は次の方法で表示できます。

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

日付を変更するすべてのコミットについてpickedit(またはe)に置き換え、保存してエディターを終了します。

ISO-8601形式で作成者の日付とコミッターの日付を指定することにより、各コミットを修正できます。

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

最初の日付はコミット日、2番目の日付は作成者の日付です。

次に、次のコミットに移動します:

git rebase --continue

すべてのコミットを修正するまで、このプロセスを繰り返します。で進行状況を確認してくださいgit status


1
私はこれをたどり、「別の頭」になりました!
Simon H

1
@Simon H私は私の答えをもう一度テストしましたが、うまくいきます。あなたは別の何かをタイプするべきでした、またはあなたはもう離れた頭にいました 取り外したヘッドから戻りたい場合は、を実行してくださいgit checkout name-of-current-branch
Ortomala Lokni 2017

4
これが最善かつ最も簡単な答えです。小さなヒント:古いコミットメッセージを保持するに--no-edit はin git commit --amend --no-edit --date=2017-10-08T09:51:07を使用します。
Mariusz Pawelski

2
また、更新する場合がありますGIT_COMMITTER_DATE 、ここで説明したようeddmann.com/posts/...
smihael

2
@smihaelリンクありがとうございます。私はあなたの提案を私の答えに含めました。
Ortomala Lokni


44

theosp回答基づいて、git-cdc(変更日付のコミット用に)というスクリプトを記述しましたPATH

名前は重要です。git-xxxどこにでもPATH入力できます。

git xxx
# here
git cdc ... 

そのスクリプトは、Windowsでもbashにあります(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"

これにより、HEAD(@~)の前のコミットの作成者/コミット日が指定された日付にリセットされます。

git cdc @~ "2 days ago"

これにより、HEAD(@~)の前のコミットの作成者/コミット日が同じ時間、ただし2日前にリセットされます。


イリヤ・セメノフコメントで言及しています

OS Xの場合、GNU coreutilsbrew install coreutils)をインストールし、それをPATHPATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH")に追加して、" 2 days ago"構文を使用することもできます。


1
私にとって、これは日付と時刻を1つの引用符で囲むことでのみ機能しました。 git cdc @~ "2014-07-04 20:32:45それ以外の場合は、時刻を認識せず、時刻00:00:00を取得します(3番目の引数になります)。
peschü

3
OS Xの場合brew install coreutils、GNU coreutils()をインストールし、それをPATH(PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH")に追加して、「2日前」の構文を使用することもできます。
Ilya Semenov

1
@IlyaSemenov興味深い。見やすくするために、回答にコメントを含めました。
VonC、2015

私はあなたの最初の例を使おうとしていますが、「致命的:無効な日付形式:」を受け取り続けます。Mac OS Xが期待する日付形式は何ですか?
usbsnowcrash

Macでは@usbsnowcrashがわかりません。2番目の例「2 days ago」は機能しますか?
VonC 2016年

25

複数のコミット日付を編集する方法

他の回答は、いくつかのコミット日付を編集するのにあまり便利ではありません。数年後にこの質問に戻り、テクニックを共有しました。

最後の4つのコミットの日付を変更するには:

git rebase -i HEAD~4

次のようにリベースを編集し、exec必要に応じて行を挿入して日付を変更します。

pick 4ca564e Do something
exec git commit --amend --no-edit --date "1 Oct 2019 12:00:00 PDT"
pick 1670583 Add another thing
exec git commit --amend --no-edit --date "2 Oct 2019 12:00:00 PDT"
pick b54021c Add some tests
exec git commit --amend --no-edit --date "3 Oct 2019 12:00:00 PDT"
pick e8f6653 Fix the broken thing
exec git commit --amend --no-edit --date "4 Oct 2019 12:00:00 PDT"

--amend/ --dateオプションの素晴らしい使い方。環境変数を使用して私自身の答えよりも簡単です。賛成。
VonC、

現在の日付/時刻をパラメーターとして使用することは可能ですか?
19

更新GIT_AUTHOR_DATEのみです。
ブレーズ

再 「現在の日付/時刻をパラメーターとして使用することは可能ですか?」:「今」は有効な日付として理解されるため、上記のexec行は次のようになりますexec git commit --amend --no-edit --date "now"
Andrew Richards

20

以前の最後のコミットの場合。

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

すでにorginにプッシュしていて、強制的に使用できる場合:

git push --force 

プッシュを強制できず、プッシュされた場合、コミットを変更できません!。


18

以下は、最後のコミットのコミット時刻と作成者時刻の両方を、が受け入れた時刻に変更する便利なエイリアスです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

編集:これ はより自動化されたバージョンで、インデックスがクリーン(コミットされていない変更がない)であることを確認し、最後のコミットメッセージを再利用するか、それ以外の場合は失敗します(フールプルーフ)。

[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!"

17

古いコミットの日付を変更するために、この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]


私はこれが素晴らしく、美しく働いたことを言いたかっただけです。ありがとう、あなたは私にかなりの時間を節約してくれました!
パランザ

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 "$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"
}

1
あなたはそこにバグがあります: if [[ -z "$commit" ]]->if [[ -z "$date_timestamp" ]]
blueFast

いいね!GIT_COMMITTER_DATE=メソッドの最後に設定して、指定された日付を維持するためのさらなる手動コミットを防ぐことをお勧めします。
loopkin

@ loopkin、GIT_COMMITTER_DATEは「git commit」コマンドに対してのみ設定されるため、後でクリアする必要はありません
nimrodm

@nimrodm、私はもう一度テストしましたが、あなたは正しいです。ご指摘いただきありがとうございます。
loopkin

12

著者の日付とコミットの日付の両方を変更するには:

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

10

別のコミットの正確な日付を取得したい場合(コミットをリベース編集して、元のリベース前のバージョンの日付にしたいとします):

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

これにより、HEADコミットの日付が正確にコミット日付a383243に修正されます(あいまいな場合は、さらに桁を含めます)。また、エディタウィンドウがポップアップ表示されるので、コミットメッセージを編集できます。

それはあなたが普段気にしている著者の日付です-コミッターの日付については他の答えを見てください。


7

承認された回答(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はキャレット記号を使用した行分割をサポートしています^)、成功しませんでした。
  • ISO日付を記述して、要素の順序に対する正しい曜日と一般的な不満を見つける時間を大幅に節約できます。
  • 作成者とコミッターの日付を同じにしたい場合は、以前に設定した変数を参照するだけです。

Colin Svingenによるブログ投稿に感謝します。彼のコードは私にとってはうまくいきませんでしたが、それは私が正しい解決策を見つけるのに役立ちました。


7

コミットがまだプッシュされていない場合は、次のようなものを使用できます。

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

その後、git bashはすでに適用された日付でエディターを開くので、VIエディターのコマンドモード「:wq」を入力して保存するだけで、プッシュできます。


2
良い答えに追加するだけです:コミットメッセージを編集したくない場合(コミット日付を変更したいだけの場合)、--no-editオプションを使用します。
アントニオヴィニシウスメネゼスメデイ

また、コミットがすでにプッシュされている場合でも、git push -f(強制更新)を使用して変更されたコミットをプッシュできます。ただし、副作用がある場合があります。(特に多くの人がリポジトリのローカルクローンを持っている場合)
Antonio Vinicius Menezes Medei


2

すばらしい答えはたくさんありますが、1日または1か月に複数のコミットの日付を変更したい場合、適切な答えが見つかりません。だから私は説明のためにこれのための新しいスクリプトを作成します、それが誰かを助けることを願っています:

#!/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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.