2013-05-07 3 views
41

Avviso domanda newbie !!! Sto iniziando a utilizzare Git, e in particolare Sourcetree che sembra una buona applicazione per visualizzarlo. Durante il mio primo test è andato abbastanza bene, ramificando e unendo (vedi il diagramma in alto). So che questa struttura significa che sto usando lo sviluppo e il ramo principale nel modo sbagliato, ma va bene perché almeno ha funzionato.Git/Sourcetree ramificazione e fusione di base

Al mio secondo tentativo però, non riuscivo a visualizzare alcun ramo, anche se il lavoro veniva eseguito in entrambi sembrano apparire in un singolo ramo (con una nota '7 avanti'), e quando Cerco di unire e niente sembra accadere. Spero che il secondo screenshot sia abbastanza per qualcuno da dirmi cosa sta succedendo qui? Altrimenti proverò a dare qualche informazione in più.

In questo momento sto solo giocando, quindi sto ancora facendo i conti con un flusso di lavoro adeguato, solo cercando di ottenere che le azioni di ramificazione e fusione di base si svolgano in modo coerente attraverso Sourcetree. Qualsiasi aiuto sarà apprezzato.

enter image description here

+1

Ho avuto lo stesso problema. Al momento sto cercando di abituarmi anche a git. Quando ricordo male, prova a recuperare l'attuale 'fonte' da Git Origin. Questo aggiorna la tua fonte locale.Per quanto ne so, "X ahread" o "X behind" significa che la tua sorgente locale non è "sincronizzata" con Git-Server. –

+0

Non c'è niente di sbagliato qui. Il tuo padrone e il tuo sviluppo non sono stati divergenti, quindi stanno indicando lo stesso commit. Hai letto il capitolo della ramificazione del [libro Git] (http://git-scm.com/book/en/Git-Branching)? – 1615903

+1

Questa non è una buona domanda per SO dal momento che è così stretta. Inoltre, "guarda questo e indovina cosa ho fatto di sbagliato" non è molto per gli altri. Probabilmente vorrai lavorare con alcuni tutorial SourceTree e/o Git, che dovrebbero essere sui loro siti. –

risposta

13

Nella seconda immagine ci sono rami. A livello locale ci sono 2 rami, master & sviluppo. Entrambi i rami stanno riposando allo stesso commit però. Se si desidera 'vedere i rami' come nella prima immagine, è possibile eseguire un commit su sviluppare, tuttavia il grafico sarà ancora lineare. Potrai creare unionesviluppare in master a quel punto se desideri.

Se si desidera vedere il grafico divergere, provare a mettere un commit su master pure. Quindi inizierai a vedere qualcosa di più simile alla prima immagine.

Per avere un'idea di come funziona git con un programma di visualizzazione come questo, ti suggerisco di fare azioni come suggerito sopra, e dare un'occhiata al grafico in ogni fase intermedia.

+0

Questo lo rende un po 'più chiaro - grazie. Ora ho apportato modifiche a ciascun ramo e ora sono divergenti. Ancora tanto da imparare! – Chris

+0

Prova anche il rebasing, e sicuramente scatta un'istantanea ad ogni passaggio intermedio con lo strumento di visualizzazione: D – quickshiftin

+4

Ho avuto esattamente lo stesso problema, la tua risposta mi ha aiutato molto a capire i rami in git. Non so perché questa domanda è stata chiusa per qualche stupido motivo ... – SathOkh

2

Mi sono imbattuto in questo stesso problema e ho scoperto che c'è un'impostazione in SourceTree su "Non eseguire l'avanzamento rapido durante l'unione, creare sempre il commit". Assicurati che sia selezionato e vedrai la struttura della filiale da loro.

Questa impostazione si trova nella scheda Git nelle preferenze.

4

Qui stanno succedendo alcune cose. In primo luogo, è utile capire che i rami in Git sono in realtà solo "etichette" che sono bloccate su un particolare commit e che verranno spostate automaticamente quando ci si impegna nel ramo; Git creerà il nuovo commit, con un nuovo hash di commit, e aggiornerà il branch/label in modo che punti al nuovo commit. (Si potrebbe chiedere, in che modo è diverso dai tag, quindi un tag è bloccato sullo stesso commit e non riceverà gli aggiornamenti quando si chiama git commit.)

