Il mio ufficio vuole unioni infinite di succursali come politica; quali altre opzioni abbiamo?


119

Il mio ufficio sta cercando di capire come gestiamo le divisioni e le fusioni delle filiali e abbiamo riscontrato un grosso problema.

Il nostro problema riguarda i sidebranch a lungo termine, il tipo in cui alcune persone lavorano in un sidebranch che si divide dal master, ci sviluppiamo per alcuni mesi e quando raggiungiamo un traguardo sincronizziamo i due.

Ora, IMHO, il modo naturale di gestirlo è, schiacciare il sidebranch in un unico commit. mastercontinua ad avanzare; come dovrebbe - non stiamo scaricando retroattivamente mesi di sviluppo parallelo nella masterstoria di. E se qualcuno ha bisogno di una risoluzione migliore per la storia del sidebranch, beh, ovviamente è ancora tutto lì - non è solo master, è nel sidebranch.

Ecco il problema: lavoro esclusivamente con la riga di comando, ma il resto del mio team utilizza GUIS. E ho scoperto che il GUIS non ha un'opzione ragionevole per visualizzare la cronologia di altri rami. Quindi, se raggiungi un impegno di squash, dicendo "questo sviluppo schiacciato dal ramo XYZ", è un dolore enorme andare a vedere cosa c'è dentro XYZ.

Su SourceTree, per quanto riesco a trovare, è un grosso mal di testa: se sei acceso mastere vuoi vedere la cronologia master+devFeature, devi controllare master+devFeature(toccando ogni singolo file diverso), oppure scorrere un registro che mostra TUTTI i rami del repository in parallelo fino a trovare il posto giusto. E buona fortuna a capire dove sei lì.

I miei compagni di squadra, giustamente, non vogliono avere una storia di sviluppo così inaccessibile. Quindi vogliono che queste grandi e lunghe catene di sviluppo si fondano, sempre con un impegno di unione. Non vogliono alcuna cronologia che non sia immediatamente accessibile dal ramo principale.

Io odio questa idea; significa un groviglio infinito e inarrivabile della storia dello sviluppo parallelo. Ma non vedo quale alternativa abbiamo. E sono piuttosto sconcertato; questo sembra bloccare quasi tutto ciò che so sulla buona gestione delle filiali e sarà una frustrazione costante per me se non riesco a trovare una soluzione.

Abbiamo qualche opzione qui oltre a fondere costantemente le sidebranches in master con merge-commit? Oppure, c'è una ragione per cui usare costantemente merge-commit non è così male come temo?


84
Registrare un'unione come unione è davvero così male? Vedo che schiacciare una storia lineare ha i suoi vantaggi, ma sono sorpreso che non farlo vada contro "quasi tutto ciò che sai sulla buona gestione delle filiali". Quali sono esattamente i problemi di cui hai paura?
IMSoP

65
OK, ma nella mia mente un ramo di lunga durata è esattamente dove si fa desiderare un po 'di visibilità, in modo che incolpa e bisects Non basta atterrare sulla "il cambiamento è stato introdotto come parte della Grande riscrittura del 2016". Non sono abbastanza fiducioso da pubblicare come risposta, ma il mio istinto è che dovrebbero essere schiacciati i compiti all'interno del ramo delle caratteristiche , in modo da avere una storia breve del progetto accessibile dalla storia principale, senza dover controlla un ramo orfano.
IMSoP

5
Detto questo, è del tutto possibile, quindi la domanda si riduce a "Sto cercando di usare git ad un livello superiore rispetto ai miei compagni di squadra; come posso impedirgli di rovinarlo per me." Il che, abbastanza onestamente, non mi aspettavo sinceramente git log master+bugfixDec10thdi essere il punto di rottura: - /
Standback

26
"sidebranches a lungo termine - il tipo in cui hai alcune persone che lavorano in un sidebranch che si divide dal master, ci sviluppiamo per alcuni mesi e quando raggiungiamo un traguardo sincronizziamo i due." Non tiri periodicamente dal master al ramo laterale? In questo modo ogni (pochi) impegni a padroneggiare tende a semplificare la vita in molti casi.
TafT

4
È merge --no-ffquello che vuoi? Su masterse stesso hai un commit che descrive cosa è cambiato nel ramo, ma tutti i commit esistono ancora e sono genitori di HEAD.
CAD97,

Risposte:


243

