Saya ingin menempatkan proyek Git di GitHub tetapi berisi file-file tertentu dengan data sensitif (nama pengguna dan kata sandi, seperti /config/deploy.rb untuk capistrano).
Saya tahu saya bisa menambahkan nama file ini ke .gitignore , tetapi ini tidak akan menghapus riwayatnya di dalam Git.
Saya juga tidak ingin memulai lagi dengan menghapus direktori /.git.
Apakah ada cara untuk menghapus semua jejak file tertentu di riwayat Git Anda?
Jawaban:
Untuk semua tujuan praktis, hal pertama yang harus Anda khawatirkan adalah MENGUBAH PASSWORDS ANDA! Tidak jelas dari pertanyaan Anda apakah repositori git Anda sepenuhnya lokal atau apakah Anda memiliki repositori jarak jauh di tempat lain; jika remote dan tidak diamankan dari orang lain, Anda memiliki masalah. Jika ada orang yang mengkloning repositori itu sebelum Anda memperbaikinya, mereka akan memiliki salinan kata sandi Anda di mesin lokal mereka, dan tidak mungkin Anda bisa memaksa mereka untuk memperbarui ke versi "tetap" Anda dengan itu hilang dari sejarah. Satu-satunya hal aman yang dapat Anda lakukan adalah mengubah kata sandi Anda menjadi sesuatu yang lain di mana pun Anda menggunakannya.
Dengan cara itu, inilah cara untuk memperbaikinya. GitHub menjawab pertanyaan itu sebagai FAQ :
Catatan untuk pengguna Windows : gunakan tanda kutip ganda (") sebagai ganti tunggal dalam perintah ini
Pembaruan 2019:
Ini adalah kode saat ini dari FAQ:
Ingatlah bahwa setelah Anda mendorong kode ini ke repositori jarak jauh seperti GitHub dan yang lainnya telah mengkloning repositori jarak jauh itu, Anda sekarang berada dalam situasi di mana Anda menulis ulang sejarah. Ketika orang lain mencoba menarik perubahan terbaru Anda setelah ini, mereka akan mendapatkan pesan yang menunjukkan bahwa perubahan tidak dapat diterapkan karena itu bukan fast-forward.
Untuk memperbaikinya, mereka harus menghapus repositori yang sudah ada dan mengkloning kembali, atau mengikuti instruksi di bawah "MEMULIHKAN DARI REBASE UPSTREAM" di halaman manual git-rebase .
Kiat : Jalankan
git rebase --interactive
Di masa depan, jika Anda secara tidak sengaja melakukan beberapa perubahan dengan informasi sensitif tetapi Anda perhatikan sebelum mendorong ke repositori jarak jauh, ada beberapa perbaikan yang lebih mudah. Jika komit terakhir adalah yang menambahkan informasi sensitif, Anda dapat menghapus informasi sensitif, kemudian jalankan:
Itu akan mengubah komit sebelumnya dengan setiap perubahan baru yang Anda buat, termasuk seluruh penghapusan file yang dilakukan dengan a
git rm
. Jika perubahan lebih lanjut dalam sejarah tetapi masih tidak didorong ke repositori jarak jauh, Anda dapat melakukan rebase interaktif:Itu membuka editor dengan komit yang Anda buat sejak nenek moyang terakhir bersama dengan repositori jarak jauh. Ubah "pilih" menjadi "edit" pada baris apa pun yang mewakili komit dengan informasi sensitif, dan simpan dan keluar. Git akan berjalan melalui perubahan, dan meninggalkan Anda di tempat di mana Anda dapat:
Untuk setiap perubahan dengan informasi sensitif. Akhirnya, Anda akan kembali ke cabang Anda, dan Anda dapat dengan aman mendorong perubahan baru.
sumber
filter-branch
kode Anda dan bahwa pada halaman github yang Anda tautkan. Misalnya baris ke-3 mereka--prune-empty --tag-name-filter cat -- --all
. Apakah solusinya berubah atau saya kehilangan sesuatu?<introduction-revision-sha1>..HEAD
tidak berfungsi. Ini hanya menghapus file dari komit kedua dan seterusnya. (Bagaimana cara saya memasukkan komit awal ke dalam rentang komit?) Cara simpanan ditunjukkan di sini: help.github.com/articles/…git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' \ --prune-empty --tag-name-filter cat -- --all
Mengubah kata sandi Anda adalah ide yang bagus, tetapi untuk proses menghapus kata sandi dari riwayat repo Anda, saya merekomendasikan BFG Repo-Cleaner , sebuah alternatif yang lebih cepat dan lebih sederhana untuk
git-filter-branch
secara eksplisit dirancang untuk menghapus data pribadi dari repositori Git.Membuat
private.txt
file yang mencantumkan kata sandi, dll, yang ingin Anda hapus (satu entri per baris) dan kemudian jalankan perintah ini:Semua file di bawah ukuran ambang (1MB secara default) dalam riwayat repo Anda akan dipindai, dan setiap string yang cocok (yang tidak ada dalam komit terbaru Anda ) akan diganti dengan string "*** DIHAPUS ***". Anda kemudian dapat menggunakan
git gc
untuk membersihkan data yang mati:BFG biasanya 10-50x lebih cepat daripada berjalan
git-filter-branch
dan opsinya disederhanakan dan disesuaikan dengan dua use case berikut:Pengungkapan penuh: Saya penulis Repo-Cleaner BFG.
sumber
git commit
. Jika tidak, +1 untuk alat baru di kotak alat pengembang :)These are your protected commits, and so their contents will NOT be altered
saat melintasi dan merevisi sisa riwayat komit Anda. Namun, jika Anda perlu mengembalikan, maka ya Anda harus melakukan pencarian***REMOVED***
di komit yang baru saja Anda putar.Jika Anda mendorong ke GitHub, memaksakan dorongan tidak cukup, hapus repositori atau hubungi dukungan
Bahkan jika Anda memaksa mendorong satu detik setelah itu, itu tidak cukup seperti yang dijelaskan di bawah ini.
Satu-satunya tindakan yang valid adalah:
Apakah yang dibocorkan adalah kredensial yang dapat diubah seperti kata sandi?
tidak ada (foto telanjang):
apakah Anda peduli jika semua masalah di repositori dihilangkan?
Iya:
Memaksa satu detik kemudian tidak cukup karena:
GitHub terus menggantung komitmen untuk waktu yang lama.
Staf GitHub memang memiliki kekuatan untuk menghapus komitmen menjuntai seperti itu jika Anda menghubungi mereka.
Saya mengalami tangan pertama ini ketika saya mengunggah semua GitHub melakukan surel ke repo yang mereka minta saya ambil, jadi saya lakukan, dan mereka melakukan a
gc
. Namun, permintaan tarik yang berisi data harus dihapus : bahwa data repo tetap dapat diakses hingga satu tahun setelah penghapusan awal karena hal ini.Komitmen yang menggantung dapat dilihat melalui:
Salah satu cara mudah untuk mendapatkan sumber pada komit itu adalah dengan menggunakan metode zip unduhan, yang dapat menerima referensi apa pun, misalnya: https://github.com/cirosantilli/myrepo/archive/SHA.zip
Dimungkinkan untuk mengambil SHA yang hilang baik dengan:
type": "PushEvent"
. Misalnya milik saya: https://api.github.com/users/cirosantilli/events/public ( mesin Wayback )Ada scrappers seperti http://ghtorrent.org/ dan https://www.githubarchive.org/ yang secara teratur menyatukan data GitHub dan menyimpannya di tempat lain.
Saya tidak dapat menemukan apakah mereka mengikis perbedaan komit aktual, dan itu tidak mungkin karena akan ada terlalu banyak data, tetapi secara teknis memungkinkan, dan NSA dan teman-teman kemungkinan memiliki filter untuk mengarsipkan hanya barang-barang yang terkait dengan orang atau komitmen yang menarik.
Jika Anda menghapus repositori alih-alih hanya memaksakan dorongan, komit segera menghilang bahkan dari API dan memberikan 404, misalnya https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a24 ini karya bahkan jika Anda membuat ulang repositori lain dengan nama yang sama.
Untuk menguji ini, saya telah membuat repo: https://github.com/cirosantilli/test-dangling dan lakukan:
Lihat juga: Bagaimana cara menghapus komit menggantung dari GitHub?
sumber
Saya merekomendasikan naskah ini oleh David Underhill, bekerja seperti pesona bagi saya.
Ia menambahkan perintah-perintah ini sebagai tambahan cabang-filter natacado untuk membersihkan kekacauan yang ditinggalkannya:
Skrip lengkap (semua kredit ke David Underhill)
Dua perintah terakhir mungkin berfungsi lebih baik jika diubah menjadi berikut:
sumber
git gc --aggressive --prune=now
Agar jelas: Jawaban yang diterima benar. Coba dulu. Namun, itu mungkin tidak perlu rumit untuk beberapa kasus penggunaan, terutama jika Anda menemukan kesalahan yang menjengkelkan seperti 'fatal: revisi buruk --prune-kosong', atau benar-benar tidak peduli tentang sejarah repo Anda.
Alternatifnya adalah:
Ini tentu saja akan menghapus semua cabang histori komit, dan masalah dari repo github Anda, dan repo git lokal Anda. Jika ini tidak dapat diterima, Anda harus menggunakan pendekatan alternatif.
Sebut ini opsi nuklir.
sumber
Kamu bisa menggunakan
git forget-blob
.Penggunaannya cukup sederhana
git forget-blob file-to-forget
. Anda bisa mendapatkan info lebih lanjut di sinihttps://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
Ini akan hilang dari semua komit dalam riwayat Anda, reflog, tag, dan sebagainya
Saya mengalami masalah yang sama setiap sekarang dan kemudian, dan setiap kali saya harus kembali ke posting ini dan yang lainnya, itu sebabnya saya mengotomatiskan prosesnya.
Kredit untuk kontributor dari Stack Overflow yang memungkinkan saya untuk menyatukan ini
sumber
Ini solusi saya di windows
pastikan jalurnya benar jika tidak maka tidak akan berhasil
Saya harap ini membantu
sumber
Gunakan cabang-filter :
sumber
Saya harus melakukan ini beberapa kali to-date. Perhatikan bahwa ini hanya berfungsi pada 1 file pada satu waktu.
Dapatkan daftar semua komit yang mengubah file. Yang di bawah akan melakukan komit pertama:
git log --pretty=oneline --branches -- pathToFile
Untuk menghapus file dari histori gunakan komit pertama sha1 dan path ke file dari perintah sebelumnya, dan isi mereka ke dalam perintah ini:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
sumber
Jadi, ini terlihat seperti ini:
sumber
Dalam proyek android saya, saya memiliki admob_keys.xml sebagai file xml yang terpisah di folder app / src / main / res / values / . Untuk menghapus file sensitif ini saya menggunakan skrip di bawah ini dan bekerja dengan sempurna.
sumber