Utilizzando git sottostruttura fusione, mentre anche la fusione in tutti i rami di tutte le sottostrutture fuse

StackOverflow https://stackoverflow.com/questions/2137950

  •  22-09-2019
  •  | 
  •  

Domanda

Mi piacerebbe usare un popolare, open source issue tracker (Redmine), che offre l'integrazione git. Purtroppo, ogni progetto nel tracker può essere associato solo con un repo git. La creazione di più progetti in inseguitore non è la mia messa a punto ideale.

Con questo in mente, ho tentato di usare git sottostruttura fusione (spiegato qui , e qui ). Ho creato un pronti contro termine "ombrello" che si è fusa in ciascuno dei numerosi altri pronti contro termine che sto lavorando.

Purtroppo, gli esempi forniti tirare solo nel ramo principale di ogni sotto-albero. Dal momento che ho di sviluppo in corso in molteplici rami di ciascuna sottostruttura, ho bisogno di imparare ad avere questo ombrello repo riflettono ogni ramo di ogni sotto-albero.

È possibile?

Credit Extra:? E se 2 sottostrutture hanno ciascuna un ramo con lo stesso nome

È stato utile?

Soluzione

Per quelli di noi che non hanno familiarità con Redmine, si prega di estendere la vostra descrizione per includere le risposte alle seguenti domande: Che tipo di accesso nel repository fa la necessità inseguitore? Sarà necessario fare i propri commit? O, lo fa solo bisogno di certi tipi di accesso in lettura (forse per convalidare impegnarsi hash ed eseguire la scansione commettere i registri per le parole chiave)?

Se il vostro inseguitore ha bisogno solo l'accesso in lettura, potrebbe non essere necessario qualsiasi sottostruttura fusione a tutti. È perfettamente accettabile avere più commit iniziale (consentendo multipli, storie indipendenti) in un unico repository. Il progetto Git si fa questo per alcuni 'extra' ( man , HTML , todo ) che condividono nessuna storia (commit) con, ma sono pubblicato a fianco il gruppo principale di rami per il codice sorgente ( maint , Master , Avanti , pu ). Per la vostra fine, esso può essere sufficiente per l'installazione di un telecomando per ogni sotto-archivio a prendere le loro punte ramo nel repository aggregazione. Forse basterebbero le automatiche ‘rami di monitoraggio a distanza’, o forse avete bisogno di prendere il passo in più per creare (e aggiornare) filiali locali sulla base dei rami di monitoraggio remoto.

Lo schema sotto-albero fusione che descrivi non è probabilmente significativo della situazione generale in cui i rami nei repository di origine non sono correlati o solo semi-related. Ma, se tutti i repository di origine condividono un insieme di rami in cui ogni ramo ha un determinato scopo che è la stessa in tutti i repository, si potrebbe probabilmente significato unirle in una specie di super-repository.

Ma la questione interessante non è “che cosa succede se due repository hanno filiali con lo stesso nome?”, Ma “come si fa a gestire il caso in cui un repository manca un ramo dal comune, 'globale' set?”.

Se tutti i sub-repository hanno lo stesso insieme di rami, basta fare quello che hai fatto con Master , ma una volta per ogni ramo. Il problema nasce quando un ramo particolare manca un repository. Si potrebbe sostituire la sua Master , ma che potrebbe non essere sempre la risposta giusta. Dipende perché si stanno aggregando il repository insieme, in primo luogo e che cosa ci si aspetta di ‘vedere’ in quel sottoalbero di quel ramo nel super-repository.

Se i sub-repository sono non strettamente correlati, poi ho davvero i miei dubbi circa la ragionevolezza di questo approccio sotto-albero. Un tale approccio per i repository estranei si sente come sarebbe ‘andare contro il grano’. Probabilmente è ancora possibile, ma dubito ci sia qualsiasi strumento per aiutare, e sarà necessario passare un po 'di tempo pianificazione fuori i casi d'angolo.

Se si finisce attaccare con sottostruttura si fonde, si potrebbe guardare al di terze parti comando git subtree . Potrebbe aiutare a mantenere i vostri miriade di repository sincronizzate.