Anche se utilizzo Git dalla riga di comando, devo essere d'accordo con i tuoi colleghi. Non è sensato schiacciare grandi cambiamenti in un unico commit. In questo modo stai perdendo la storia, non solo rendendola meno visibile.

Il punto di controllo del codice sorgente è tenere traccia della cronologia di tutte le modifiche. Quando è cambiato cosa perché? A tal fine, ogni commit contiene puntatori a commit parent, un diff e metadati come un messaggio di commit. Ogni commit descrive lo stato del codice sorgente e la cronologia completa di tutte le modifiche che hanno portato a quello stato. Il garbage collector può eliminare i commit che non sono raggiungibili.

Azioni come rebasing, cherry-picking o squashing eliminano o riscrivono la storia. In particolare, i commit risultanti non fanno più riferimento ai commit originali. Considera questo:

  • Si schiacciano alcuni commit e si nota nel messaggio di commit che la cronologia schiacciata è disponibile nel commit originale abcd123.
  • Elimina [1] tutti i rami o tag che includono abcd123 poiché vengono uniti.
  • Hai lasciato correre il garbage collector.

[1]: Alcuni server Git consentono ai rami di essere protetti dall'eliminazione accidentale, ma dubito che tu voglia mantenere tutti i rami delle tue funzioni per l'eternità.

Ora non puoi più cercare quel commit - semplicemente non esiste.

Fare riferimento a un nome di ramo in un messaggio di commit è anche peggio, poiché i nomi di ramo sono locali in un repository. Ciò che è master+devFeaturenel tuo checkout locale potrebbe essere doodlediduhnel mio. I rami stanno semplicemente spostando le etichette che puntano a qualche oggetto di commit.

Di tutte le tecniche di riscrittura della storia, il rebasing è il più favorevole perché duplica i commit completi con tutta la loro cronologia e sostituisce semplicemente un commit parent.

Che la masterstoria includa la storia completa di tutti i rami che sono stati uniti in essa è una buona cosa, perché rappresenta la realtà. [2] Se ci fosse uno sviluppo parallelo, questo dovrebbe essere visibile nel registro.

[2]: Per questo motivo, preferisco anche impegni espliciti di unione sulla storia linearizzata ma alla fine falsa risultante dal rifacimento.

Sulla riga di comando, git logcerca di semplificare la cronologia visualizzata e mantenere tutti i commit visualizzati pertinenti. È possibile modificare la semplificazione della cronologia in base alle proprie esigenze. Potresti essere tentato di scrivere il tuo strumento git log che accompagna il grafico di commit, ma è generalmente impossibile rispondere "questo commit era originariamente impegnato su questo o quel ramo?". Il primo genitore di un commit di unione è il precedente HEAD, ovvero il commit nel ramo in cui si sta unendo. Ma ciò presuppone che non sia stata eseguita un'unione inversa dal master nel ramo della funzione, quindi dall'avanzamento rapido del master all'unione.

La migliore soluzione per le filiali a lungo termine che ho incontrato è quella di prevenire le filiali che si uniscono solo dopo un paio di mesi. La fusione è più semplice quando le modifiche sono recenti e di piccole dimensioni. Idealmente, ti unirai almeno una volta alla settimana. L'integrazione continua (come in Extreme Programming, non come in "installiamo un server Jenkins"), suggerisce anche più fusioni al giorno, ovvero non mantenere rami di funzionalità separati ma condividere un ramo di sviluppo in gruppo. La fusione prima che una funzione sia QA richiede che la funzione sia nascosta dietro un flag di funzionalità.

In cambio, una frequente integrazione consente di individuare potenziali problemi molto prima e aiuta a mantenere un'architettura coerente: cambiamenti di vasta portata sono possibili perché questi cambiamenti sono rapidamente inclusi in tutti i settori. Se una modifica rompe un po 'di codice, interromperà solo un paio di giorni di lavoro, non un paio di mesi.

La riscrittura della storia può avere senso per progetti davvero enormi quando ci sono più milioni di righe di codice e centinaia o migliaia di sviluppatori attivi. È discutibile il motivo per cui un progetto così grande dovrebbe essere un singolo repository git invece di essere diviso in librerie separate, ma a quella scala è più conveniente se il repository centrale contenga solo "release" dei singoli componenti. Ad esempio il kernel Linux impiega lo squash per mantenere gestibile la cronologia principale. Alcuni progetti open source richiedono l'invio di patch via e-mail, anziché una fusione a livello di git.


