Rimuovere i file sensibili e la loro storia di Git commit dal
-
22-08-2019 - |
Domanda
Vorrei mettere un Git del progetto su GitHub, ma contiene alcuni file con dati sensibili (nomi utente e password, come /config/deploy.rb per capistrano).
So che posso aggiungere i nomi .gitignore, ma questo non sarebbe rimuovere la loro storia all'interno di Git.
Anche io non voglio ricominciare tutto da capo, cancellando /.git directory.
C'è un modo per rimuovere tutti tracce di un particolare file nella vostra storia di Git?
Soluzione
Per tutti gli scopi pratici, il prima cosa che si dovrebbe essere preoccupati è cambiare la vostra password! Non è chiaro dalla tua domanda se il repository git è interamente locale o se si dispone di un repository remoto ma altrove; se è a distanza e non protetto dagli altri di avere un problema. Se qualcuno ha clonato quel repository prima di risolvere questo problema, avranno una copia delle password sulla propria macchina locale, e non c'è nessun modo si può costringerli ad aggiornare alla versione "fissa" con essa scomparso dalla storia. L'unica cosa sicura che puoi fare è cambiare la password per qualcosa d'altro in tutto il mondo che lo avete usato.
Con quella di mezzo, ecco come risolvere il problema. risponde esattamente a questa domanda come un FAQ :
Nota per gli utenti Windows : utilizzare le virgolette ( ") invece di single in questo comando
git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force
Tenete a mente che se avete già trasmesso questo codice per un repository remoto come GitHub e altri hanno clonato che repository remoto, siete ora in una situazione in cui si sta riscrivendo la storia. Quando gli altri cercano tirare giù le ultime modifiche dopo questo, si otterrà un messaggio che indica che le le modifiche non possono essere applicate perché non è un fast-forward.
Per risolvere questo problema, avranno a uno eliminare il loro repository esistenti e ri-clone di esso, o seguire le istruzioni in "Ripristino da monte REBASE" nel git-rebase pagina man .
In futuro, se si impegnano accidentalmente alcuni cambiamenti con informazioni sensibili, ma si nota prima a spingere per un repository remoto, ci sono alcune correzioni più facili. Se lo scorso commettere è quello di aggiungere le informazioni sensibili, si può semplicemente rimuovere le informazioni sensibili, quindi eseguire:
git commit -a --amend
Che modificare il commit precedente con le nuove modifiche apportate, tra cui intere rimozioni di file fatto con un git rm
. Se le modifiche sono più indietro nella storia, ma ancora non hanno spinto ad un repository remoto, si può fare un rebase interattivo:
git rebase -i origin/master
Che apre un editor con i commit apportate dal tuo ultimo antenato comune con il repository remoto. Change "pick" a "modifica" su tutte le linee che rappresentano un commit con informazioni sensibili, e salvare e uscire. Git camminerà attraverso i cambiamenti, e ti lasciano in un punto in cui è possibile:
$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
Per ogni modifica con le informazioni sensibili. Alla fine, vi ritroverete di nuovo sul ramo, e si può spingere in modo sicuro le nuove modifiche.
Altri suggerimenti
Cambia la tua password è una buona idea, ma per il processo di rimozione password dal tuo repo storia, vi consiglio il BFG Repo-Cleaner, un sistema più veloce, semplice alternativa a git-filter-branch
espressamente progettato per la rimozione di dati privati da Git repository.
Creare un private.txt
elenco dei file, le password, ecc, che si desidera rimuovere (una voce per riga) e quindi eseguire il comando:
$ java -jar bfg.jar --replace-text private.txt my-repo.git
Tutti i file al di sotto di una soglia dimensioni (1MB per impostazione predefinita) nella vostra repo storia sarà acquisita, e qualsiasi stringa corrispondente (che non è nella tua ultima commit) sarà sostituito con la stringa "***RIMOSSO***".È quindi possibile utilizzare git gc
per pulire via i morti, i dati:
$ git gc --prune=now --aggressive
Il BFG è in genere 10-50 volte più veloci rispetto al git-filter-branch
e le opzioni sono state semplificate e personalizzate, intorno a questi due comuni casi d'uso:
- Rimozione Pazzo Di File Di Grandi Dimensioni
- Rimozione Password, Credenziali e altri Dati privati
Full disclosure:Io sono l'autore della BFG Repo-Cleaner.
questo script da David Underhill, ha lavorato come un fascino per me.
Si aggiunge questi comandi a filtro-ramo aggiunta di natacado per ripulire il pasticcio si lascia dietro:
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
script completo (tutto il credito a David Underhill)
#!/bin/bash
set -o errexit
# Author: David Underhill
# Script to permanently delete files/folders from your git repository. To use
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2
if [ $# -eq 0 ]; then
exit 0
fi
# make sure we're at the root of git repo
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi
# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter \
"git rm -rf --cached --ignore-unmatch $files" HEAD
# remove the temporary history git-filter-branch
# otherwise leaves behind for a long time
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune
Gli ultimi due comandi possono funzionare meglio se è cambiata la seguente:
git reflog expire --expire=now --all && \
git gc --aggressive --prune=now
Se ti ha spinto a GitHub, forza di spinta non è sufficiente, eliminare il supporto repository o contatto
Anche se si forza spingere uno secondo dopo, non è sufficiente, come spiegato di seguito.
I corsi solo validi di azione sono:
-
è ciò che trapelata una credenziale mutevole come una password?
- sì: modificare le password immediatamente, e considerare l'utilizzo di più OAuth e API chiavi !
-
no (nudi foto):
-
Ti importa se tutti i problemi nel repository vengono nuked?
- no: eliminare il repository
-
Si
- Supporto contatto
- se la perdita è molto critica a voi, al punto che si è disposti a prendere un po 'i tempi di inattività repository per renderlo meno probabilità di perdere, renderlo privato mentre si attende per il supporto GitHub per rispondere a te
-
forza di spinta un secondo più tardi, non è sufficiente perché:
-
GitHub mantiene penzoloni si impegna per un lungo periodo.
personale GitHub ha il potere di cancellare tali penzoloni impegna se si contatta loro però.
ho sperimentato in prima persona quando ho caricato tutto GitHub commettere messaggi di posta elettronica ad un repo mi hanno chiesto di prendere in giù, così ho fatto, e hanno fatto un
gc
. Tirare le richieste che contengono i dati devono essere cancellati comunque : che i dati di pronti contro termine sono rimasti accessibili fino a un anno dopo la rimozione iniziale a causa di questo.commit ciondolanti può essere visto sia attraverso:
- utente web commettere: https://github.com/cirosantilli/test- penzoloni / commit / 53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( Wayback machine )
- l'API: https://api.github.com/ repos / cirosantilli / test-penzoloni / impegna / 53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( Wayback machine )
Un modo conveniente per ottenere la fonte in quel impegnano quindi è quello di utilizzare il metodo di download zip, che può accettare alcun riferimento, ad esempio: https://github.com/cirosantilli/myrepo/archive/SHA.zip
-
E 'possibile prendere la SHAs mancanti o:
- messa in vendita di eventi API con
type": "PushEvent"
. Per esempio. il mio: https://api.github.com/users/cirosantilli/events/public ( Wayback ) - più comodamente a volte, guardando i SHAs di richieste di trazione che hanno tentato di rimuovere il contenuto
- messa in vendita di eventi API con
-
Ci sono scrappers come http://ghtorrent.org/ e https://www.githubarchive.org/ quella piscina regolarmente i dati GitHub e memorizzarloaltrove.
Non ho potuto trovare se raschiano l'attuale commit diff, e che è improbabile perché non ci sarebbe troppi dati, ma è tecnicamente possibile, e la NSA e gli amici probabilmente filtri per archiviare solo roba legata a persone o impegna di interesse.
Se si elimina il repository invece di forza di spinta però, commette scompaiono anche dalle API immediatamente e dare 404, ad esempio, https://api.github.com/repos/cirosantilli/ test-penzoloni-delete / impegna / 8c08448b5fbf0f891696819f3b2b2d653f7a3824 questo funziona anche se si ricrea un altro repository con lo stesso nome.
Per testare il tutto, ho creato un repo: https://github.com/cirosantilli/ test-penzoloni e ha fatto:
git init
git remote add origin git@github.com:cirosantilli/test-dangling.git
touch a
git add .
git commit -m 0
git push
touch b
git add .
git commit -m 1
git push
touch c
git rm b
git add .
git commit --amend --no-edit
git push -f
Si veda anche: Come rimuovere un penzoloni commettere da GitHub?
Per essere chiari: la risposta accettata è corretta. Provare per primo. Tuttavia, può essere inutilmente complessa per alcuni casi di utilizzo, in particolare se si verificano errori fastidiosi come 'fatale: revisione guasta --prune-vuoto'., O realmente non si preoccupano la storia della vostra repo
Un'alternativa potrebbe essere:
- cd in ramo di base del progetto
- Rimuovere il codice / file di sensibile
- rm-rf .git / # Rimuovere tutte le informazioni git da il codice
- Vai github e cancellare il repository
- Segui questa guida per spingere il codice per un nuovo repository come si farebbe normalmente - https://help.github.com/articles / l'aggiunta di-un-esistente-project-to-github-con-la-riga di comando /
Questa sarà ovviamente rimuovere tutti commettono storia filiali, e le questioni sia dal repo github, e il vostro repo git locale. Se questo è inaccettabile si dovrà utilizzare un approccio alternativo.
Chiamare questo l'opzione nucleare.
Ecco la mia soluzione in windows
git filtro-filiale --albero-filtro "rm -f 'filedir/filename'" TESTA
git push --force
assicurarsi che il percorso sia corretto altrimenti non funzionerà
Spero che aiuta
Usa Filtro-ramo :
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*' --prune-empty --tag-name-filter cat -- --all
git push origin *branch_name* -f
È possibile utilizzare git forget-blob
.
L'utilizzo è piuttosto semplice git forget-blob file-to-forget
. È possibile ottenere ulteriori informazioni qui
E 'scomparirà da tutti i commit nella vostra storia, reflog, tag e così via
I funzionare nello stesso problema di tanto in tanto, e ogni volta devo tornare a questo post e gli altri, è per questo che ho automatizzato il processo.
I crediti verso contributori da overflow dello stack che mi ha permesso di mettere questo insieme |
Ho dovuto fare questo un paio di volte aggiornato. Si noti che questo funziona solo su 1 file alla volta.
-
Ottenere un elenco di tutti i commit che ha modificato un file. Quello in basso sarà il primo commit:
git log --pretty=oneline --branches -- pathToFile
-
Per rimuovere il file dalla storia usare il primo commit SHA1 e il percorso del file dal comando precedente, e riempirli in questo comando:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
Quindi, sembra qualcosa di simile a questo:
git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
Rimuovere la cache per tracciati file da git e aggiungere il file
.gitignore
elenco
Nel mio progetto Android avevo admob_keys.xml , come file XML separato in / valori cartella app / src / main / res /. Per rimuovere questo file sensibili che ho usato qui di seguito sceneggiatura e ha funzionato perfettamente.
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch app/src/main/res/values/admob_keys.xml' \
--prune-empty --tag-name-filter cat -- --all