Filiali Raccolta, senza confondersi

Se Redmine specifica --mirror clone, l'implicazione è che si aspetta sezioni locali e non può essere in grado di leggere direttamente i ‘rami di monitoraggio a distanza’, quindi sarà probabilmente bisogno di creare e aggiornare alcune sedi locali.

Filiali locali aggiornati da ‘rami di monitoraggio remoto’
  • Impostazioni iniziali

    mkdir $COLLECTION_REPO && cd $COLLECTION_REPO &&
    git init
    git remote add alpha <url/path-to-alpha-repo>
    git remote add bravo <url/path-to-bravo-repo>
    git remote add charlie <url/path-to-charlie-repo>
    for r in $(git remote); do
        git config --add remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.heads.tags.;s.remotes.tags/all.')"
        git config remote.$r.tagopt --no-tags
    done
    
  • Periodico aggiornamento

    git remote update
    git for-each-ref --shell --format \
      'git branch --force --track -l all/%(refname:short) %(refname:short)' refs/remotes \
      | sh
    
Filiali locali che ricevere direttamente Consigli Branch inverosimile
  • Impostazioni iniziali

    mkdir $COLLECTION_REPO && cd $COLLECTION_REPO &&
    git init
    git remote add alpha <url/path-to-alpha-repo>
    git remote add bravo <url/path-to-bravo-repo>
    git remote add charlie <url/path-to-charlie-repo>
    for r in $(git remote); do
        git config remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.remotes.heads/all.')"
        git config --add remote.$r.fetch \
          "$(git config remote.$r.fetch | sed -e 's.heads.tags.g')"
        git config remote.$r.tagopt --no-tags
    done
    
  • Periodico aggiornamento

    git remote update
    

Entrambi i metodi finire raccogliere rami sotto refs/heads/all/<remote-name>/<branch-name-on-remote>, ma la prima ha anche un duplicato di arbitri sotto refs/remotes/<remote-name>/<branch-name-on-remote>. Il primo utilizza un normale fetch refspec e utilizza git branch di duplicare i ‘rami di monitoraggio a distanza’ (refs/remotes/…) nelle normali, le sezioni locali (refs/heads/all/…). Il secondo utilizza un refspec personalizzatoper memorizzare gli arbitri recuperati direttamente nella gerarchia di destinazione rif.

A causa del modo in cui gli aggiornamenti sono ciecamente inverosimile in questo repository unito, nessuno dovrebbe mai cercare di utilizzare direttamente esso: no commit fatta direttamente sui suoi rami, senza spinte dall'esterno. Se qualcuno dovesse fare impegna a livello locale o di spingere su uno dei rami quei commit fosse annullata quando il prossimo aggiornamento è fatto.

Se Redmine in grado di gestire un repository nuda, mi consiglia di utilizzare uno. Utilizzare git init --bare e un nome di pronti contro termine che termina con .git. Anche git config core.logAllRefUpdates true potrebbe essere una buona idea (dato che il valore predefinito è false in un repository nudo).

Oltre il prefisso all/ negli spazi dei nomi, un'altra differenza tra questo approccio e un clone completo --mirror è che arbitri fuori refs/heads e refs/tags non verranno raccolti. La maggior parte degli altri arbitri comuni sono considerati ‘locale’ in un repository (che è il motivo per cui non vengono copiati da un clone normale). Alcuni degli altri arbitri sono ‘filiali remote di monitoraggio’ (refs/remotes), un po ‘di tagliare in due’ di conservazione dei dati (refs/bisect), git filter-branch ‘originali’ ref backup (refs/original), eccetera. Probabilmente nessuna di queste altre cose sono importanti per Redmine. Se lo sono, possono anche essere inclusi con refspecs supplementari.

Creazione impegna iniziali extra

Per organizzare una filiale con un nuovo primo commit, vedi GitTips pagina sotto Come creare un nuovo ramo che non ha nessun antenato . Due delle ricette coinvolgono un altro repository da cui si preme o la fetch di un ramo dopo aver attraversato la solita init / ADD / commit fase (esattamente ciò che le ricette di cui sopra in modo automatico).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top