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?

È stato utile?

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é:

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:

  1. cd in ramo di base del progetto
  2. Rimuovere il codice / file di sensibile
  3. rm-rf .git / # Rimuovere tutte le informazioni git da il codice
  4. Vai github e cancellare il repository
  5. 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

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

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.

  1. 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

  2. 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top