2013-02-13 14 views
9

Esiste un modo efficace per eseguire un comando di profondità ricorsivo prima git submodule foreach? Sto usando il comando foreach --recursive che esegue il lavoro, tranne che per la larghezza. Questo è un problema perché se ho la seguente struttura:sottomodulo git foreach - Un modo efficace per eseguire in modo ricorsivo il commit di un modulo figlio?

  • Un
    • B
  • C

E devo impegna in tutti e tre, una foreach --recursive add -A && git commit ... ha colpito una , B, C, che è problematico se voglio che il supermodulo acquisisca i commit di B in quel momento.

Ho trovato this discussion dal 2008, ma non sembra che nessuna delle funzioni suggerite sia nella versione corrente di Git che ho (1.7.9.5).

ho scritto una piccola funzione bash per fare questo (scusate il denominazione abbreviata):

function git-sfed() { git submodule foreach "git submodule foreach '$*' && $*"; } 

E provandola con il seguente comando fantasiosa sembra funzionare:

git-sfed 'python -c "import sys; print sys.argv" $path' 

Questo comando sembra robusto, o ci sono altri metodi comuni esistenti?

+0

Nota: alcuni comandi ora sono a conoscenza del sottomodulo: ad esempio, 'git grep -e" bar "--recurse-submodules' è disponibile con Git 2.12: http://stackoverflow.com/a/41788645/6309 – VonC

risposta

3

Non ho trovato nessun altro modo oltre alla funzione per eseguire un comando di profondità foreach.

Il test consisterebbe nel verificare se raggiunge una ricorsività per una profondità superiore a uno.

A 
    B 
    D 
    C 

Ho avuto problemi con dal sottoscritto e il mio comando quando si cerca di mettere tra virgolette singole (kinda non fa schifo essere in grado di scriverli) - fuga con più livelli di comandi bash è un po 'di confusione.

Questo (citazioni problema) Occorre semplificare in Git 1.9/2.0 (1 ° trimestre 2014), con commit 1c4fb13 da Anders Kaseorg (andersk):

'eval "[email protected]"' crea un ulteriore livello di interpretazione della shell, che probabilmente non è atteso da un utente che passa più argomenti a git foreach modulo:

$ git grep "'" 
[searches for single quotes] 
$ git submodule foreach git grep "'" 
Entering '[submodule]' 
/usr/lib/git-core/git-submodule: 1: eval: Syntax error: Unterminated quoted string 
Stopping at '[submodule]'; script returned non-zero status. 

Per risolvere questo problema, se l'utente supera più di un argomento, eseguire direttamente "[email protected]" anziché passarlo a eval.

Esempi:

  • uso tipico quando si aggiunge un ulteriore livello di citare è passare un singolo argomento che rappresenta l'intero comando da passare alla shell.
    Questo non cambia questo.
  • Si può immaginare qualcuno alimentazione input non attendibile come argomento:
git submodule foreach git grep "$variable" 

attualmente traduce in una vulnerabilità iniezione di codice shell non ovvia.
Eseguendo direttamente il comando nominato dagli argomenti, come in questa patch, lo corregge.

+0

Ho provato sia gli mb14 che le mie tecniche e sembrano funzionare entrambi. Ho pubblicato un [esempio] (http://pastebin.com/eHeYiya7) su pastebin. – eacousineau

10

Si può provare questo

git submodule foreach --recursive | tail -r | sed 's/Entering//' | xargs -I% cd % ; git add -A \& git commit 

La lista (ricorsivamente) tutti i moduli, poi invertire la lista, tail -r in modo da ottenere le directory nell'ordine in cui si desidera (primo figlio), entrare nella directory e fai ciò che vuoi in esso.

+0

Interessante, risposta più completa della mia. +1 – VonC

+0

mine dovrebbe funzionare per qualsiasi profondità – mb14

+0

Grazie per questo! Sfortunatamente, però, non avevo l'opzione '-r' (Ubuntu), ma attraverso [questo post] (http://stackoverflow.com/a/742485/170413) c'è il comando' tac'. Quindi con un diverso aroma di xargs, è nata un'altra variante: 'git submodule foreach --recursive | tac | sed 's/Inserimento //' | xargs -n 1 bash -c 'cd $ 1 && git status' _' – eacousineau

Problemi correlati