Creazione di un repository alternativo di tipo spin-off, in grado di recuperare gli aggiornamenti dal repository principale (noto anche come fork del proprio repository)

2

Dal momento che sto meglio con le rappresentazioni visive, sostanzialmente voglio fare questo:

Hofattoqualchericercaehopotutotrovaresoloquesto Git: Branch o Fork? E questo Un modello decente di branching git per prodotti che dovrebbe accompagnare la versione di un altro prodotto di terze parti (e pro e contro di una proposta)

Ma mentre una situazione simile, quelle domande non hanno avuto alcuna risposta concreta.

Iniziale, sembrava facile come creare un fork, ma sembra che non si possano biforcarsi i propri repository.

Ho quindi pensato che "Fancy House" potesse semplicemente essere un ramo eterno, ma in diverse occasioni le persone hanno sconsigliato questo, dicendo che i rami sono destinati allo sviluppo temporaneo e dovrebbero sempre essere usati per fondersi nuovamente nel ramo principale. Inoltre, i rilasci sono difficili da gestire e il fatto di avere un ramo "vero padrone" e "padrone di casa fantasioso" potrebbe causare ulteriore imbarazzo e una possibile confusione (e solo a uno di essi è consentito essere veramente il ramo predefinito).

Ho eseguito un rapido test dei cosiddetti "submodules", ma sembra che crei una cartella all'interno del repository (quindi "Fancy_House / House_Project / House / Lights.txt"), che non funziona e non funziona molto la struttura delle cartelle (non è possibile creare "New & Fancy Lights.txt"), e aggiunge anche i principali file di repository e così via, ulteriore intasamento del repository di spin-off con cose non necessarie.

Allo stesso modo, una richiesta di pull da un repository a un repository diverso farebbe anche il trucco; ma non è possibile farlo neanche.

Naturalmente, non è assolutamente impossibile copiare semplicemente manualmente le modifiche e commettere dal progetto principale allo spin-off; ma ciò significa che tutti i commit e la cronologia vengono persi e richiede un intervento manuale, il che può essere particolarmente fastidioso se vengono aggiunte molte piccole correzioni al ramo di sviluppo. Forse usare la funzione di sottomodulo solo così è proprio lì in faccia e non è necessario cambiare i repository ... soluzione ancora molto fastidiosa.

Tendiamo a utilizzare esclusivamente GitHub desktop o GitKraken, se questo aiuta affatto.

Potrei essere completamente ignaro di qualcosa di ovvio; è per questo che sto chiedendo qui.

    
posta Araxiel 03.11.2017 - 10:56
fonte

2 risposte

2

Ho intenzione di spiegare alcuni sfondi Git per comprendere perché le forcelle longeve sono così difficili.

In Git, una versione / commit rappresenta uno snapshot / stato del codice sorgente. Non rappresenta un insieme di modifiche. Pertanto, non esiste un modo elegante per tracciare diverse "edizioni" o "varianti" del tuo software.

Un ramo e un fork / repository separati sono più o meno la stessa cosa per quanto riguarda Git. All'interno della storia di un repository Git, nessuno di questi concetti esiste: ci sono solo commit. In particolare, un ramo è solo un'etichetta mobile che punta a un commit. Pertanto, mentre i rami vengono spesso utilizzati per organizzare diversi thread di sviluppo, non rappresentano tali cambiamenti. Invece, il commit HEAD di un ramo rappresenta solo lo stato attuale di sviluppo e il commit contiene qualsiasi cronologia che ha portato a quello stato.

L'unione tenta di unificare lo stato di due (o più) commit / snapshot del codice sorgente. Innanzitutto, Git cerca l'ultimo antenato comune di tutti i commit principali, quindi calcola i differenziali tra la testa di ciascun genitore e l'antenato comune. Quindi cerca di unire entrambe le differenze. Se non c'è conflitto, Git applica le modifiche e crea un nuovo commit con questo stato.

Più modifiche ci sono, più conflitti di fusione ottieni e più diventa difficile l'unione. Pertanto, la fusione anticipata è fondamentale per mantenere il carico di lavoro gestibile. Ma questo significa anche che dovresti unire due rami in entrambe le direzioni. Altrimenti, le modifiche non raggruppate continuano ad accumularsi su un ramo e dovrai risolvere gli stessi conflitti più e più volte su ogni unione:

     1---2---3---4---5  fork
    /       /       /
