2009-11-27 12 views
22

Ho letto alcune domande git qui, ma non riusciva a trovare una risposta a questo:Git: la fusione rami pubblici e privati, mentre mantenendo intatti alcuni file in entrambi i rami

ho una pubblica e una privata filiali in cui voglio consentire a determinati file di divergere.

Questi sono i file di configurazione con password e le mie personalizzazioni locali.

Desidero essere in grado di unire i rami in entrambi i modi: da privato a pubblico e viceversa, ma non voglio che questi file specifici vengano automaticamente uniti.

C'è un modo per configurare git in questo modo? Mi piacerebbe trovare una soluzione automatizzata :) - in modo che la fusione possa essere eseguita come al solito.


EDIT: ecco la soluzione che ha funzionato per me (Grazie a VonC per i consigli su gitattribute)

l'unica cosa inaspettata per me era che "merge protezione" inizia a lavorare solo dopo file hanno divergenti nei due rami, non subito dopo la seguente configurazione è stata applicata

.gitattributes (pista con git, se si desidera condividere questo) o .git/informazioni/attributi:

file1  merge=keepmine 
path/file2  merge=keepmine 

keepmine è nominato direttore di fusione personalizzato che è solo un comando do-nothing chiamato al posto del conducente fusione interna sui file selezionati, che è impostato al di sotto

Quando la fusione dal privato al ramo pubblico faccio di solito git merge --squash private . In questo modo le modifiche private non entreranno nella cronologia git sul ramo pubblico.

.git/config:

#public repository 
[remote "origin"] 
    fetch = +refs/heads/*:refs/remotes/origin/* 
    url = <public repo git url> 

#private repository 
#has to set up with git init and populated with the initial commit to branch mybranch 
[remote "private"] 
    push = +: 
    url = /path/to/local/private/repo 
[merge "keepmine"] 
    name = dont_merge_selected_files 
    driver = echo %O %A %B 
[branch "master"] 
    remote = origin 
    merge = refs/heads/master 

#private branch settings 
[branch "mybranch"] 
    remote = private 
    merge = refs/heads/mybranch 

se c'è un modo per migliorare questo si prega di commentare

risposta

14

Per motivi di sicurezza, è possibile aggiungere uno git attribute (vedere here for an example) per quei file privati.

In questo modo, è possibile definire uno script (un "gestore di unione") che garantirà che il file incluse le informazioni private rimarranno vuote (o con un contenuto pubblico) se unite nel ramo pubblico, mantenendo il contenuto locale se unito al ramo privato.
Significa che è possibile unire/rebase senza pensare a quel file.

+0

funziona, grazie! – Evgeny

+1

Funziona solo quando il file viene modificato in entrambi i rami. Una volta risolta l'unione con keepmine, la seguente fusione nell'altro ramo verrà risolta da recurse. – f3r3nc

2

Conservare le password sotto controllo di versione è l'idea peggiore mai. Hai bisogno di CVS, non di git, per lavorare con file separati. Git come molti altri DVCS moderni che lavorano con l'intero albero, non con file separati.

+0

sicuro, ma la password è il punto minore qui. – Evgeny

3

Un modo per farlo è con git rebase. Mantenendo le tue modifiche private in un paio di commit dalla fine del tuo master, puoi commettere cose pubbliche sul ramo master (o qualsiasi altra cosa tu scelga il tuo ramo di lavoro), e quindi rebase il tuo ramo privato contro il master ogni volta che vuoi aggiornare .

Un altro modo per gestire questo è quello di mantenere i file di configurazione del modello in Git, come ad esempio frobozz.config.template. Nella vostra directory di lavoro, copiate frobozz.config (senza versione) e modificate. Assicurati di eseguire il backup anche della directory di lavoro, se è necessario eseguire il backup delle modifiche locali.

3

Questo sembra funzionare solo se sono stati rilevati conflitti di unione. Mescolando avanti e indietro tra i rami il file viene sovrascritto. A meno che non abbia impostato qualcosa di sbagliato. Ovviamente questo su Windows msysgit git versione 1.6.5.1.1367.

+0

@yoyodyn sì, hai ragione funziona solo su file con conflitti di unione. – Evgeny

+0

potresti anche considerare di unire un solo modo da pubblico a privato, ma in questo caso dovrai rimanere disciplinato - sviluppare solo funzioni pubbliche sul repository pubblico/repository – Evgeny

+0

Quello che ho effettivamente ottenuto sono tre cloni dello stesso repository in diverse posizioni geografiche. Il nostro ufficio lavora nel ramo principale, un altro sito lavora nel ramo di test in modo che il cliente possa fare QA e il terzo è il ramo di produzione in cui si trova il codice attualmente in esecuzione. Abbiamo almeno un file Macros.h che includiamo in molti progetti C++ che contengono valori diversi per le macro a seconda che siano master, test o produzione. Ho cercato di trovare un modo per impedire che il file macros.h venga unito tra i rami. – yoyodyn