43
@Standback Non mi interessa cosa fa uno sviluppatore localmente ... usa i commit "wip", i commit extra per ogni errore di battitura fisso, .... Va bene, è meglio impegnarsi troppo spesso. Idealmente, lo sviluppatore pulisce quei commit prima che vengano spinti, come combinare tutti i commit che risolvono solo alcuni errori di battitura. È comunque una buona idea tenere separati i commit se fanno cose diverse, ad esempio un commit per funzionalità effettiva e test correlati, un altro per errori di battitura non correlati. Ma una volta che i commit sono stati spinti, riscrivere o eliminare la cronologia è più un problema di quanto non valga la pena, almeno nella mia esperienza.
amon,

11
"è generalmente impossibile rispondere" questo commit è stato originariamente impegnato su questo o quel ramo? "" Vedo il fatto che i "rami" sono solo dei suggerimenti per i commit senza una vera storia propria come uno dei maggiori difetti di progettazione in git Voglio davvero essere in grado di chiedere al mio sistema di controllo della versione "cosa c'era nel ramo x alla data y".
Peter Green

80
Niente è più frustrante che provare a identificare la causa di un bug nel codice usando git bisect, solo per farlo arrivare a un super-commit da 10.000 linee da un ramo laterale.
tpg2114,

2
@Standback IMHO più piccolo è il commit, più è leggibile e amichevole. Un commit che tocca più di pochi punti è impossibile da capire a prima vista, quindi basta prendere la descrizione al valore nominale. Questa è la leggibilità della descrizione (ad es. "Funzione implementata X"), non del commit (codice) stesso. Preferirei avere un 1000 di commit di una lettera come "cambiato http in https"
:)

2
cherry-pick non riscrive o cancella la cronologia. crea solo nuovi commit che replicano le modifiche dai commit esistenti
Sarge Borsch,

110

Mi piace la risposta di Amon , ma ho ritenuto che una piccola parte necessitasse di molta più enfasi: puoi semplificare facilmente la cronologia mentre visualizzi i log per soddisfare le tue esigenze, ma altri non possono aggiungere la cronologia durante la visualizzazione dei log per soddisfare le loro esigenze. Questo è il motivo per cui è preferibile conservare la storia come è avvenuta.

Ecco un esempio da uno dei nostri repository. Usiamo un modello di richiesta pull, quindi ogni caratteristica assomiglia ai tuoi rami di lunga durata nella storia, anche se di solito durano solo una settimana o meno. I singoli sviluppatori a volte scelgono di cancellare la loro storia prima della fusione, ma spesso ci accoppiamo con le funzionalità, quindi è relativamente insolito. Ecco alcuni dei primi impegni gitk, la gui che viene fornita in bundle con git:

vista gitk standard

Sì, un po 'un groviglio, ma ci piace anche perché possiamo vedere con precisione chi ha avuto ciò che cambia in quale momento. Riflette accuratamente la nostra storia di sviluppo. Se vogliamo vedere una vista di livello superiore, una richiesta pull unita alla volta, possiamo guardare la seguente vista, che è equivalente al git log --first-parentcomando:

vista gitk con --first-parent

git logha molte più opzioni progettate per darti esattamente le viste che desideri. gitkpuò prendere qualsiasi git logargomento arbitrario per costruire una vista grafica. Sono sicuro che altre GUI hanno funzionalità simili. Leggi i documenti e impara a usarlo correttamente, piuttosto che applicare la tua git logvisione preferita su tutti al momento dell'unione.


24
Non avevo familiarità con questa opzione! Questo è un grande aiuto per me e sembra che imparare più opzioni di registro mi permetterà di conviverci più facilmente.
Standback

25
+1 per "Puoi semplificare facilmente la cronologia durante la visualizzazione dei log per soddisfare le tue esigenze, ma altri non possono aggiungere la cronologia durante la visualizzazione dei log per soddisfare le loro esigenze." Riscrivere la storia è sempre discutibile. Se pensavi fosse importante registrare al momento del commit, allora era importante. Anche se hai scoperto che era sbagliato o lo hai rifatto in seguito, questo fa parte della storia. Alcuni errori hanno senso solo quando si può vedere in colpa che questa riga è stata lasciata da una riscrittura successiva. Quando gli errori vengono ripiegati con il resto dell'epopea non è possibile esaminare il motivo per cui le cose sono finite come sono.
TafT

