Questo è il comando git-filter-branch che può essere eseguito nel provider di hosting gratuito OnWorks utilizzando una delle nostre molteplici workstation online gratuite come Ubuntu Online, Fedora Online, emulatore online Windows o emulatore online MAC OS
PROGRAMMA:
NOME
git-filter-branch - Riscrive i rami
SINOSSI
git ramo-filtro [--env-filtro ] [--filtro-albero ]
[--filtro-indice ] [--filtro-genitore ]
[--filtro-msg ] [--commit-filtro ]
[--filtro-nome-tag ] [--filtro-sottodirectory ]
[--prune-vuoto]
[--originale ] [-D ] [-f | --forza]
[--] [ ...]
DESCRIZIONE
Ti consente di riscrivere la cronologia delle revisioni di Git riscrivendo i rami menzionati in
opzioni>, applicando filtri personalizzati su ogni revisione. Questi filtri possono modificare ogni albero
(ad es. rimozione di un file o esecuzione di una riscrittura perl su tutti i file) o informazioni su ciascuno
commettere. In caso contrario, tutte le informazioni (inclusi i tempi di commit originali o le informazioni di unione)
sarà preservato.
Il comando riscriverà solo il positivo riferimenti menzionati nella riga di comando (ad es. se tu
passare a.b, solo b verrà riscritto). Se non specifichi alcun filtro, i commit saranno
reimpegnato senza alcuna modifica, che normalmente non avrebbe alcun effetto. Tuttavia, questo
potrebbe essere utile in futuro per compensare alcuni bug di Git o simili, quindi tale
l'uso è consentito.
NOTA: questo comando rispetta il file .git/info/grafts e i refs nello spazio dei nomi refs/replace/.
Se hai innesti o riferimenti di sostituzione definiti, l'esecuzione di questo comando li farà
permanente.
AVVERTIMENTO! La cronologia riscritta avrà nomi di oggetti diversi per tutti gli oggetti e
non convergerà con il ramo originale. Non sarai in grado di spingere facilmente e
distribuire il ramo riscritto sopra il ramo originale. Si prega di non utilizzare questo
comando se non conosci tutte le implicazioni ed evita di usarlo comunque, se semplice
un singolo commit sarebbe sufficiente per risolvere il tuo problema. (Vedi il "RECUPERO DA MONTE
REBASE" in git-rebase(1) per ulteriori informazioni sulla riscrittura pubblicata
storia.)
Verificare sempre che la versione riscritta sia corretta: i riferimenti originali, se diversi da
quelli riscritti, verranno memorizzati nel namespace rif/originale/.
Nota che poiché questa operazione è molto costosa in termini di I/O, potrebbe essere una buona idea reindirizzare
la directory temporanea fuori disco con il -d opzione, ad esempio su tmpfs. Secondo quanto riferito l'accelerazione
è molto evidente.
Filtri
I filtri vengono applicati nell'ordine elencato di seguito. Il l'argomento è sempre
valutata nel contesto della shell usando il eval comando (con la notevole eccezione del
filtro commit, per motivi tecnici). Prima di ciò, la variabile d'ambiente $GIT_COMMIT
sarà impostato per contenere l'id del commit da riscrivere. Inoltre, GIT_AUTHOR_NAME,
GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL e
GIT_COMMITTER_DATE sono presi dal commit corrente ed esportati nell'ambiente, in
per influenzare le identità dell'autore e del committente del commit sostitutivo creato da
git-commit-albero(1) dopo che i filtri hanno funzionato.
Se qualsiasi valutazione di restituisce uno stato di uscita diverso da zero, l'intera operazione sarà
abortito.
A carta geografica è disponibile una funzione che accetta un argomento "ID sha1 originale" e restituisce a
"riscritto sha1 id" se il commit è già stato riscritto e "originale sha1 id"
altrimenti; il carta geografica la funzione può restituire diversi ID su righe separate se il filtro di commit
emesso più commit.
VERSIONI
--env-filtro
Questo filtro può essere utilizzato se hai solo bisogno di modificare l'ambiente in cui il commit
sarà eseguita. In particolare, potresti voler riscrivere l'autore/committente
nome/e-mail/ora variabili d'ambiente (vedi git-commit-albero(1) per i dettagli). Non
dimentica di riesportare le variabili.
--filtro-albero
Questo è il filtro per riscrivere l'albero e il suo contenuto. L'argomento viene valutato
in shell con la directory di lavoro impostata sulla radice dell'albero estratto. Il nuovo
l'albero viene quindi utilizzato così com'è (i nuovi file vengono aggiunti automaticamente, i file scomparsi vengono rimossi automaticamente
- né file .gitignore né altre regole di ignoranza AVERE QUALSIASI EFFETTO!).
--filtro-indice
Questo è il filtro per riscrivere l'indice. È simile al filtro ad albero ma lo fa
non controllare l'albero, il che lo rende molto più veloce. Usato frequentemente con git rm
--cached --ignore-unmatch ..., vedi ESEMPI sotto. Per i casi pelosi, vedere git-aggiornamento-
Index(1).
--filtro-genitore
Questo è il filtro per riscrivere l'elenco padre del commit. Riceverà il genitore
string su stdin e restituirà la nuova stringa padre su stdout. La stringa padre è
nel formato descritto in git-commit-albero(1): vuoto per il commit iniziale, "-p
parent" per un commit normale e "-p parent1 -p parent2 -p parent3 ..." per un merge
commettere.
--filtro-msg
Questo è il filtro per riscrivere i messaggi di commit. L'argomento viene valutato nel
shell con il messaggio di commit originale sullo standard input; viene utilizzato il suo output standard
come nuovo messaggio di commit.
--commit-filtro
Questo è il filtro per eseguire il commit. Se questo filtro è specificato, sarà
chiamato invece di git albero di commit comando, con argomenti della forma "
[(-P )...]" e il messaggio di registro su stdin. L'ID commit è previsto
su stdout.
Come estensione speciale, il filtro di commit può emettere più ID di commit; in quel caso,
i figli riscritti del commit originale li avranno tutti come genitori.
È possibile utilizzare il carta geografica funzione di convenienza in questo filtro e altre comodità
funzioni, anche. Ad esempio, chiamando skip_commit "$@" lascerò fuori la corrente
commit (ma non le sue modifiche! Se lo desideri, usa git rebase Invece).
Puoi anche usare git_commit_non_empty_tree "$@" invece di git commit-tree "$@" se
non desideri mantenere impegni con un genitore single e questo non modifica il
albero.
--filtro-nome-tag
Questo è il filtro per riscrivere i nomi dei tag. Una volta superato, verrà chiamato per ogni
tag ref che punta a un oggetto riscritto (o a un tag oggetto che punta a a
oggetto riscritto). Il nome del tag originale viene passato tramite l'input standard e il nuovo tag
nome è previsto sullo standard output.
I tag originali non vengono cancellati, ma possono essere sovrascritti; usa "--tag-name-filter cat"
per aggiornare semplicemente i tag. In questo caso, fai molta attenzione e assicurati di avere il
backup dei vecchi tag nel caso in cui la conversione abbia avuto esito negativo.
È supportata la riscrittura quasi corretta degli oggetti tag. Se il tag ha un messaggio
allegato, verrà creato un nuovo oggetto tag con lo stesso messaggio, autore e
marca temporale. Se il tag ha una firma allegata, la firma verrà rimossa. è
per definizione impossibile conservare le firme. La ragione per cui questo è "quasi" corretto,
è perché idealmente se il tag non è cambiato (punta allo stesso oggetto, ha lo stesso
nome, ecc.) dovrebbe conservare qualsiasi firma. Non è così, le firme lo faranno
sempre essere rimosso, acquirente attenzione. Non c'è nemmeno il supporto per cambiare l'autore o
timestamp (o il messaggio tag per quella materia). I tag che puntano ad altri tag saranno
riscritto per puntare al commit sottostante.
--filtro-sottodirectory
Guarda solo la cronologia che tocca la sottodirectory data. Il risultato conterrà
quella directory (e solo quella) come radice del progetto. Implica la sezione chiamata "Rimappa
all'antenato”.
--prune-vuoto
Alcuni tipi di filtri genereranno commit vuoti, che hanno lasciato intatto l'albero. Questo
switch consente a git-filter-branch di ignorare tali commit. Tuttavia, solo questo interruttore
si applica ai commit che hanno uno e un solo genitore, quindi manterrà le unioni
punti. Inoltre, questa opzione non è compatibile con l'uso di --commit-filtro. Anche se
devi solo usare la funzione git_commit_non_empty_tree "$@" invece del git
commit-tree "$@" nel tuo filtro di commit per farlo accadere.
--originale
Utilizzare questa opzione per impostare lo spazio dei nomi in cui verranno archiviati i commit originali. Il
il valore predefinito è refs/originale.
-D
Utilizzare questa opzione per impostare il percorso della directory temporanea utilizzata per la riscrittura. quando
applicando un filtro ad albero, il comando deve controllare temporaneamente l'albero ad alcuni
directory, che può consumare molto spazio in caso di progetti di grandi dimensioni. Per impostazione predefinita
lo fa nel .git-riscrivi/ directory ma puoi sovrascrivere quella scelta con questo
parametro.
-f, --forza
git ramo-filtro si rifiuta di iniziare con una directory temporanea esistente o quando c'è
sono già arbitri che iniziano con rif/originale/, a meno che non sia forzato.
...
Argomenti per git rev-lista. Tutti i riferimenti positivi inclusi da queste opzioni vengono riscritti.
Puoi anche specificare opzioni come --tutti, ma devi usare -- separarli da
, il git ramo-filtro opzioni. Implica la sezione chiamata "Rimappa all'antenato".
Remap a antenato
Utilizzando rev-lista(1) argomenti, ad esempio limitatori di percorso, è possibile limitare l'insieme delle revisioni
che vengono riscritti. Tuttavia, si distinguono i riferimenti positivi sulla riga di comando: we
non lasciarli esclusi da tali limitatori. A tal fine, vengono invece riscritti
per indicare l'antenato più vicino che non era escluso.
ESEMPI
Supponiamo di voler rimuovere un file (contenente informazioni riservate o copyright
violazione) da tutti commette:
git filter-branch --tree-filter 'rm filename' HEAD
Tuttavia, se il file è assente dall'albero di qualche commit, un semplice nome file rm lo farà
fallire per quell'albero e impegnarsi. Quindi potresti invece voler usare rm -f nomefile come
script.
Usando --index-filter con git rm produce una versione significativamente più veloce. Come con l'uso di rm
filename, git rm --cached filename fallirà se il file è assente dall'albero di a
commettere. Se vuoi "dimenticare completamente" un file, non importa quando è stato inserito
history, quindi aggiungiamo anche --ignore-unmatch:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
Ora otterrai la cronologia riscritta salvata in HEAD.
Per riscrivere il repository in modo che sembri che foodir/ fosse stata la radice del suo progetto e scartare tutto
altra storia:
git filter-branch --subdirectory-filter foodir -- --all
In questo modo è possibile, ad esempio, trasformare una sottodirectory di una libreria in un proprio repository. Notare la --
che separa ramo-filtro opzioni dalle opzioni di revisione e --all per riscrivere tutto
rami e tag.
Per impostare un commit (che in genere è all'inizio di un'altra cronologia) come genitore del
commit iniziale corrente, per incollare l'altra cronologia dietro la cronologia corrente:
git filter-branch --parent-filter 'sed "s/^\$/-p /"' TESTA
(se la stringa genitore è vuota, cosa che accade quando abbiamo a che fare con il commit iniziale
- aggiungi graftcommit come genitore). Nota che questo presuppone la storia con una singola radice (che
cioè, nessuna fusione senza antenati comuni è avvenuta). In caso contrario, utilizzare:
git filter-branch --filtro-genitore \
'prova $GIT_COMMIT = && echo "-p " || testa di gatto
o ancora più semplice:
echo "$commit-id $graft-id" >> .git/info/grafts
git filter-ramo $graft-id..HEAD
Per rimuovere i commit creati da "Darl McBribe" dalla cronologia:
git filter-branch --commit-filter '
if [ "$GIT_AUTHOR_NAME" = "Tesoro McBribe" ];
poi
skip_commit "$@";
altro
git commit-tree "$@";
fi' TESTA
La funzione skip_commit è definito come segue:
salta_commit()
{
cambio;
while [ -n "$1" ];
do
cambio;
mappa "$ 1";
cambio;
fatto;
}
La magia dello spostamento prima elimina l'id dell'albero e poi i parametri -p. Nota che questo
gestisce correttamente le fusioni! Nel caso in cui Darl abbia commesso una fusione tra P1 e P2, sarà
propagato correttamente e tutti i figli dell'unione diventeranno commit di unione con P1,P2 come
i loro genitori invece del commit di unione.
NOTA le modifiche introdotte dai commit, e che non sono ripristinate da successive
commits, sarà ancora nel ramo riscritto. Se vuoi buttare via i cambiamenti insieme
con i commit, dovresti usare la modalità interattiva di git rebase.
Puoi riscrivere i messaggi di log di commit usando --msg-filter. Per esempio, git svn-id
stringhe in un repository creato da git svn può essere rimosso in questo modo:
git filter-branch --msg-filter '
sed -e "/^git-svn-id:/d"
'
Se devi aggiungere Confermato da righe per, diciamo, gli ultimi 10 commit (nessuno dei quali è un'unione),
usa questo comando:
git filter-branch --msg-filter '
gatto &&
echo "Acked-by: Bugs Bunny[email protected]>"
'TESTA~10..TESTA
L'opzione --env-filter può essere utilizzata per modificare l'identità del committente e/o dell'autore. Per
esempio, se scoprissi che i tuoi commit hanno l'identità sbagliata a causa di una configurazione errata
user.email, puoi apportare una correzione, prima di pubblicare il progetto, in questo modo:
git filter-branch --env-filter '
if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
poi
GIT_AUTHOR_EMAIL=[email protected]
esporta GIT_AUTHOR_EMAIL
fi
if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
poi
GIT_COMMITTER_EMAIL=[email protected]
esporta GIT_COMMITTER_EMAIL
fi
' -- --Tutti
Per limitare la riscrittura solo a una parte della cronologia, specificare un intervallo di revisione oltre a
il nuovo nome della filiale. Il nuovo nome del ramo punterà alla revisione più in alto che a git
rev-lista di questo intervallo verrà stampato.
Considera questa storia:
RE--MI--FA--SOL--LA
/ /
LA--SI-----DO
Per riscrivere solo commit D, E, F, G, H, ma lascia soli A, B e C, usa:
git filtro-ramo ... C..H
Per riscrivere i commit E,F,G,H, usa uno di questi:
git filtro-ramo ... C..H --non D
git filtro-ramo ... D..H --non C
Per spostare l'intero albero in una sottodirectory o rimuoverlo da lì:
git filter-branch --index-filter \
'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.nuovo \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
LISTA DI CONTROLLO PER RIMUOVERE A REPOSITORY
git-filter-branch può essere usato per sbarazzarsi di un sottoinsieme di file, di solito con alcuni
combinazione di --index-filter e --subdirectory-filter. La gente si aspetta il risultato
repository per essere più piccolo dell'originale, ma sono necessari alcuni passaggi in più per renderlo effettivamente
è più piccolo, perché Git si sforza di non perdere i tuoi oggetti finché non glielo dici tu. Primo
assicurati che:
· Hai davvero rimosso tutte le varianti di un nome file, se un blob è stato spostato nel corso della sua vita.
git log --name-only --follow --all -- filename può aiutarti a trovare i rinomina.
· Hai davvero filtrato tutti i riferimenti: usa --tag-name-filter cat -- --all quando chiami
git-filtro-ramo.
Quindi ci sono due modi per ottenere un repository più piccolo. Un modo più sicuro è clonare, che mantiene
il tuo originale intatto.
· Clonalo con git clone file:///path/to/repo. Il clone non avrà il rimosso
oggetti. Vedere git-clone(1). (Nota che la clonazione con un percorso semplice è solo hardlink
Tutto quanto!)
Se davvero non vuoi clonarlo, per qualsiasi motivo, controlla i seguenti punti
invece (in questo ordine). Questo è un approccio molto distruttivo, quindi make a di riserva o torna indietro
per clonarlo. Sei stato avvertito.
· Rimuovi i riferimenti originali supportati da git-filter-branch: dì git for-each-ref
--format="%(refname)" refs/originale/ | xargs -n 1 git update-ref -d.
· Scade tutti i reflog con git reflog scade --expire=now --all.
· Garbage collect tutti gli oggetti senza riferimenti con git gc --prune=now (o se il tuo git-gc è
non abbastanza nuovo da supportare argomenti per --prune, usa git repack -ad; git prune
Invece).
NOTE
git-filter-branch ti consente di eseguire complesse riscritture con script di shell della cronologia di Git,
ma probabilmente non hai bisogno di questa flessibilità se sei semplicemente rimozione non desiderato dati piace
file di grandi dimensioni o password. Per quelle operazioni che potresti voler prendere in considerazione Il Marketplace per le BFG
Repo-Cleaner[1], un'alternativa basata su JVM a git-filter-branch, in genere almeno 10-50x
più veloce per quei casi d'uso e con caratteristiche abbastanza diverse:
· Qualsiasi versione particolare di un file viene pulita esattamente una volta. Il GGG, a differenza di
git-filter-branch, non ti dà l'opportunità di gestire un file in modo diverso
in base a dove o quando è stato commesso nella tua storia. Questo vincolo dà il
vantaggio delle prestazioni principali del GGG, ed è adatto al compito di pulire i cattivi
dati - non ti interessa where i dati errati sono, lo vuoi solo andato.
· Per impostazione predefinita, il GGG sfrutta appieno le macchine multi-core, pulizia del commit
alberi di file in parallelo. git-filter-branch pulisce i commit in modo sequenziale (cioè in a
modo a filettatura singola), sebbene sia is possibile scrivere filtri che includano i propri
parallelismo, negli script eseguiti contro ogni commit.
· Il command Opzioni[2] sono molto più restrittivi del ramo git-filter e dedicati
solo per rimuovere i dati indesiderati, ad esempio: --strip-blobs-bigger-than 1M.
GIT
Parte della git(1) seguito
NOTE
1. Il BFG Repo-Cleaner
http://rtyley.github.io/bfg-repo-cleaner/
2. opzioni di comando
http://rtyley.github.io/bfg-repo-cleaner/#esempi
Usa git-filter-branch online usando i servizi onworks.net