Gitの古いコミットのタイムスタンプをどのように変更できますか?
-
19-08-2019 - |
質問
解決
修正するコミットの特定のハッシュにgit filter-branch
およびGIT_AUTHOR_DATE
を設定するenvフィルターで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'
他のヒント
インタラクティブなリベースを行い、日付を変更したいコミットに対して編集を選択できます。たとえば、入力したコミットを修正するためにリベースプロセスが停止した場合:
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
上記の行は、コミットの修正に使用される環境変数GIT_COMMITTER_DATEを設定します。
すべてはGit Bashでテストされています。
これらすべての提案を1つのコマンドで処理するより良い方法は
LC_ALL=C GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
これにより、最後のコミットのコミットと作成者の日付が<!> quot;今すぐに設定されます。<!> quot;
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
このためのスクリプトとHomebrewパッケージを書きました。インストールは非常に簡単で、GitHubの PotatoLabs/git-redate
ページで見つけることができます。
構文:
git redate -c 3
git redate
を実行するだけで、最新の5つのコミットのすべての日付を編集することができます(コミットしたいコミット数の-c
オプションもあります。デフォルトは5)。質問、コメント、提案がある場合はお知らせください!
各コミットは、コミッター日付と著者日付の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
日付を変更するすべてのコミットについて、pick
をedit
(または単に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
で進行状況を確認します。
theosp の答え、git-cdc
(変更日コミット用)というスクリプトを作成し、それをPATH
に入れました。
名前は重要です。git-xxx
のどこにでも入力できます。
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(coreutils
)より前のコミットの作成者/コミット日付が同じ時間である2日前にリセットされます。
OS Xの場合、GNU
brew install coreutils
(PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
)をインストールし、2 days ago
(<=>)に追加してから<!> quot; <=> <!> quot;を使用することもできます。構文。
git commit --amend --date="now"
これにより、最後のコミットの日付(タイムスタンプ)が変更されます
git commit --amend --date "Thu May 28 18:21:46 2015 +0530"
前回の最後のコミットの場合。
git rebase -i HEAD~2
git commit --amend --date=now
すでに原点にプッシュし、強制的に使用できる場合:
git push --force
プッシュを強制できない場合、およびプッシュされた場合、コミットを変更できません! 。
これは、最後のコミットのコミット時刻と作成者時刻の両方を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!"
古いコミットの日付を変更するためにこの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]
次の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"
}
作成者の日付とコミットの日付の両方を変更するには:
GIT_COMMITTER_DATE="Wed Sep 23 9:40 2015 +0200" git commit --amend --date "Wed Sep 23 9:40 2015 +0200"
別のコミットの正確な日付を取得したい場合(たとえば、コミットをリベース編集して、リベース前の元のバージョンの日付にしたい場合):
git commit --amend --date="$(git show -s --format=%ai a383243)"
これにより、HEADコミットの日付が、コミットの日付a383243に正確に修正されます(あいまいな場合は、さらに数字を含めます)。また、コミットメッセージを編集できるように、エディターウィンドウがポップアップ表示されます。
それはあなたが普段気にしている著者の日付のものです。コミッターの日付については他の回答をご覧ください。
受け入れられた回答を実行する場合( 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によるブログ投稿。彼のコードは私には機能しませんでしたが、正しい解決策を見つけるのに役立ちました。
すでに多くの素晴らしい答えがありますが、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
コミットがまだプッシュされていない場合、次のようなものを使用できます。git commit --amend --date = <!> quot; Wed Mar 25 10:05:44 2020 +0300 <!> quot; その後、git bashは既に適用された日付でエディターを開くため、VIエディターコマンドモード<!> quot;:wq <!> quot;を入力して保存するだけです。プッシュできます