[解決済み】Gitのコミットを過去にする方法とは?
質問
個人的に使用するためにすべてを Git に変換しているのですが、あるファイルの古いバージョンがすでにリポジトリにあるのを見つけました。 ファイルの正確な履歴を残すために、ファイルの "date modified" に従って正しい順序で履歴にコミットするにはどうしたらよいでしょうか。
このようなことができると聞きました。
git filter-branch --env-filter="GIT_AUTHOR_DATE=... --index-filter "git commit path/to/file --date " --tag-name-filter cat -- --all
解決方法は?
あなたが受けたアドバイスには欠陥があります。GIT_AUTHOR_DATEを無条件で
--env-filter
は、すべてのコミットの日付を書き換えてしまいます。また
ギットコミット
内部
--index-filter
.
ここでは、複数の独立した問題を扱っているのですね。
"now "以外の日付の指定
各コミットには、作者日付とコミッター日付の2つの日付があります。環境変数 GIT_AUTHOR_DATE と GIT_COMMITTER_DATE を指定することで、新しいコミットを書き込む際にそれぞれの日付を上書きすることができます。以下を参照してください。 git-commit(1) の「日付の書式」です。 または下記をご参照ください。
Git internal format = <unix timestamp> <time zone offset>, e.g. 1112926393 +0200
RFC 2822 = e.g. Thu, 07 Apr 2005 22:13:13 +0200
ISO 8601 = e.g. 2005-04-07T22:13:13
通常使用時に新しいコミットを書き込む唯一のコマンドは
ギットコミット
. また
--date
オプションを使えば、作者の日付を直接指定することができます。想定される使い方は
git filter-branch --env-filter
は、上記の環境変数も使用します (これらは、このオプションの名前の由来となった "env" の一部です。
git-filter-branch(1) の「オプション」です。
と、その基礎となる "plumbing "コマンド
git-commit-tree(1)です。
.
シングルへのファイルの挿入 レフ 歴史
リポジトリが非常にシンプルな場合 (すなわち、単一のブランチのみで、タグがない場合) は、おそらく git rebase を実行します。
以下のコマンドでは、"A "の代わりにコミットのオブジェクト名(SHA-1ハッシュ)を使用します。 を実行するときは、「日付の上書き」メソッドのいずれかを使用することを忘れないでください。 git commit .
---A---B---C---o---o---o master
git checkout master
git checkout A~0
git add path/to/file
git commit --date='whenever'
git tag ,new-commit -m'delete me later'
git checkout -
git rebase --onto ,new-commit A
git tag -d ,new-commit
---A---N (was ",new-commit", but we delete the tag)
\
B'---C'---o---o---o master
新しいファイルを含むように A を更新したい場合 (新しいコミットを作成してそこにファイルを追加するのではなく)、次のようにします。
git commit --amend
の代わりに
git commit
. その結果は次のようになります。
---A'---B'---C'---o---o---o master
上記は、新しいコミットの親となるべきコミットの名前を指定できる限り、動作します。もし、実際に新しいファイルを新しいルートコミット(親がいない)で追加したい場合は、少し異なる方法が必要です。
B---C---o---o---o master
git checkout master
git checkout --orphan new-root
git rm -rf .
git add path/to/file
GIT_AUTHOR_DATE='whenever' git commit
git checkout -
git rebase --root --onto new-root
git branch -d new-root
N (was new-root, but we deleted it)
\
B'---C'---o---o---o master
git checkout --orphan
は比較的新しいものですが (Git 1.7.2)、その中には
同じことをする他の方法
は、古いバージョンのGitでも動作します。
ファイルをマルチに挿入する レフ 歴史
リポジトリがより複雑な場合(つまり、複数の参照(ブランチ、タグなど)を持っている場合)、おそらくは
git フィルタブランチ
.
を使用する前に
git フィルタブランチ
は、リポジトリ全体のバックアップコピーを作成する必要があります。
簡単な
タール
は、作業ツリー全体(.gitディレクトリを含む)のアーカイブで十分です。
gitフィルターブランチ
はバックアップ参照を作成しますが、正しいフィルタリングでない場合、単に
.git
ディレクトリを作成し、バックアップから復元してください。
注:以下の例では、下位のコマンドである
git update-index --add
の代わりに
git add
. を使用することができます。
git add
しかし、まずファイルを外部の場所から期待されるパスにコピーする必要があります (
--index-filter
は、空の一時的な GIT_WORK_TREE 内でコマンドを実行します)。
もし、新しいファイルを既存のコミットごとに追加したい場合は、このようにします。
new_file=$(git hash-object -w path/to/file)
git filter-branch \
--index-filter \
'git update-index --add --cacheinfo 100644 '"$new_file"' path/to/file' \
--tag-name-filter cat \
-- --all
git reset --hard
を使用して既存のコミットの日付を変更する理由は特に見当たりません。
--env-filter 'GIT_AUTHOR_DATE=…'
. もし使うなら、コミットごとに日付を書き換えるような条件付きにするはずです。
もし、新しいファイルをある既存のコミット("A")の後のコミットだけに表示させたい場合は、このようにすればよいでしょう。
file_path=path/to/file
before_commit=$(git rev-parse --verify A)
file_blob=$(git hash-object -w "$file_path")
git filter-branch \
--index-filter '
if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$before_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi
' \
--tag-name-filter cat \
-- --all
git reset --hard
もしファイルを履歴の途中に挿入する新しいコミットで追加したい場合は、新しいコミットを生成する前に
git filter-branch
を追加し
--parent-filter
に
git フィルターブランチ
:
file_path=path/to/file
before_commit=$(git rev-parse --verify A)
git checkout master
git checkout "$before_commit"
git add "$file_path"
git commit --date='whenever'
new_commit=$(git rev-parse --verify HEAD)
file_blob=$(git rev-parse --verify HEAD:"$file_path")
git checkout -
git filter-branch \
--parent-filter "sed -e s/$before_commit/$new_commit/g" \
--index-filter '
if x=$(git rev-list -1 "$GIT_COMMIT" --not '"$new_commit"') &&
test -n "$x"; then
git update-index --add --cacheinfo 100644 '"$file_blob $file_path"'
fi
' \
--tag-name-filter cat \
-- --all
git reset --hard
新しいルートコミットで最初にファイルを追加するように手配することもできます。
git rebase
セクション(それを
new_commit
) を使用する場合は、無条件に
--index-filter
を、そして
--parent-filter
のように
"sed -e \"s/^$/-p $new_commit/\""
.
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] コミット前に 'git add' を取り消すにはどうすればよいですか?
-
[解決済み] 既存の、プッシュされていないコミットメッセージを修正するには?
-
[解決済み] Git リポジトリを以前のコミットに戻すにはどうすればよいですか?
-
[解決済み] Git で、ステージされていない変更を破棄するにはどうしたらいいですか?
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み] Git で最新のコミットを新しいブランチに移動する
-
[解決済み】ローカルのGitブランチの名前を変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】ファイルのアンリンクに失敗しました。もう一度試してみるべきですか?
-
[解決済み】Git Extensions。Win32 エラー 487: cygwinのヒープ用に領域を確保できなかった、Win32エラー0
-
[解決済み】git push >> fatal: 設定されたプッシュ先がありません。
-
Gitのプッシュでエラーが発生! [リモート拒否] master -> master (pre-receive hook declined) error: failed to push s...
-
git commit リモートエラー [rejected] master -> master (フェッチファースト)
-
[解決済み】Git Push Error: リポジトリデータベースにオブジェクトを追加する権限が不足しています。
-
[解決済み】マージが終了していません(MERGE_HEADは存在します)。
-
[解決済み] GitHubに空のブランチを作成する
-
[解決済み] SourceTree error:1407742E:SSLルーチン:SSL23_GET_SERVER_HELLO:tlsv1警告プロトコルバージョン
-
[解決済み] 現在の支店にはトラッキング情報がありません