Il git "Golden Rule of Rebasing" è così essenziale?


22

Di recente ho avuto una discussione con persone assolutamente contrarie a una strategia di ribasatura dei rami delle funzioni su GIT. Sembra essere uno schema accettato per usare rebase solo per filiali locali e private, ma non usarlo mai quando ci sono diverse persone che lavorano su una stessa funzione e ramo, come da questa cosiddetta "Regola d'oro del rifacimento" (come spiegato qui: https : //www.atlassian.com/git/tutorials/merging-vs-rebasing/conceptual-overview )

Sono solo sorpreso che ci sia consenso su questo. Ho lavorato 3 anni con una strategia di rebasing completa, con circa 20 sviluppatori che lavorano insieme e indovina un po ', ha funzionato.

Il processo è sostanzialmente:

  • Crei il tuo ramo delle caratteristiche, chiamiamolo "myfeature" e spingilo su origin / myfeature
  • Altre persone possono verificarlo e lavorarci su
  • A volte puoi rifarlo dal master: da "myfeature", git rebase origin / master ; e poi sì, devi forzarlo.
  • Cosa succede quando altre persone vogliono spingere i propri impegni? Lo ribattevano semplicemente: git rebase origin / myfeature . Quindi ora sono in rapido avanzamento e possono spingerlo senza forzare.

L'unico principio da rispettare è che il ramo delle caratteristiche sia di proprietà di qualcuno . Il proprietario è l'unico che può spingere-forza.

Quindi, lo ammetto: non appena c'è una forza di spinta, c'è il rischio di fare errori. È vero. Ma ci sono anche molti modi per recuperare dagli errori e, in 3 anni di sviluppo, non ho visto molti errori di spinta forzata e quando è successo abbiamo sempre trovato il modo di recuperare correttamente.

Quindi, perché questa "Regola d'oro del rebase" è così ampiamente accettata? C'è qualcos'altro che mi è mancato? Capisco che richiede un minimo di organizzazione (ogni strategia richiede una certa organizzazione), ma funziona.


Qualcosa che ho dimenticato di dire, ma ha la sua importanza: nella mia esperienza precedente stavamo usando gerrit come strumento di revisione del codice. Significa che se qualcuno invia un commit mentre il proprietario della succursale sta eseguendo un rebase, non c'è rischio che il commit venga perso, perché viene spinto su Gerrit invece che direttamente nel repository di origine. E poiché il proprietario della filiale è l'unico che ha il diritto di presentare commesse da gerrit, il rischio di commettere errori è stato molto basso.
Joel,

cosa succede se unisco il ramo delle funzionalità di qualcun altro nel mio?
Winston Ewert,

Se la tua funzione dipende da un'altra, allora suppongo che potresti rifare la tua dall'altra: git rebase origin / otherFeature (dico rebase piuttosto che unire, poiché l'obiettivo è mantenere la storia lineare). Ammetto che la complessità di tutto ciò aumenta molto quando si introducono sempre più dipendenze tra i rami.
Gioele,

Risposte:


10

Il problema con la forzatura forzata non riguarda il ramo delle funzionalità e il master, ma di spingere il master verso il master di qualcun altro: tale sincronizzazione sovrascriverà il master con le modifiche, ignorando tutto ciò che è in punta.

Considerando questo pericolo, c'è un motivo per cui non dovresti usarlo affatto a meno che le cose non siano andate male e non hai assolutamente, assolutamente bisogno di usarlo per effettuare riparazioni. Un sistema SCM non dovrebbe mai essere forzato in questo modo, se lo fa perché qualcosa è andato terribilmente storto (e il mio primo approccio in questi casi sarebbe di ripristinare i backup e ripetere le operazioni per mantenere intatta la cronologia).

Quindi forse la domanda è: perché ti stai ribellando? Per una cronologia "pulita" quando si riportano le funzionalità al master? Se è così, stai buttando via tutta la buona storia della ramificazione per motivi puramente di stile. Anche la fusione rapida IMHO non è una buona pratica, dovresti tenere tutta la cronologia in modo da poter vedere ciò che hai realmente fatto, non una versione disinfettata in seguito.


Ovviamente potresti tirare su master, rebase e quindi forzare la spinta, ma questo non è atomico.
Kevin,

@gbjbaanb hai perfettamente ragione, la strategia di rebasing è tutta incentrata su motivi di stile / storia più leggibile. Non sto cercando di sostenere che sia meglio o no. Ma è possibile farlo, ed è questo il punto che voglio sollevare. Ovviamente non stavo parlando di forzare la forza sul master, ma solo sui rami delle caratteristiche.
Joel,

4
IMHO la funzionalità di progettazione di entrambi rebase, e le fusioni in avanti veloce sono state un errore. SCM consiste nel mantenere la cronologia in modo da poter vedere cosa è successo quando è necessario e scattare istantanee per i punti rilevanti nel tempo. Almeno questo è quello che vuole la maggior parte della gente, immagino che Linus volesse che la storia fosse la più semplice da leggere per lui e quindi li mise a suo vantaggio. IMHO avrebbe dovuto fare uno sforzo maggiore per rendere le differenze tra 2 revisioni più gestibili (ovvero consentire alla vista di essere più semplice, non alla storia sottostante)
gbjbaanb,

2
Quando pubblichi un documento, pubblichi la prima bozza? C'è qualche legge che dice che gli strumenti utilizzati per scrivere la prima stesura non possono essere utilizzati per modificare per la pubblicazione? Git è uno strumento di sviluppo. Se si desidera in modo affidabile e verificabile preservare una serie, preservarla. Se si desidera invece modificarlo per la pubblicazione, modificarlo. Git è stellare in entrambi i compiti.
jillill

5

Rebase non è essenziale, come si dice che è per lo più cosmetici. A volte è molto più semplice di una fusione. Quindi può avere un valore "effettivo", ma solo "a volte"

L'uso improprio di rebase può essere costoso. È improbabile che perda dati se sai abbastanza per non farti prendere dal panico e cercare le procedure di recupero, ma "hey nessuno spinge per un po 'che devo sistemare ..." non è eccezionale. Né qualcuno sta perdendo tempo nel recupero della ricerca e nei test quando avrebbe potuto aggiungere funzionalità o eliminare bug (o a casa con la famiglia).

Con questo compromesso i risultati di "pochissime persone fanno un ribasso e una spinta forzata" non è molto sorprendente.

Alcuni flussi di lavoro possono ridurre il rischio, ad esempio ridurlo a "zero, purché si ricordi quali rami è consentito forzare e quali non è possibile". In realtà potrebbero essere abbastanza sicuri da giustificare il rischio, ma la gente fa spesso delle scelte basate su un folklore più ampio. Poi di nuovo in realtà i benefici sono piuttosto piccoli, quindi quanto deve essere veramente piccolo il rischio?


3
"hey nessuno spinge per un po 'devo sistemare ..." .. sembra come ai vecchi tempi di usare Visual Source Safe. Pensavo che Git fosse meglio di così.
gbjbaanb,

Sì, quindi le persone fanno regole come "non giocare con gli strumenti affilati! (Forza la spinta)" Quindi possono evitare di curare ferite evitabili!
Stripes

2
@gbjbaanb Sì, Git è meglio di così - quando lo si utilizza in modo corretto. Lamentarsi del fatto che Git non sia in grado di affrontare elegantemente lo sviluppo concorrente quando si riepilogano e cambiano costantemente gli hash di commit di tutto è come lamentarsi del fatto che le macchine siano inferiori alle carrozze perché sono molto più pesanti per il cavallo da tirare. Non è colpa dello strumento se la gente insiste nell'usarlo in modo sbagliato ...
Idan Arye,

4
Beh, è ​​un po 'colpa dello strumento. Git espone MOLTI spigoli vivi, mentre a volte nota che sono nitidi spesso non lo fa. Se lo confronti per dire CVS in cui tutti i bit taglienti si trovano in un SINGOLO sottocomando ("cvs admin"? Ha un po 'di tempo ...) che fa di tutto per dire "questo può tagliarti male, no usalo a meno che tu non abbia un disperato bisogno ". O altri sistemi di controllo della versione che omettono funzionalità che possono danneggiare.
Stripes

4
Questo non vuol dire che git non abbia fatto valide scelte progettuali (funzione correlata al gruppo per sottocomando e preferisce consentire a git di risolvere cose più complesse con le mani giuste) ... ma sono SCELTE e si può essere critici nei confronti del scelta di avere così tanti spigoli vivi, proprio come uno può essere critico nei confronti della scelta di altri VCS per tralasciare così tante utili funzioni "solo perché qualcuno può farsi male".
Stripes

2

Per aggiungere una voce diversa:

Sì, se lavori come descritto, non ci sono problemi con l'uso rebasee la spinta forzata. Il punto critico è: hai un accordo nella tua squadra.

Gli avvertimenti rebasee gli amici riguardano il caso in cui non esiste un accordo speciale. Normalmente, git ti protegge automaticamente, ad esempio, non consentendo una spinta non veloce. L'uso rebasee la spinta forzata prevalgono su quella sicurezza. Va bene se hai qualcos'altro in atto.

Nel mio team, a volte rifacciamo anche i rami delle funzionalità se la storia è diventata disordinata. O eliminiamo il vecchio ramo e ne creiamo uno nuovo con un nuovo nome, oppure coordiniamo semplicemente in modo informale (il che è possibile perché siamo una piccola squadra e nessun altro lavora nel nostro repository).


Si noti che anche il progetto git fa qualcosa di simile: hanno un ramo di integrazione che viene regolarmente ricreato, chiamato "pu" ("aggiornamenti proposti"). È documentato che questo ramo viene ricreato regolarmente e che non è necessario basare nuovi lavori su di esso.


1

Quindi, lo ammetto: non appena c'è una forza di spinta, c'è il rischio di fare errori. È vero. Ma ci sono anche molti modi per recuperare dagli errori e, in 3 anni di sviluppo, non ho visto molti errori di spinta forzata e quando è successo abbiamo sempre trovato il modo di recuperare correttamente.

Il motivo per cui gli utenti di Git tendono a evitare la cronologia condivisa mutevole è perché non c'è evitamento o riparazione automatici di questi problemi. Devi sapere cosa stai facendo e devi sistemare tutto manualmente se sbagli. Consentire esattamente a una persona di eseguire la spinta forzata non è intuitivo e contrariamente al design distribuito di Git. Cosa succede se quella persona va in vacanza? Qualcun altro possiede temporaneamente la filiale? Come fai a sapere che non cammineranno dappertutto qualunque cosa il proprietario originale stesse facendo? E nel mondo open source, cosa succede se il proprietario della filiale si allontana gradualmente dalla comunità, senza andarsene ufficialmente? Potresti perdere molto tempo in attesa di passare la proprietà della filiale a qualcun altro.

Ma il vero problema è questo: se sbagli e non te ne accorgi immediatamente, i vecchi commit alla fine svaniranno dopo che è trascorso abbastanza tempo. A quel punto, il problema potrebbe essere irrecuperabile (o almeno, potenzialmente molto difficile da recuperare, a seconda dell'aspetto della storia di backup: esegui il backup di vecchie copie del tuo repository Git, cioè non solo dei cloni?).

In contrasto con il lavoro di evoluzione di Changesur di Mercurial (che, devo notare, non è ancora finito o stabile). Tutti possono apportare qualsiasi modifica alla cronologia che preferiscono, a condizione che le modifiche non siano contrassegnate come pubbliche. Questi emendamenti e ribassi possono essere spinti e tirati con totale impunità, senza bisogno di un proprietario di filiale. Nessun dato viene mai cancellato; l'intero repository locale è solo append. I cambiamenti che non sono più necessari sono contrassegnati come obsoleti, ma mantenuti indefinitamente. Alla fine, quando rovini la tua cronologia (che viene trattata come una parte normale del tuo flusso di lavoro quotidiano), c'è un comando ingegnoso per ripulirla automaticamente. Questo è il tipo di UX che le persone si aspettano prima di andare in giro a modificare la cronologia condivisa.


Sono d'accordo con questa "filosofia git" e penso anche che a volte le filosofie possano essere hackerate :). Più seriamente, come ho affermato nei commenti, ormai 3 anni fa, ero nel caso particolare di avere gerrit come strumento di revisione del codice che fungeva da strumento di backup di fatto, impedendo tale potenziale perdita drammatica. Ora penso ancora che rebase sia OK quando sei sicuro di "controllare" un ramo. Anche in un progetto opensource, se sto sviluppando una funzione e apro una richiesta pull, "possiedo" quel PR, ritengo di avere il diritto di modificare il suo ramo, spetta a me non rovinare il mio lavoro durante il rebasing ... (1/2)
Joel

... e se alcune persone vogliono apportare modifiche a quel PR, allora penso che dovrebbero dirmelo prima, ed è una questione di comunicazione. (2/2)
Gioele il

PS: grazie per il link sull'evoluzione del changeset, è interessante
Joel

In realtà, rebase è come dire: "riscriviamo tutto il mio lavoro da zero (dall'ultimo maestro), eliminando tutto il mio lavoro precedente". Se stai bene farlo, puoi fare il rebase.
Gioele il
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.