---a---b---c---d---e  master

Nell'esempio precedente, c'è un ramo master e un fork longevo.

  • Commit 3 è un'unione con merge-base a . Questo unisce le modifiche a..c con a..2 e registra un nuovo commit 3 . Relativo al fork, questa unione rappresenta il modo in cui sono state applicate le modifiche a..c . Poiché i conflitti di unione potrebbero essere stati risolti, potrebbe non essere effettivamente uguale alle modifiche a..c .

  • Commit 5 è un'altra unione, questa volta con la base merge c . Questo unisce le modifiche c..e con c..4 . Si noti che il commit 3 (che rappresenta il modo in cui sono stati risolti i conflitti precedenti tra i rami) fa parte di uno solo di questi rami. Laddove i due rami differivano durante l'unione 3 , probabilmente si differenziano ancora durante l'unione 5 , quindi dovrai risolvere quelle differenze / conflitti di nuovo .

In effetti, ogni unione viene trasferita alla successiva unione e lo sforzo aumenta. A meno che non si fondano in entrambe le direzioni. Ma ciò va contro il tuo obiettivo di avere Fancy stuff solo nel fork.

(Esistono approcci alternativi come rebasing e cherry picking che applicano un insieme di modifiche in cima a un commit diverso. Perché questo guarda solo alle modifiche introdotte da quei commit e non all'istantanea del codice sorgente che rappresentano, questo soffre meno dai conflitti.Tuttavia, questo non unisce le cronologie Git ma registra commit completamente nuovi, non correlati per rappresentare il nuovo stato del codice sorgente (riscrittura della cronologia). E se la forcella si discosta troppo, il diff potrebbe non "adattarsi" più al codice sorgente , che richiede di applicare ogni modifica manualmente.)

Quindi Git non è in grado di aiutare qui. Ci sono due approcci:

Uno è quello di visualizzare una variante del software come una serie di patch l'una sull'altra. La forcella non mantiene il risultato finale di tali modifiche, ma solo le differenze che rappresentano queste modifiche. Il repository originale potrebbe quindi essere un sottomodulo. Ogni volta che l'originale cambia, si modificano le patch in modo che continuino a essere adattate. All'interno di Git, potrebbero anche esserci alcuni commit che rebase continuamente in cima al master originale, ma che perde la cronologia delle tue modifiche. Questo è appropriato solo per modifiche chirurgiche molto piccole che non possono essere unite nel repository originale. Mantenere le patch sarebbe opportuno per piccole estensioni o correzioni di bug che non è possibile restituire.

L'approccio migliore è quello di risolvere il problema a livello di architettura software, non a livello Git. Invece di apportare modifiche dirette al software, rendere il software così configurabile che le modifiche possano essere implementate come estensioni. Parole chiave pertinenti: Principio aperto / chiuso, Alterna funzionalità, Iniezione di dipendenza, Modelli di progettazione, Plugin. Quindi, il progetto principale espone i punti di estensione in modo da poter inserire le modifiche di fantasia, oppure hai letteralmente una singola base di codice in cui la modalità fantasia / non-fantasia può essere selezionata al momento della compilazione o in fase di esecuzione.

    
risposta data 03.11.2017 - 20:52
fonte
3

I then thought "Fancy House" could simply be an eternal branch, but on multiple occasions people have advised against that

Le altre soluzioni sono essenzialmente solo mantenendo un ramo eterno in un repository separato e non sono meno consigliabili. Hai letto ciò che la gente di solito consiglia di fare invece di rami eterni?

Vuoi modificare il tuo software così al momento della costruzione o della configurazione puoi creare una casa normale o una casa di lusso, creando moduli ben definiti che condividono il maggior numero possibile di codice.

Una filiale potrebbe essere una valida soluzione a breve termine se la tua versione iniziale era mal progettata e hai bisogno di ottenere qualcosa, ma mantenere filiali a lungo termine è un lavoro molto incline agli errori.

    
risposta data 03.11.2017 - 12:52
fonte

Leggi altre domande sui tag