@Standback Related, una cosa che mi aiuta a mantenere questa struttura per me, sta usando merge --no-ff- non usare le fusioni di avanzamento rapido, invece crea sempre un commit di unione in modo che --first-parentabbia qualcosa su cui lavorare
Izkata

34

Il nostro problema riguarda i sidebranch a lungo termine, il tipo in cui alcune persone lavorano in un sidebranch che si divide dal master, ci sviluppiamo per alcuni mesi e quando raggiungiamo un traguardo sincronizziamo i due.

Il mio primo pensiero è: non farlo nemmeno se non assolutamente necessario. Le fusioni devono essere impegnative a volte. Mantenere le filiali indipendenti e il più breve possibile. È un segno che è necessario suddividere le storie in blocchi di implementazione più piccoli.

Nel caso in cui tu debba farlo, allora è possibile unire in git con l'opzione --no-ff in modo che le storie siano mantenute distinte sul loro stesso ramo. I commit appariranno ancora nella cronologia unita ma possono anche essere visualizzati separatamente nel ramo delle caratteristiche in modo che almeno sia possibile determinare a quale linea di sviluppo facessero parte.

Devo ammettere che quando ho iniziato a usare git ho trovato un po 'strano che il commit del ramo apparisse nella stessa storia del ramo principale dopo l'unione. È stato un po 'sconcertante perché non sembrava che quei commit appartenessero a quella storia. Ma in pratica, non è affatto doloroso, se si considera che il ramo di integrazione è proprio questo: il suo scopo è quello di combinare i rami delle caratteristiche. Nel nostro team, non schiacciamo e facciamo frequenti commit di unione. Usiamo --no-ff tutto il tempo per assicurarci che sia facile vedere la cronologia esatta di qualsiasi funzione dovremmo voler investigare.


3
Sono pienamente d'accordo; tutti preferiscono restare vicini al maestro. Ma questo è un problema diverso, che è molto più grande e molto meno sotto la mia modesta influenza :-P
Standback

2
+1 pergit merge --no-ff
0xcaff il

1
Anche +1 per git merge --no-ff. Se usi gitflow, questo diventa il valore predefinito.
David Hammen,

10

Lasciami rispondere ai tuoi punti direttamente e chiaramente:

Il nostro problema riguarda i sidebranch a lungo termine, il tipo in cui alcune persone lavorano in un sidebranch che si divide dal master, ci sviluppiamo per alcuni mesi e quando raggiungiamo un traguardo sincronizziamo i due.

Di solito non vuoi lasciare i tuoi rami non sincronizzati per mesi.

Il ramo delle funzionalità si è ramificato in base al flusso di lavoro; chiamiamolo masterper semplicità. Ora, ogni volta che ti impegni a padroneggiare, puoi e dovresti git checkout long_running_feature ; git rebase master. Ciò significa che, per progettazione, i tuoi rami sono sempre sincronizzati.

git rebaseè anche la cosa giusta da fare qui. Non è un hack o qualcosa di strano o pericoloso, ma completamente naturale. Si perde un po 'di informazioni, che è il "compleanno" del ramo delle funzionalità, ma il gioco è fatto. Se qualcuno lo trova importante, potrebbe essere fornito salvandolo da qualche altra parte (nel sistema di biglietteria o, se necessario, in un git tag...).

Ora, IMHO, il modo naturale di gestirlo è, schiacciare il sidebranch in un unico commit.

No, non lo vuoi assolutamente, vuoi un commit di unione. Un commit di unione è anche un "commit singolo". In qualche modo, non inserisce tutti i singoli commit di ramo "in" master. È un unico commit con due genitori: la mastertesta e la testa del ramo al momento della fusione.

Assicurati di specificare l' --no-ffopzione, ovviamente; la fusione senza --no-ff, nel tuo scenario, dovrebbe essere severamente vietata. Sfortunatamente, --no-ffnon è l'impostazione predefinita; ma credo che ci sia un'opzione che puoi impostare per renderlo tale. Vedi git help mergecosa --no-fffa (in breve: attiva il comportamento che ho descritto nel paragrafo precedente), è cruciale.

non stiamo scaricando retroattivamente mesi di sviluppo parallelo nella storia del maestro.

Assolutamente no - non si sta mai scaricando qualcosa "nella storia" di un ramo, specialmente non con un commit di unione.

E se qualcuno ha bisogno di una migliore risoluzione per la storia del sidebranch, beh, ovviamente è ancora tutto lì - non è proprio nel master, è nel sidebranch.

