Come lavorare su git local branch, usando pull per aggiornare ma senza push

2

Sto lavorando su una copia locale di un grande progetto su github. La maggior parte delle modifiche apportate sono modifiche per adattare l'applicazione a un caso d'uso specifico, in quanto tali non saranno accettate dal manutentore. Sto cercando di capire il modo migliore in cui posso aggiornare regolarmente il mio ramo locale con le modifiche apportate al ramo principale, ma senza sovrascrivere le modifiche che ho apportato. Ad esempio, potrei usare:

git checkout my_branch git merge master

Quindi spingere mybranch su un master di progetto separato su github

Se questo è il modo consigliato di avere la propria copia di un progetto git con aggiornamenti regolari da un progetto principale?

    
posta Don Smythe 03.02.2017 - 06:16
fonte

2 risposte

5

Non esiste un modo semplice per ottenere aggiornamenti da upstream mantenendo le modifiche locali al code base. A un certo punto, ci saranno probabilmente dei conflitti, e dovrai risolverli manualmente.

La ridefinizione delle modifiche nello stato corrente di upstream non è una soluzione praticabile a lungo termine, specialmente se le tue modifiche sono più di una manciata di commit. Poiché le tue adattazioni non vengono mai unite nel repository upstream, ogni volta che esegui il rebase dovrai rebase di tutto ciò che hai fatto. Ciò significa risolvere gli stessi conflitti ancora e ancora. Rebasando anche la cronologia "riscrive", il che significa che unire il ramo tuo diventa assolutamente impossibile.

Se è necessario mantenere il flusso di lavoro corrente, potrebbe essere meglio impedire al ramo principale di tracciare qualsiasi ramo a monte e gestire tutte le unioni manualmente, in modo efficace con i comandi suggeriti. Un git pull upstream master è quasi uguale a git fetch upstream; git merge upstream/master . L'unione manuale ti darà un maggiore controllo. L'unione anziché la ridistribuzione riduce anche il carico di lavoro a lungo termine.

Tuttavia, Git non è uno strumento adatto per gestire diverse modifiche di una base di codice. Il termine "controllo di versione" è leggermente fuorviante qui. Questo non è perché Git è uno strumento cattivo, ma perché questo è un problema intrinsecamente difficile. Questo problema diventa molto più semplice se la base di codice originale è sufficientemente configurabile in modo da non dover modificare il codice per implementare le modifiche - in OOP speak, dovrebbe obbedire al principio open / closed .

Anche se gli adattamenti specifici del problema non hanno alcun valore per il progetto originale, il che lo renderebbe sicuramente più configurabile. La migliore strategia a lungo termine è quindi apportare piccole modifiche al codice originale per renderlo più configurabile. Ciò potrebbe significare l'impostazione di alcune opzioni in un file di configurazione, l'aggiunta di un sistema di plugin, hook e callback per determinati eventi o l'introduzione di un'iniezione di dipendenza. Una volta che tali modifiche sono nel progetto upstream, è possibile implementare le modifiche senza dover toccare il codice upstream, che riduce significativamente il carico di manutenzione. I tuoi plug-in specifici per il problema vivrebbero in un progetto completamente separato.

Se il progetto upstream non accetta le tue modifiche, mantenere un piccolo set di patch come livello di compatibilità è ancora meglio che apportare tutte le modifiche direttamente nel codebase upstream.

    
risposta data 03.02.2017 - 10:46
fonte
1

Potresti

  • Metti da parte le tue modifiche nella directory di lavoro locale, fai un tiro a git, quindi applica le tue mosse. Ciò manterrà aggiornate le tue modifiche, ma i tuoi rami divergeranno non appena effettuerai un commit. Lo consiglio solo se è necessario effettuare un aggiornamento tra commit.

    git stash && git pull origin master && git stash apply. 
    
  • Esegui un git pull --rebase anziché una normale estrazione basata su unione. Un rebase troverà il primo antenato comune tra il ramo master remoto e i tuoi commit locali, applica i commit remoti, quindi applica i commit locali su di essi.

Potresti imbatterti in frequenti conflitti, ovviamente, nel tuo caso d'uso specifico (poiché dici che il manutentore originale del ramo remoto non ha alcun interesse in esso e potrebbe felicemente sovrascrivere le tue modifiche), ma è un modello molto utile e ha il vantaggio di mantenere la cronologia dei commit rigorosamente lineare.

    
risposta data 03.02.2017 - 07:58
fonte

Leggi altre domande sui tag