Saya mengonversikan semuanya menjadi Git untuk penggunaan pribadi saya dan saya menemukan beberapa versi lama dari file yang sudah ada di repositori. Bagaimana cara saya mengkomitnya ke histori dalam urutan yang benar sesuai dengan "tanggal modifikasi" file sehingga saya memiliki riwayat file yang akurat?
Saya diberitahu bahwa ini akan berhasil:
git filter-branch --env-filter="GIT_AUTHOR_DATE=... --index-filter "git commit path/to/file --date " --tag-name-filter cat -- --all
git
version-control
repository
git-commit
tidak diketahui
sumber
sumber
git commit --date="xxx day ago" -m "yyy"
cukup untuk tujuan itu jika ada yang bertanya-tanya.Jawaban:
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:
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 mencakupgit 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 .
Jika Anda ingin memperbarui A untuk memasukkan file baru (alih-alih membuat komit baru di mana ia ditambahkan), maka gunakan
git commit --amend
alih-alihgit commit
. Hasilnya akan terlihat seperti ini: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:
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 gantigit 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:
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:
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 :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/\""
.sumber
--index-filter
menerapkan komit yang dikembalikan olehgit rev-list
? Saat ini saya melihat filter indeks diterapkan pada sub-set daftar-rev. Hargai wawasan apa pun.-- --all
untuk memproses semua komit yang dapat dijangkau dari referensi apa pun. Contoh terakhir menunjukkan bagaimana mengubah hanya komit tertentu (cukup uji GIT_COMMIT untuk apa pun yang Anda suka). Untuk hanya mengubah daftar komitmen tertentu, Anda bisa menyimpan daftar sebelum memfilter (mis.git rev-list … >/tmp/commits_to_rewrite
), Lalu menguji keanggotaan di dalam filter (misif grep -qF "$GIT_COMMIT" /tmp/commits_to_rewrite; then git update-index …
.). Apa, tepatnya, yang ingin Anda capai? Anda mungkin ingin memulai pertanyaan baru jika terlalu banyak untuk dijelaskan dalam komentar.import-directories.perl
dari Git'scontrib/
(atauimport-tars.perl
, atauimport-zips.py
...) untuk membuat repositori Git baru dari snapshot Anda (bahkan dengan Cap waktu "lama"). Therebase
/filter-branch
teknik dalam jawaban saya hanya diperlukan jika Anda ingin memasukkan file yang “ditinggalkan” sejarah repositori yang sudah ada.Anda bisa membuat komit seperti biasa, tetapi ketika Anda komit, atur variabel lingkungan
GIT_AUTHOR_DATE
danGIT_COMMITTER_DATE
ke datetimes yang sesuai.Tentu saja, ini akan membuat komit di ujung cabang Anda (yaitu, di depan komit HEAD saat ini). Jika Anda ingin mendorongnya lebih jauh dalam repo, Anda harus mendapatkan sedikit kemewahan. Katakanlah Anda memiliki riwayat ini:
Dan Anda ingin komit baru Anda (ditandai sebagai "X") muncul kedua :
Cara termudah adalah dengan bercabang dari komit pertama, tambahkan komit baru Anda, lalu rebase semua komit lainnya di atas komit baru. Seperti itu:
sumber
GIT_AUTHOR_DATE='Fri Jul 26 19:32:10 2013 -0400' GIT_COMMITTER_DATE='Fri Jul 26 19:32:10 2013 -0400' git commit
2013-07-26T19:32:10
: kernel.org/pub/software/scm/git/docs/…THE_TIME='2019-03-30T8:20:00 -0500' GIT_AUTHOR_DATE=$THE_TIME GIT_COMMITTER_DATE=$THE_TIME git commit -m 'commit message here'
Saya tahu pertanyaan ini sudah cukup lama, tetapi itulah yang sebenarnya berhasil bagi saya:
sumber
--date
juga mendukung format tanggal relatif yang dapat dibaca manusia.git --date
hanya akan mengubah $ GIT_AUTHOR_DATE ... jadi tergantung pada keadaan Anda akan melihat tanggal saat ini terlampir pada komit ($ GIT_COMMITTER_DATE)git show <commit-hash> --format=fuller
. Di sana, Anda akan melihatAuthorDate
tanggal yang Anda tentukan, tetapiCommitDate
tanggal yang sebenarnya dari komit.Dalam kasus saya dari waktu ke waktu saya telah menyimpan banyak versi myfile seperti myfile_bak, myfile_old, myfile_2010, backup / myfile dll. Saya ingin memasukkan sejarah myfile di git menggunakan tanggal modifikasi mereka. Jadi, ganti nama tertua ke myfile,,
git add myfile
lalugit commit --date=(modification date from ls -l) myfile
, ganti nama tertua berikutnya ke myfile, git lain komit dengan --tanggal, ulangi ...Untuk mengotomatiskan hal ini, Anda dapat menggunakan shell-foo untuk mendapatkan waktu modifikasi file. Saya mulai dengan
ls -l
dancut
, tetapi stat (1) lebih langsungsumber
--date
"Ganti tanggal penulis yang digunakan dalam komit."git log
Tanggal tampaknya adalah AuthorDate,git log --pretty=fuller
menunjukkan AuthorDate dan CommitDate.git commit
pilihan--date
hanya akan memodifikasiGIT_AUTHOR_DATE
, tidakGIT_COMMITTER_DATE
. Seperti yang dijelaskan oleh Buku Pro Git : "Penulis adalah orang yang awalnya menulis karya, sedangkan komuter adalah orang yang terakhir mengaplikasikan karya." Dalam konteks tanggal,GIT_AUTHOR_DATE
adalah tanggal file diubah, sedangkanGIT_COMMITTER_DATE
tanggal adalah komitmennya. Penting di sini untuk mencatat bahwa secara default,git log
menampilkan tanggal penulis sebagai "Tanggal" tetapi kemudian menggunakan tanggal komit untuk pemfilteran ketika diberi--since
opsi.stat -c %y
di macOS (dan varian BSD lainnya) adalahstat -f %m
.Berikut ini adalah apa yang saya gunakan untuk melakukan perubahan pada hari
foo
-N=1
hari di masa lalu:Jika Anda ingin berkomitmen pada tanggal yang lebih lama, katakan 3 hari yang lalu, ubah saja
date
argumen:date -v-3d
.Itu sangat berguna ketika Anda lupa untuk melakukan sesuatu kemarin, misalnya.
UPDATE :
--date
juga menerima ekspresi suka--date "3 days ago"
atau bahkan--date "yesterday"
. Jadi kita bisa menguranginya menjadi satu perintah baris:sumber
git --date
hanya akan mengubah $ GIT_AUTHOR_DATE ... jadi tergantung pada keadaan Anda akan melihat tanggal saat ini terlampir pada komit ($ GIT_COMMITTER_DATE)git commit --amend --date="$(stat -c %y fileToCopyMTimeFrom)"
git commit --amend --date="$(date -R -d '2020-06-15 16:31')"
Dalam kasus saya, saat menggunakan opsi --date, proses git saya macet. Mungkin saya melakukan sesuatu yang mengerikan. Dan sebagai hasilnya beberapa file index.lock muncul. Jadi saya secara manual menghapus file .lock dari folder .git dan dieksekusi, untuk semua file yang dimodifikasi untuk dikomit dalam melewati tanggal dan itu bekerja saat ini. Terima kasih atas semua jawaban di sini.
sumber
git commit --date
. Juga, pesan komit contoh Anda harus diubah untuk mencegah pesan satu baris yang buruk seperti @JstRoRR inigit --date
hanya akan mengubah $ GIT_AUTHOR_DATE ... jadi tergantung pada keadaan Anda akan melihat tanggal saat ini terlampir pada komit ($ GIT_COMMITTER_DATE)Untuk membuat komit yang sepertinya dilakukan di masa lalu, Anda harus menetapkan keduanya
GIT_AUTHOR_DATE
danGIT_COMMITTER_DATE
:di mana
date -d'...'
bisa tanggal yang tepat suka2019-01-01 12:00:00
atau suka relatif5 months ago 24 days ago
.Untuk melihat kedua tanggal dalam log git gunakan:
Ini juga berfungsi untuk gabungan komitmen:
sumber
Anda selalu dapat mengubah tanggal di komputer Anda, membuat komit, lalu mengubah tanggal kembali dan mendorong.
sumber
Atau cukup gunakan git-git-sejarah palsu untuk menghasilkannya untuk rentang data tertentu.
sumber