Con un commit di unione, è ancora lì. Non nel maestro, ma nel fianco, chiaramente visibile come uno dei genitori della fusione commette, e mantenuto per l'eternità, come dovrebbe essere.

Vedi cosa ho fatto? Tutte le cose che descrivi per il tuo commit di squash sono proprio lì con il --no-ffcommit di merge .

Ecco il problema: lavoro esclusivamente con la riga di comando, ma il resto del mio team utilizza GUIS.

(Nota laterale: lavoro quasi esclusivamente anche con la riga di comando (beh, è ​​una bugia, di solito uso emacs magit, ma questa è un'altra storia - se non sono in un posto conveniente con la mia configurazione individuale di emacs, preferisco il comando linea pure). Ma per favore fatevi un favore e provare almeno git guiuna volta. e ' così molto più efficiente per la raccolta di linee, fusti, ecc per l'aggiunta / rovina aggiunge.)

E ho scoperto che il GUIS non ha un'opzione ragionevole per visualizzare la cronologia di altri rami.

Questo perché ciò che stai cercando di fare è totalmente contrario allo spirito di git. gitsi basa dal nucleo su un "grafico aciclico diretto", il che significa che molte informazioni sono nella relazione genitore-figlio-commit delle commit. E, per le fusioni, ciò significa che la vera unione si impegna con due genitori e un figlio. Le GUI dei tuoi colleghi andranno bene non appena utilizzi i no-ffcommit di unione.

Quindi, se raggiungi un impegno di squash, dicendo "questo sviluppo schiacciato dal ramo XYZ", è un dolore enorme andare a vedere cosa c'è in XYZ.

Sì, ma questo non è un problema della GUI, ma del commit di squash. L'uso di uno squash significa lasciare la testa del ramo della funzione penzolante e creare un nuovo commit master. Questo rompe la struttura su due livelli, creando un grande casino.

Quindi vogliono che queste grandi e lunghe catene di sviluppo si fondano, sempre con un impegno di unione.

E hanno assolutamente ragione. Ma essi non sono "fuse in ", sono solo uniti. Una fusione è una cosa veramente equilibrata, non ha un lato preferito che viene unito "nell'altro" ( git checkout A ; git merge Bè esattamente lo stesso che git checkout B ; git merge Atranne per le differenze visive minori come i rami che vengono scambiati in git logecc.).

Non vogliono alcuna cronologia che non sia immediatamente accessibile dal ramo principale.

Che è completamente corretto. In un momento in cui non ci sono funzionalità non unite, avresti un singolo ramo mastercon una ricca cronologia che incapsula tutte le linee di commit delle funzioni che ci sono mai state, tornando al git initcommit dall'inizio del tempo (nota che ho evitato espressamente di usare il termine " rami "nell'ultima parte di quel paragrafo perché la storia in quel momento non è più" rami ", anche se il grafico di commit sarebbe piuttosto ramoso).

Odio quell'idea;

Quindi provi un po 'di dolore, poiché stai lavorando contro lo strumento che stai utilizzando. L' gitapproccio è molto elegante e potente, specialmente nell'area ramificata / di fusione; se lo fai bene (come accennato in precedenza, specialmente con --no-ff) è a passi da gigante ad altri approcci (ad esempio, il pasticcio di sovversione di avere strutture di directory parallele per i rami).

significa un groviglio infinito e inarrivabile della storia dello sviluppo parallelo.

Infinito, parallelo - sì.

Innaffiabile, groviglio - no.

Ma non vedo quale alternativa abbiamo.

Perché non lavorare esattamente come l'inventore git, i tuoi colleghi e il resto del mondo, ogni giorno?

Abbiamo qualche opzione qui oltre a fondere costantemente le sidebranches in master con merge-commit? Oppure, c'è una ragione per cui usare costantemente merge-commit non è così male come temo?

Nessuna altra opzione; non così male.


10

Schiacciare un sidebranch a lungo termine ti farebbe perdere molte informazioni.

Quello che vorrei fare è provare a reimpostare il master nel sidebranch a lungo termine prima di fondere il sidebranch in master . In questo modo mantieni ogni commit nel master, rendendo la cronologia del commit lineare e più facile da capire.

Se non potessi farlo facilmente ad ogni commit, lo lascerei non lineare , al fine di mantenere chiaro il contesto di sviluppo. Secondo me, se ho una fusione problematica durante il rebase del master nella sidebranche, significa che la non linearità aveva un significato nel mondo reale. Ciò significa che sarà più facile capire cosa è successo nel caso in cui ho bisogno di scavare nella storia. Ho anche il vantaggio immediato di non dover fare un rebase.


: + per citare rebase. Indipendentemente dal fatto che sia l'approccio migliore qui (personalmente non ho avuto grandi esperienze con esso, anche se non l'ho usato molto), sembra sicuramente essere la cosa più vicina a ciò che OP sembra voler davvero - in particolare, un compromesso tra un dump della cronologia fuori ordine e nascondere completamente quella storia.
Kyle Strand,

