2015-04-16 7 views
8

Ho un problema con questo script bash che sto scrivendo. Sto cercando di applicare il passaggio 3 di this procedure from Github documentation per rimuovere tutti i file nella cronologia dei repository dalla cronologia git. Ad esempio, se .gitignore ignora .txt, voglio rimuovere tutto .txt dalla cronologia. E così via per ciascuna linea .gitignore.Impossibile utilizzare lo script bash per rimuovere i file dalla cronologia git

Sono in grado di utilizzare un carattere jolly nel file di esempio. Così posso eseguire la seguente per rimuovere tutti i file TXT:

git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *.txt' --prune-empty --tag-name-filter cat -- --all 

Così ho provato a fare uno script bash per fare lo stesso.

Ho fatto un semplice file .gitignore di testare questo con, come segue:

#foo 
*.txt 
*.docx 

mio script di shell è simile al seguente:

#!/bin/bash 

s1="#" 
str1="'git rm --cached --ignore-unmatch " 
str2="'" 

cat .gitignore | while read line 
do 
    if [[ $line == *"$s1"* ]] 
    then 
     echo #skip 
    else 
     str3=$str1$line$str2 
     git filter-branch --force --index-filter $str3 --prune-empty --tag-name-filter cat -- --all 
    fi 
done 

Tuttavia, questo risultato è la seguente output:

fatal: bad revision 'rm' 
fatal: bad revision 'rm' 

(una volta per ogni riga del file .gitignore)

0.123.

Cosa ho fatto di sbagliato?

+0

Cita le tue variabili! – Biffen

+1

Non è possibile inserire comandi complessi in una stringa. Non provarci http://mywiki.wooledge.org/BashFAQ/050 Soprattutto non è possibile ottenere preventivi per funzionare correttamente. –

+0

Il comando che sto usando ha citazioni singole in esso. Quando ho appena provato a eseguire il comando e ad aggiungere $ line, il comando risultante in esecuzione includeva 'git rm --cached --ignore unmatch $ line' invece di contenere il contenuto di $ line. – Jake

risposta

7

Credo che questo potrebbe fare ciò che vuoi.

#!/bin/bash 

cat .gitignore | while read line 
do 
    if [[ $line == *#* ]] 
    then 
     echo #skip 
    else 
     git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch '"$line" --prune-empty --tag-name-filter cat -- --all 
    fi 
done 

Ho evitato tutte le variabili intermedie inutili che hanno solo complicato le cose. (Anche se solo rimuovendo la singola citazione da str1 e far cadere str2 avrebbe potuto essere sufficiente questo è più sano per quanto mi riguarda.)

il filtro deve solo essere una singola stringa, ma come si costruisce la stringa verrà fino a tu.

Probabilmente è anche possibile raccogliere tutti i modelli da gitignore e basta eseguire il filtro ramo una volta (e non è necessario --force a quel punto).

#!/bin/bash 

patts=() 
while read -r line 
do 
    if [[ $line != *#* ]]; then 
     patts+=("$line") 
    fi 
done < .gitignore 

git filter-branch --index-filter 'git rm --cached --ignore-unmatch '"${patts[*]}" --prune-empty --tag-name-filter cat -- --all 

Si noti inoltre che probabilmente si dovrebbe essere sicuri che si sta solo a che fare con semplici disegni qui perché il rm e .gitignore comprensione dei modelli non è proprio la stessa in tutti i casi non credo.

+0

Ha funzionato! Grazie mille. Accetterò la risposta il prima possibile. – Jake

+0

Grazie ancora. Ho iniziato a scrivere senza le variabili stringa extra, ma non avendo usato molto lo scripting di bash, ero confuso su come ottenere $ line dove avevo bisogno. Questa soluzione è stata molto più semplice e utile. – Jake

Problemi correlati