Nasihat yang Anda berikan cacat. Menyetel GIT_AUTHOR_DATE tanpa syarat dalam suatu --env-filter
akan menulis ulang tanggal setiap komit. Juga, tidak biasa menggunakan komit git di dalam --index-filter
.
Anda berurusan dengan banyak masalah independen di sini.
Menentukan Tanggal Selain "sekarang"
Setiap komit memiliki dua tanggal: tanggal penulis dan tanggal committer. Anda dapat mengesampingkan masing-masing dengan memberikan nilai melalui variabel lingkungan GIT_AUTHOR_DATE dan GIT_COMMITTER_DATE untuk perintah apa pun yang menulis komit baru. Lihat “Format Tanggal” di git-commit (1) atau di bawah ini:
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
Satu-satunya perintah yang menulis komit baru selama penggunaan normal adalah git commit . Ini juga memiliki --date
opsi yang memungkinkan Anda menentukan secara langsung tanggal penulis. Penggunaan yang Anda antisipasi mencakup git filter-branch --env-filter
juga menggunakan variabel lingkungan yang disebutkan di atas (ini adalah bagian dari "env" setelah opsi tersebut dinamai; lihat "Opsi" di cabang-filter-git (1) dan perintah "plumbing" yang mendasari perintah git-commit -tree (1) .
Memasukkan File ke dalam Riwayat ref Tunggal
Jika repositori Anda sangat sederhana (yaitu Anda hanya memiliki satu cabang, tanpa tag), maka Anda mungkin dapat menggunakan git rebase untuk melakukan pekerjaannya.
Dalam perintah berikut, gunakan nama objek (SHA-1 hash) dari komit bukan "A". Jangan lupa untuk menggunakan salah satu metode "date override" saat Anda menjalankan 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
Jika Anda ingin memperbarui A untuk memasukkan file baru (alih-alih membuat komit baru di mana ia ditambahkan), maka gunakan git commit --amend
alih-alih git commit
. Hasilnya akan terlihat seperti ini:
---A'---B'---C'---o---o---o master
Cara di atas berfungsi selama Anda dapat menyebutkan komit yang seharusnya menjadi induk dari komit baru Anda. Jika Anda benar-benar ingin file baru Anda ditambahkan melalui komit root baru (tidak ada orang tua), maka Anda perlu sesuatu yang sedikit berbeda:
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
relatif baru (Git 1.7.2), tetapi ada cara lain untuk melakukan hal yang sama yang bekerja pada Git versi lama.
Memasukkan File ke dalam Riwayat Multi- ref
Jika repositori Anda lebih kompleks (mis. Ia memiliki lebih dari satu ref (cabang, tag, dll.)), Maka Anda mungkin perlu menggunakan git filter-branch . Sebelum menggunakan cabang-git filter , Anda harus membuat salinan cadangan seluruh repositori Anda. Arsip tar sederhana dari seluruh pohon kerja Anda (termasuk direktori .git) sudah cukup. git filter-branch memang membuat referensi cadangan, tetapi seringkali lebih mudah untuk memulihkan dari penyaringan yang tidak tepat dengan hanya menghapus .git
direktori Anda dan mengembalikannya dari cadangan Anda.
Catatan: Contoh-contoh di bawah ini menggunakan perintah tingkat bawah git update-index --add
sebagai ganti git add
. Anda dapat menggunakan git add , tetapi pertama-tama Anda harus menyalin file dari beberapa lokasi eksternal ke jalur yang diharapkan ( --index-filter
menjalankan perintahnya dalam GIT_WORK_TREE sementara yang kosong).
Jika Anda ingin file baru Anda ditambahkan ke setiap komit yang ada, maka Anda dapat melakukan ini:
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
Saya tidak benar-benar melihat alasan untuk mengubah tanggal dari komitmen yang ada --env-filter 'GIT_AUTHOR_DATE=…'
. Jika Anda menggunakannya, Anda harus membuatnya bersyarat sehingga akan menulis ulang tanggal untuk setiap komit.
Jika Anda ingin file baru Anda hanya muncul di komit setelah beberapa komit yang ada ("A"), maka Anda dapat melakukan ini:
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
Jika Anda ingin file ditambahkan melalui komit baru yang akan dimasukkan ke tengah-tengah riwayat Anda, maka Anda perlu membuat komit baru sebelum menggunakan cabang-git filter dan menambahkan --parent-filter
ke cabang-git filter :
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
Anda juga dapat mengatur agar file ditambahkan pertama kali dalam komit root baru: buat komit root baru Anda melalui metode "yatim" dari bagian git rebase (tangkap dalam new_commit
), gunakan tanpa syarat --index-filter
, dan --parent-filter
sejenisnya "sed -e \"s/^$/-p $new_commit/\""
.