1

Personalmente preferisco fare il mio sviluppo in un fork, quindi estrarre le richieste per unirle nel repository primario.

Ciò significa che se voglio riformulare le mie modifiche in cima al master o eliminare alcuni commit WIP, posso farlo totalmente. Oppure posso solo richiedere che anche tutta la mia storia venga unita.

Quello che mi piace fare è fare il mio sviluppo su un ramo ma spesso mi ribasso contro master / dev. In questo modo ottengo le modifiche più recenti dal master senza avere un sacco di commit di merge nel mio ramo o dover affrontare un sacco di conflitti di merge quando è il momento di unire al master.

Per rispondere esplicitamente alla tua domanda:

Abbiamo qualche opzione qui oltre a fondere costantemente le sidebranches in master con merge-commit?

Sì, puoi unirli una volta per ramo (quando la funzione o la correzione è "completa") o se non ti piace avere i commit di unione nella tua cronologia, puoi semplicemente eseguire una fusione in avanti veloce sul master dopo aver effettuato un rebase finale.


3
Mi dispiace, faccio la stessa cosa, ma non vedo come questo risponda alla domanda: - /
Standback

2
Aggiunta una risposta esplicita alla domanda dichiarata.
Wayne Werner,

Quindi, va bene per i miei impegni, ma io (e la mia squadra) ci occuperemo del lavoro di tutti . Mantenere pulita la mia storia è facile; lavorare in una storia di sviluppo disordinata è il problema qui.
Standback

Vuoi dire che vuoi richiedere altri sviluppatori per ... cosa? Non rebase e basta schiacciare l'unione? O stavi solo postando questa domanda per lamentarti della mancanza di disciplina git dei tuoi colleghi?
Wayne Werner,

1
il rebasing regolare non è utile se diversi sviluppatori stanno lavorando su quel ramo di funzionalità.
Paŭlo Ebermann,

-1

Il controllo delle revisioni è immondizia immondizia.

Il problema è che i lavori in corso sul ramo delle funzionalità possono contenere molti "proviamo questo ... no che non ha funzionato, sostituiamolo con quello" e tutti i commit tranne l'ultimo "che" finiscono inquinando inutilmente la storia.

In definitiva, la storia dovrebbe essere mantenuta (in parte potrebbe essere utile in futuro), ma solo una "copia pulita" dovrebbe essere unita.

Con Git, questo può essere fatto ramificando prima il ramo della funzione (per mantenere tutta la cronologia), quindi (interattivamente) ri-raggruppando il ramo della filiale della funzione dal master e quindi unendo il ramo riformulato.


1
Solo per chiarire: quello che stai dicendo è di riscrivere la storia su (una copia di) il ramo delle caratteristiche, quindi ha una storia breve e pulita, eliminando tutto il avanti e indietro dello sviluppo iniziale. E poi, fondere il ramo riscritto in master è più semplice e pulito. Ti ho capito bene?
Standback

1
Sì. E quando ti unirai al master, sarà solo un avanzamento veloce (supponendo che ti sia riformulato di recente prima della fusione).
Depresso

Ma come viene conservata questa storia? Lasci in giro il ramo della caratteristica originale?
Paŭlo Ebermann,

@ PaŭloEbermann Bingo.
Depresso

Bene, come ha detto qualcun altro in un commento: i rami sono solo dei puntatori nel grafico cronologico gite sono locali. Ciò che è nominato fooin un repository può essere nominato barin un altro repository . E sono pensati per essere temporanei: non vuoi ingombrare il tuo repository con migliaia di rami di funzioni che devono essere mantenuti in vita per evitare di perdere la cronologia. E dovresti mantenere quei rami per mantenere la cronologia come riferimento, perché gitalla fine eliminerà qualsiasi commit che non è più raggiungibile da un ramo.
cmaster
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.