È sbagliato git spingere i rami della forza?


11

Quando lavoro su un ramo di una funzione, tendo a voler ripulire i commit nel ramo usando un rebase interattivo prima che il mio lavoro venga rivisto e integrato nel ramo principale.

Durante lo sviluppo della funzione, desidero trasferire il mio lavoro intermedio al repository remoto come misura di backup. Vale a dire quando il mio disco rigido si arresta in modo anomalo, non voglio perdere l'intero ramo delle funzionalità.

Tuttavia, questo porta al fatto che spesso devo fare un git push --forcerepository remoto dopo un rebase, un'azione che è generalmente disapprovata. O come dice la pagina github collegata:

Poiché la modifica della cronologia dei commit può rendere le cose difficili per tutti gli altri che utilizzano il repository, è considerato una cattiva pratica reimpostare i commit quando si è già passati a un repository.

Esiste una politica (generalmente accettata) che risolve questo conflitto?

Perché questo non è un duplicato di Git "Golden Rule of Rebasing" è così essenziale?

La mia domanda qui chiede una politica per risolvere il conflitto tra il voler fare il backup del tuo lavoro nel repository remoto e il riassegnare il tuo lavoro , mentre l'altra domanda cerca di negare l'esistenza di un conflitto e chiede perché alcune persone pensano che il conflitto esista affatto, e quindi chiede perché "è essenziale" non spingere i ribassi di forza?



1
@gbjbaanb se si effettuano commit WIP, un rebase è molto utile per evitare di avere molti commit per un singolo giorno di lavoro. Faccio spesso commit per piccoli cambiamenti, quindi ho l'opzione "annulla a uno stato che ricordo" se necessario - la maggior parte di questi sono irrilevanti / disturbano la storia principale del repository (motivo per cui rebase è così utile).
Enderland

1
@gbjbaanb Questa è una questione di opinione, penso. Molti team usano una strategia di rebasing per mantenere pulita la loro storia.
Chiel ten Brinke

1
@enderland tutti vogliono una bella storia, è ancora la cosa sbagliata (e pericolosa) da fare, come mostrato dal link. Torvalds non avrebbe mai dovuto inserirlo, avrebbe dovuto consentire invece che i commit fossero "compressi" sul display.
gbjbaanb,

1
@gbjbaanb ma ... non l'ha fatto, e quindi dobbiamo lavorare con quello che abbiamo. Per me è molto più utile disporre di un singolo commit sul ramo master invece di oltre 30 commit individuali e incrementali da ciascun ramo di feature. Ma credo che tutti avranno un flusso di lavoro diverso ...
Enderland,

Risposte:


5

La domanda chiave da porsi:

  • Mantieni il tuo ramo remoto dopo la fusione nel master?

Se si elimina il ramo della funzionalità remota dopo l'unione in master, si sta già perdendo la cronologia. Supponendo che tu schiaccia / rinnovi il ramo prima di fare la tua unione / PR perdi questa storia. Tutta la tua spinta forzata in questo caso ti consente di usare github come backup.

La situazione in cui vorresti conservare la cronologia e non forzare la spinta è se il tuo ramo remoto persiste dopo essere stato unito e non esiste solo per un periodo di tempo temporaneo.

Suppongo che mi stai chiedendo se avrei mantenuto il ramo non basato? No, AFAIC. Tuttavia, la spinta forzata potrebbe teoricamente comportare la perdita di commit da parte di altri utenti che hanno spinto nello stesso ramo

Sembra che tu abbia più persone che spingono contemporaneamente verso quel ramo. Questo significa che si fanno a cuore la storia sul ramo.

Quello che potresti fare invece per il tuo lavoro intermedio è creare un fork di quel ramo. Puoi spingerlo fino a questo punto e poi riassegnare tutti i tuoi commit in un unico commit prima della fusione, quindi quando li unisci nel tuo ramo delle funzioni, hai solo 1 commit (con la cronologia rinnovata dell'intero ramo).


"Mantieni il tuo ramo remoto dopo la fusione di nuovo in master?" Suppongo che mi stai chiedendo se avrei mantenuto il ramo non basato? No, AFAIC. Tuttavia, la spinta forzata potrebbe teoricamente comportare la perdita di commit da parte di altri utenti che hanno spinto nello stesso ramo.
Chiel ten Brinke,

@ChieltenBrinke Ho modificato un po 'questo. FYI
enderland

Penso che il fork come misura per prevenire la distruzione si impegni quando la forzatura a spinta è in realtà un ottimo suggerimento. Ma AFAIK non è proprio un concetto git, e per farlo è necessario un wrapper di servizio (come github). Ho ragione a riguardo? O forse sbaglio il tuo uso del termine "biforcazione" solo per creare un ramo separato?
Chiel ten Brinke

@ChieltenBrinke bene puoi realizzare la stessa cosa in vari modi. Se il ramo della funzione si trova nel repository remoto, è possibile fork il repository e disporre della versione di quel ramo. E quindi unisci quel ramo nel tuo ramo remoto dopo aver commesso gli schiacciamenti. Oppure puoi semplicemente creare un altro ramo locale (forse featurebranch-local) e quindi fare dev attivo su quel ramo, con tutte le commit che vuoi. Una volta che vuoi unire, schiaccia quei commit e poi uniscili nella funzione. Fondamentalmente semplicemente facendo dev in un ramo temporaneo effettivo e quindi schiacciando / fondendo nella tua funzione.
Enderland

Supponendo che il fork di un repository non sia possibile perché non si utilizza github, si dovrebbe lavorare con un develop-featureramo "privato" . Naturalmente la riservatezza è puramente per convenzione e non applicata da nulla, ma può essere inserita in una politica, specialmente se vengono introdotte alcune convenzioni di denominazione delle filiali. (Forse sono troppo ansioso in questo momento, forse no :) La combinazione con --force-with-leasenon può far male, anche se non dovrebbe essere invocata, come sottolineato nell'altro mio post.
Chiel ten Brinke

3

Sto elencando alcune possibilità qui che mi vengono in mente.

Rifare sempre su un nuovo ramo

Quando si dispone di un ramo disordinato some-feature, rifarlo su un nuovo ramo. Per esempio

$ git checkout -b some-feature-rebase
$ git rebase -i master # etc..

Quindi hanno some-feature-rebaserivisto e integrato.

Problema: un grande svantaggio qui è che, a rigor di termini, è necessario un nuovo ramo per ogni rebase. (Potresti avere più rebase se apporti modifiche dopo una revisione del codice, ad esempio)

Uso git push --force-with-lease

Ho appena saputo git push --force-with-leasedell'alternativa agit push --force , che

rifiuta di aggiornare un ramo a meno che non sia lo stato che ci aspettiamo; cioè nessuno ha aggiornato il ramo a monte.

Problema : questo sembra migliorare direttamente sulla situazione in cui usiamo solo --force, ma ha ancora alcuni avvertimenti, in particolare quando faccio un git fetchinvece di un git pull, che aggiorna i nostri rami a monte locali, inducendo --force-with-leasea pensare che non sono state apportate modifiche non combinate sul telecomando ramo.

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.