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.