Quando si crea un nuovo ramo, tutto ciò che accade è che Git crea una nuova etichetta, puntando allo stesso commit su cui ti trovavi. Solo quando crei un nuovo commit mentre questo nuovo ramo viene estratto, vedrai il nuovo ramo divergere dall'altro ramo.

La vera confusione inizia quando si inizia di nuovo i rami che si fondono, e questo è in gran parte a causa di una cosa strana Git chiama "Fast Forward fusione", che lo fa di default .Prendiamo il tuo secondo esempio e immaginiamo che il tuo padrone e sviluppare sono dove originariamente origin/master e l'origine/sviluppano erano:

Simple linear branching example

Quando si chiede Git di unire un ramo in un altro, Git andrà e capire cosa deve fare per ottenere la differenza tra quei rami nel ramo di destinazione. Diciamo che si desidera unire le modifiche apportate a svilupparsi in padrone, in modo da dire git:

$ git checkout master 
$ git merge develop 

Git esaminerà i rami, e vedere che si sviluppano è poco più avanti del maestro da alcuni impegna, ma non c'è niente di più complicato in corso. Quindi, eseguirà un processo di "avanzamento rapido", semplicemente prendendo l'etichetta principale e attaccandola al commit dove punta lo sviluppo. Missione compiuta, i cambiamenti che erano solo in fase di sviluppo sono ora anche nel master.

Se ogni ramo ha commits aggiuntivi, come nel tuo primo esempio, prima di fondere il master in sviluppo, "qualcosa di più complicato" è in corso. Hai fatto un commit su master, poi hai sviluppato un checkout git, hai eseguito un commit e quindi ha chiesto a Git di unire il master allo sviluppo. Git non può più "imbrogliare" spostando semplicemente le etichette delle filiali. Dovrà capire come unificare i cambiamenti dei due rami in un singolo stato dei file sotto il suo controllo (supponiamo, per ora, è sempre in grado di farlo, il che non è poi così lontano dalla verità; abbastanza bene, se non ci riesci, hai un conflitto di fusione, che in realtà non è così brutto come sembra).

Il nuovo contenuto, dopo l'unione, non sarà né l'ultimo stato del primo ramo né lo stato del secondo ramo. Quindi, deve essere rappresentato con un nuovo commit, che è ciò che vedi all'inizio del tuo primo esempio; Git ha creato ciò che definisce un "merge commit" per rappresentare il nuovo stato con i cambiamenti di ogni ramo uniti in un singolo stato.

Infine, è possibile forzare Git a creare sempre un commit di unione, anche se strettamente, tecnicamente, non è necessario. Nella riga di comando, puoi farlo con il flag --no-ff, per nessun avanzamento veloce. I client grafici avranno una casella di controllo che realizzerà la stessa cosa (in SourceTree, al momento è etichettato "Crea un commit anche se l'unione viene risolta tramite l'avanzamento rapido"). Molti (incluso me stesso) raccomandano di fondersi semplicemente con --no-ff, perché in questo modo l'atto di unire viene sempre registrato nella cronologia, indipendentemente dalle tecnicamente come se sarebbe tecnicamente possibile spostare semplicemente i puntatori di ramo.

1

È possibile evitare che i rami di scomparire in Tree Fonte permanentemente abilitando "Non fast-forward quando si uniscono, creare sempre commettere" in Strumenti/Opzioni.

Disabling fast-forward when merging permanently in Source Tree

Se si vuole decidere per ciascuna operazione di unione, c'è l'opzione "Creare un nuovo commit, anche se fast-forward è possibile" nella finestra di dialogo Unisci.

Disable fast-forward when merging during each merge operation in Source Tree

Inoltre vi suggerisco di riferimento Eelke Blok s' answer per i dettagli tecnici.

+0

Esattamente quello che stavo cercando, grazie –