Domanda

La mia domanda riguarda il modo in cui gestisce i rami Git: ogni volta che si diramano da un impegnano, questo ramo non potrà mai ricevere le modifiche dal ramo genitore a meno che forza con un merge <. / p>

Ma in altri sistemi come noi Clearcase o AccuRev, è possibile specificare come rami si riempiono con una sorta di meccanismo di ereditarietà : Voglio dire, con Clearcase, utilizzando un config_spec, si può dire “ottenere tutti i file modificati sul ramo / main / issue001 e poi proseguire con quelle sul / principale o con questo specifica linea di base”.

In AccuRev si hanno anche un meccanismo simile, che cerchiamo di flussi di ricevere le modifiche da rami superiori (corsi d'acqua come li chiamano) senza la fusione o la creazione di un nuovo commit sul ramo.

Non si dimentica questo durante l'utilizzo di Git? Riesci a elencare gli scenari in cui questa eredità è un must?

Grazie

Aggiorna Si prega di leggere VonC risposta qui sotto effettivamente concentrare la mia domanda. Una volta che siamo d'accordo "stoccaggio lineare" e SCM basate DAG hanno capacità diverse, la mia domanda è: che sono gli scenari di vita reale (in particolare per le aziende più di OSS), dove lineare può fare le cose non è possibile per DAG? Sono vale?

È stato utile?

Soluzione

Per capire perché Git non offre un qualche tipo di quello che si fa riferimento a come un "meccanismo di eredità" (che non comportano un commit), è necessario prima capire uno dei core di quelle SCM (Git vs. ClearCase per esempio)

  • ClearCase utilizza un linear stoccaggio versione : ogni versione di un elemento (file o directory) è legata in maniera diretta linear rapporto con la precedente versione di lo stesso elemento.

  • Git utilizza un DAG - Aciclica grafo diretto : ogni "versione" di un file è in realtà parte di un insieme globale di cambiamenti in un albero che è essa stessa parte di un commit. La versione precedente di quel deve essere trovata in un precedente commit, accessibile attraverso un singolo percorso grafo orientato aciclico.

In un sistema lineare, una specifica configurazione può specificare diverse regole per realizzare il "eredità" che si vede (per un dato file, selezionare prima una certa versione, e se non presente, quindi selezionare un'altra versione, e se non presente, quindi selezionare un terzo, e così via).

Il ramo è un forcella in linear storia di una determinata versione per una data regola di selezione (tutte le altre regole di selezione prima che uno si applicano ancora, da qui il "eredità" effetto)

In un DAG, un commit rappresenta tutte le "eredità" si potrà mai ottenere; non c'è alcuna selezione "cumulativa" di versioni. C'è solo un percorso in questo grafico per selezionare tutti i file che si vedrà a questo punto esatto (commit).
Un ramo è solo un nuovo percorso in questo grafico.

Per applicare, in Git, alcune altre versioni, è necessario:

  • fondono in vostra filiale qualche altro commit (come nel git pull "di cui parla di stsquad risposta ) o
  • rebase vostro ramo (come cita Greg )

Ma dal momento che Git è uno SCM DAG-based, sarà sempre risultato in un nuovo impegno.

Ciò che si sta "perdendo" con Git è una sorta di "composizione" (quando si seleziona diverse versioni con differenti regole di selezione successive), ma che non sarebbe pratico in una D VCS ( come in "distribuita"): quando si effettua un ramo con Git, è necessario farlo con un punto di partenza e un contenuto chiaramente definiti e facilmente replicati ad altri repository

.

In un VCS puramente centrale, è possibile definire l'area di lavoro (in ClearCase, il vostro "vista", sia istantanea o dinamico) con qualsiasi regole che si desidera.


sconosciuto-Google aggiunge nel commento (e nella sua domanda di cui sopra):

  

Quindi, una volta che vediamo i due modelli possono realizzare cose diverse (lineare vs DAG), la mia domanda è: quali sono gli scenari di vita reale (in particolare per le aziende più di OSS), dove lineare può fare le cose non è possibile per DAG? Sono vale la pena?

Quando si tratta di "scenario di vita reale" in termini di regole di selezione, che cosa si può fare in un modello lineare è quello di avere diversi regole di selezione per lo stesso insieme di file .

Considerate questo "config spec" (vale a dire "specifica configurazione" per le regole di selezione con ClearCase):

element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... aLabel2 -mkbranch myNewBranch

Seleziona tutti i file etichettati 'aLabel2' (e ramo da lì), ad eccezione di quelli classificati come 'aLabel3' - e il ramo da lì - (perché tale regola precede °e una menzione 'aLabel2').

Ne vale la pena?

No.

In realtà, il sapore della UCM ClearCase (il " configurazione unificata Gestione " metodologia incluso con il prodotto ClearCase, e che rappresentano tutte le 'buone pratiche' dedotte da utilizzo di base ClearCase) non lo permette, per motivi di simplificity . Un insieme di file è chiamato un "componente", e se si desidera diramare per una determinata etichetta (noto come "di base"), che sarebbe stato tradotto in questo modo seguente specifica configurazione:

element /aPath/... .../myNewBranch
element /aPath/... aLabel3 -mkbranch myNewBranch
element /aPath/... /main/0 -mkbranch myNewBranch

Devi scegliere una punto di partenza (qui, 'aLabel3') e passare da lì. Se si desidera anche i file da 'aLabel2', si farà una fusione da tutti i file 'aLabel2' a quelli di 'myNewBranch'.

Si tratta di una "semplificazione" non si deve fare con un DAG, dove ogni nodo del grafico rappresenta un univocamente definito "punto di partenza" per un ramo, tutto ciò che è l'insieme di file coinvolti.

Unire e rebase sono abbastanza per combinare quel punto di partenza con le altre versioni di un dato insieme di file, al fine di raggiungere la "composizione" desiderato, pur mantenendo quella particolare storia in isolamento in un ramo .

L'obiettivo generale è quello di ragionare in " coerente le operazioni di controllo della versione applicato ad un coerente componente". Un insieme "coerente" di file è uno in uno stato coerente, ben definito:

  • se l'etichetta, tutti i suoi file sono etichettati
  • se ramificato, tutti i suoi file saranno diramano dalla stessa unica il punto di partenza

Questo è fatto facilmente in un sistema DAG; può essere più difficile in un sistema lineare (in particolare con "Base ClearCase", dove il "config spec" può essere difficile), ma si è imposto con la metodologia UCM di quello stesso utensile lineare-based.

Invece di realizzare che "composizione" attraverso una "regola di selezione trucco privata" (con ClearCase, alcune selezionate ordine regola), a raggiungere solo con operazioni di VCS (rebase o unire), che lasciano una traccia chiara per tutti da seguire (al contrario di una specifica configurazione privato a uno sviluppatore, o condivisa tra alcuni ma non tutti gli sviluppatori). Anche in questo caso, si impone un senso di coerenza , al contrario di una "flessibilità dinamica", che si può avere un tempo difficile da riprodurre in seguito .

Questo consente di lasciare il regno della VCS (Version Control System) e inserire il regno della SCM (Software Configuration Management) , che riguarda principalmente " riproducibilità ". E che (caratteristiche SCM) possono essere raggiunti con un lineare based o un VCS DAG-based.

Altri suggerimenti

Sembra che quello che stai cercando potrebbe essere git rebase . Rebasing un ramo stacca concettualmente dal suo punto di diramazione originale e riattacca esso in un altro punto. (In realtà, il rebase viene implementata applicando ogni patch del ramo in sequenza per il nuovo punto di diramazione, la creazione di una nuova serie di patch.) Nel tuo esempio, è possibile rebase un ramo alla punta attuale di un ramo superiore, che sarà essenzialmente "erediterà" tutte le modifiche apportate al l'altro ramo.

Io non sono del tutto chiaro che cosa il vostro chiedendo ma suona come git di monitoraggio semantica è ciò che si desidera. Nella diramazione di origine am si può fare qualcosa di simile:

git -t -b my_branch origin / master

E poi future s "git pull" saranno automaticamente unire origin / master nella vostra ramo di lavoro. È quindi possibile usare "git ciliegia -v origin / master" per vedere quale sia la differenza. È possibile usare "git rebase" prima di pubblicare il modifiche per ripulire la storia, ma non si dovrebbe usare rebase una volta la vostra storia è pubblico (vale a dire le altre persone stanno seguendo quel ramo).

Per quanto riguarda il sistema di eredità utilizzato da AccuRev: utenti GIT sarà probabilmente "ottenere" il tutto, quando lo sguardo al git-flow (vedi anche: http://github.com/nvie/gitflow e http://jeffkreeftmeijer.com/2010/why-arent- you-utilizzando-git-flow / )

Questa GIT ramificazione modello più o meno lo fa (manuale / con l'aiuto dello strumento di git-flow) che cosa AccuRev fa out-of-the-box in modo automatico e con grande il supporto GUI.

emerge GIT può fare quello AccuRev fa. Dal momento che non ho mai effettivamente utilizzato git / git-flow giorno per giorno non posso davvero dire come va a finire, ma ha un aspetto promettente. (Minus adeguato sostegno GUI: -)

cercherò di rispondervi domanda. (Devo dire che qui non ho usato GIT sola lettura su di esso, quindi se qualcosa che ho citato qui di seguito è sbagliato, per favore correggetemi)

"Puoi elencare gli scenari in cui questa eredità è un must?"

Non voglio dire che è d'obbligo, perché si può risolvere un problema con lo strumento che hai, e potrebbe essere una valida soluzione per l'ambiente. Credo che sia più una questione di processi che lo strumento stesso. Rendere sicuro il vostro processo è coerente e permette anche di tornare indietro nel tempo a riprodurre alcun passo / stato intermedio è l'obiettivo, e il vantaggio è che lo strumento consentono di eseguire il processo e Scmp più indolore possibile

L'uno scenario che posso vedere è comodo avere questa 'eredità' comportamento e usare il potere della specifica configurazione, è quando si desidera che il set di modifiche " isolati " mappato a un'attività (devtask, CR, SR, o qualsiasi altra cosa definisce lo scopo / portata del vostro set di cambiamento)

Utilizzando questa composizione permette di avere il ramo di sviluppo pulito e utilizzare ancora combinazione diversa (utilizzando la composizione) del resto del codice, e hanno ancora solo ciò che è rilevante per il compito isolato in una ramo durante la tutto il ciclo di vita del compito, solo fino a quando la fase di integrazione.

Essere purista dover impegnare / merge / rebase solo per avere un "punto di partenza definito", credo che sarebbe ' inquinare ' il vostro ramo e si finirà con le modifiche + altri cambiamenti il set di ramo / modifica.

Quando / Dove questo isolamento è utile? I punti di muggito potrebbero senso solo sul contesto delle imprese che perseguono CMM e alcune certificazioni ISO, e potrebbero essere di alcun interesse per altri tipi di società o OSS

  • Essere pignoli, si potrebbe desiderare di contare con precisione le linee di codice (aggiunto / modificato / cancellato) del set variazione corrispondente a un singolo sviluppatore, poi utilizzato come un ingresso per le stime di codice e di sforzo.

  • Può essere più facile di rivedere il codice in diverse fasi, avendo appena il codice in un unico ramo (non incollato con altre modifiche)

su grandi progetti con diverse squadre e +500 sviluppatori che lavorano attivamente contemporaneamente sullo stesso codice di base, (dove grafiche individuali versione alberi elemento si presenta come un web disordinato aggrovigliato con diverse linee di carico, una per ogni grande cliente, o uno per ogni tecnologia ) grandi caratteristiche di configurazione utilizzando la composizione di parecchi gradi in profondità fatti questa quantità di persone lavorare senza per adattare il / sistema (codice base stesso prodotto) per scopi diversi. Usando questa configurazione specifica, dato dinamicamente ogni squadra o squadra sub, una visione diversa di quanto hanno bisogno e da dove devono ramo di, (cascata su diversi casi), senza la necessità di creare rami integrazione intermedi, o costantemente fusione e rebasing tutti i bit di cui avete bisogno per iniziare. Codice dallo stesso compito / obiettivo è stato ramificazione di etichette diverse, ma aveva un senso. (Si può discutere qui la 'linea di base conosciuto' come principio della SCM, ma le etichette semplici previste in un piano di SCM scritta ha fatto il lavoro) Deve essere possibile risolvere questo con GIT (immagino in modo non dinamico) ma trovo davvero difficile da immaginare senza questo comportamento 'eredità'. Credo che il punto di cui parla VonC "se ramificato, tutti i suoi file saranno diramano dallo stesso punto di partenza unico" era rotto qui, ma accanto ad essa è stato ben documentato sul SCMP, mi ricordo che c'erano forti ragioni di business per farlo in quel modo.

Si costruire queste specifiche di configurazione che ho citato sopra non era libero, in principio in cui 4-5 persone ben pagati dietro la SCM, ma sono stati successivamente ridotti di script automatici che ti ha chiesto ciò che si vuole a condizioni di etichette / rami / caratteristiche e scriveranno il CS per voi.

La riproducibilità qui è stato ottenuto solo salvando la configurazione Spec insieme con il compito inSistema devTask, così ogni attività monte mappata esigenze ea valle mappati ad una specifica configurazione, un una serie di modifiche (file di codice, documenti di progettazione, documenti di prova ecc)

Quindi, fino a qui una conclusione qui potrebbe essere, solo se il progetto è abbastanza grande / complicata (e si può permettere gestori SC lungo la durata del progetto :)), allora si avrà solo iniziare a pensare se è necessario l' 'eredità 'comportamento o strumento davvero versatile, altrimenti si andrà direttamente alla aa strumento che è gratuito e già prendersi cura della coerenza di voi scm ... ma ci potrebbero essere altri fattori sullo strumento di SCM che potrebbero rendere attaccate ad uno o ad un altro ... continua a leggere ..

Alcune note a margine, che potrebbe essere fuori argomento, ma credo che in alcuni casi come il mio bisogno di essere considerati.

Devo aggiungere che usiamo il "bene-olo CC" non UCM. Totalmente d'accordo con VonC sul una buona metodologia permette di "guidare" la flessibilità verso una configurazione più coerente . La cosa buona è che CC è abbastanza flessibile e si può trovare (non senza qualche sforzo) un buon modo per avere cosa coerente mentre in altri SCM si potrebbe avere gratuitamente. Ma per esempio qui (e in altri luoghi che ho lavorato con CC) per C / C ++ progetti non siamo in grado di permettersi il prezzo di non avere il Winkin funzione (riutilizzando gli oggetti Nuovo campo), che riducono diversi X i tempi di compilazione tempo. Si può sostenere che avere una migliore progettazione, un codice più disaccoppiato, e l'ottimizzazione Makefile può ridurre la necessità di compilare il tutto, ma ci sono casi che è necessario per compilare l'intera bestia più volte al giorno, e la condivisione del DO salva cumuli di tempo / denaro. Dove sono ora cerchiamo di utilizzare lo strumento il più libero come possiamo, e penso che ci sarà sbarazzarsi di CC, se siamo in grado di trovare uno strumento più economico o libero che implementa il Winkin funzione.

finirò con qualcosa che Paolo menziona, diversi strumenti sono migliori che altro per scopi diversi , ma vorrei aggiungere che si può ottenere di distanza da alcune limitazioni dello strumento da avere un processo coerente e senza scarificazione riproducibilità, i punti chiave al largo della SCM Alla fine credo che la risposta al vale la pena? dipende dal vostro "problema", lo SDLC si esegue, i processi di SCM, e se c'è qualche caratteristica in più (come Winkin) che potrebbe essere utile nel vostro ambiente.

i miei 2 centesimi

Teoria a parte, ecco una specie di ovvio prendere pratici su questo, dal mio punto di vista utilizzando AccuRev in un ambiente di produzione commerciale per un certo numero di anni: Il modello di ereditarietà funziona molto bene finché flussi di bambini non hanno discostato troppo da antenati che sono ancora in fase di sviluppo. Si rompe quando i flussi che ereditano sono troppo differenti.

Inheritance (le versioni successive come figli di quelli precedenti) permette cambiamenti nella antenato flussi di essere attivi nel bambino flussi senza che nessuno fare nulla (a meno che non è necessaria una fusione, nel qual caso si presenta sovrapposizioni come profondo, che è bene essere in grado di vedere).

Sembra fantastico, e in pratica è, quando tutti i flussi coinvolte sono relativamente simili. Usiamo quel modello per i flussi di aggiornamento rapido e livello di service pack di sotto di una determinata versione di produzione. (E 'una realtà un po' più complicato di così per noi, ma questo è l'idea generale.)

uscite di produzione sono in parallelo, nessuna eredità, con quelle di hotfix e Service Pack bambini al di sotto ciascuno di essi. Iniziare una nuova versione significa creare un nuovo flusso a livello di rilascio, e spingendo manualmente tutto dal flusso di manutenzione più recente per la versione precedente in esso. Dopo di che, le modifiche alle versioni precedenti che si applicano a quelle successive devono essere spinti manualmente in ciascuna di esse, che richiedono più lavoro, ma che consente un maggiore controllo.

Inizialmente abbiamo usato il modello di ereditarietà per tutte le versioni, in cui quelle successive erano figli di quelli precedenti. Che ha funzionato bene per un po ', ma ha ottenuto ingestibile nel corso del tempo. Le principali differenze di architettura attraverso rilasci inevitabilmente ereditare le modifiche una cattiva idea. Sì, si può mettere uno snapshot in mezzo al blocco di eredità, ma poi tutte le modifiche devono essere spinti manualmente, e l'unica vera differenza tra genitore-snapshot-bambino e non ereditare flussi paralleli è che l'intera visualizzazione grafica flusso spinge continuamente verso il basso ea destra, che è una valle di lacrime.

Una cosa veramente bella di AccuRev è che avete questa scelta, tutto il tempo. Non è un vincolo inerente l'architettura del programma di SCM.

Avete notato che è possibile verifica versioni dei file specfific con GIT troppo?

Basta usare questo:

git checkout [< tree-ish >] [--] < paths >

Come per config spec qualsiasi versione esistente di un file (percorsi) possono essere caricati nel worktree. Citazione di docs git-checkout:

La seguente sequenza estrae ramo principale, ritorna il Makefile per due revisioni indietro, cancella hello.c per errore, e lo ottiene indietro dall'indice:

$ git checkout master             
$ git checkout master~2 Makefile             
$ rm -f hello.c            
$ git checkout hello.c            

ClearCase, senza MultiSite, è un unico repository Git, ma è distribuito. ClearCase impegna a livello di file, ma Git impegna a livello di repository. (Quest'ultima differenza significa che la domanda iniziale si basa su un equivoco, come sottolineato negli altri post qui.)

Se queste sono le differenze di cui stiamo parlando, allora penso 'lineare' contro 'DAG' è un modo confuso per distinguere questi sistemi SCM. In ClearCase tutte le versioni di un file sono indicati come versione "ad albero" del file, ma in realtà si tratta di un grafo orientato aciclico! La vera differenza di Git è che i DAG di ClearCase esistono per file. Quindi penso che sia fuorviante riferirsi a ClearCase come non-DAG e Git come DAG.

(BTW ClearCase versioni sue directory in un modo simile ai suoi file -. Ma questa è un'altra storia)

Non sono sicuro se ti stai chiedendo nulla, ma si stanno dimostrando che i flussi AccuRev sono strumenti diversi rispetto Git (o SVN) rami. (Non so Clearcase.)

Ad esempio, con AccuRev sei costretto , come dici tu, per usare alcuni flussi di lavoro, che vi dà una storia verificabile delle modifiche che non sono supportati in Git. l'eredità di AccuRev rende certi i flussi di lavoro più efficienti e altri impossibili.

Con Git si può avere esplorativa codifica segregato in pronti contro termine o in locali caratteristica rami, che non sarebbe supportato molto bene da AccuRev.

Diversi strumenti sono buoni per scopi diversi; è utile chiedere ciò che ognuno è buono per .

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