Git: ignora i file durante l'unione


115

Ho un repository chiamato myreposul beanstalkserver remoto .

L'ho clonato sulla mia macchina locale. Creati due rami aggiuntivi: staginge dev. Spinto anche questi rami in remoto.

Adesso:

 local                   remote                   server
 --------------------------------------------------------  
 master  ==> Pushes to  `master`  ==> deployed to `prod`
 staging ==> Pushes to  `staging` ==> deployed to `staging`
 dev     ==> Pushes to  `dev`     ==> deployed to `dev`

Ho un file chiamato config.xmlche è diverso su ogni ramo.

Voglio ignorare questo file solo durante le unioni. Ma voglio che questo sia incluso quando eseguo il checkout o il commit da / al ramo del repository.

Il motivo per cui voglio questo è che abbiamo uno script di distribuzione che estrae (checkout) il ramo specifico e si distribuisce sui rispettivi server. Quindi abbiamo bisogno che il config.xmlfile di quel ramo specifico vada nel server specifico come indicato sopra quando viene distribuito.

Immagino .gitignorenon funzionerà. Quali sono le altre opzioni? Nota che il file ignorato dovrebbe far parte del checkout e del commit, il che è importante. dovrebbe essere ignorato solo durante le unioni.

Grazie!


Nella sua modalità predefinita, git pull è l'abbreviazione di git fetch seguito da git merge FETCH_HEAD. Quindi affermi un tipo di conflitto tra loro.
zzk

Bene, direi, è il checkout. Non tirare. Aggiornerò la domanda per essere chiari.
Kevin Rave


2
hai mai trovato una soluzione a questo? Gli attributi git sono utili solo nel caso in cui il file abbia conflitti tra i rami che vengono uniti, quindi non è sempre sufficiente.
pvinis

hai esaminato i link simbolici (non seguiti da git) o ​​anche hard link per il salvataggio?
Frank Nocke

Risposte:


94

Ho superato questo problema utilizzando il comando git merge con l' --no-commitopzione e quindi ho rimosso esplicitamente il file di staging e ignorato le modifiche al file. Ad esempio: diciamo che voglio ignorare le modifiche a myfile.txtprocedere come segue:

git merge --no-ff --no-commit <merge-branch>
git reset HEAD myfile.txt
git checkout -- myfile.txt
git commit -m "merged <merge-branch>"

Puoi inserire le istruzioni 2 e 3 in un ciclo for, se hai un elenco di file da saltare.


2
Aggiungerei "--no-ff" se si desidera che un file non venga sovrascritto quando l'unione avviene nella strategia di avanzamento rapido.
Ilia Shakitko

1
quindi cosa fa git reset HEAD myfile.txtesattamente? In che modo aiuta con il nostro obiettivo qui?
Kid_Learning_C

Come metti le linee 2 e 3 in un ciclo?
AndroidDev

52

Ho finito per trovare git attributes. Provandolo. Finora funzionante. Non ho ancora controllato tutti gli scenari. Ma dovrebbe essere la soluzione.

Strategie di unione: attributi Git



1
Ecco il collegamento corretto per la sezione delle strategie di unione dei documenti degli attributi git: git-scm.com/book/en/v2/…
Adrian Laurenzi

3
Ho trovato questo ben spiegato in un articolo medium.com/@porteneuve/…
ShawnFeatherly

10
Questo sembra essere un problema se non ci sono conflitti? I file verranno ancora uniti?
Brett

18

.gitattributes - è un file a livello di root del tuo repository che definisce gli attributi per una sottodirectory o sottoinsieme di file.

È possibile specificare l'attributo per dire a Git di utilizzare diverse strategie di unione per un file specifico. Qui vogliamo preservare l'esistente config.xmlper la nostra filiale. Abbiamo bisogno di impostare l' merge=oursad config.xmldi .gitattributesfile.

merge=ours dì a git di usare il nostro file (ramo corrente), se si verifica un conflitto di unione.

  1. Aggiungi un .gitattributesfile al livello principale del repository

  2. Puoi impostare un attributo per confix.xml nel .gitattributesfile

    config.xml merge=ours
    
  3. Quindi definisci una nostra strategia di fusione fittizia con:

    $ git config --global merge.ours.driver true
    

Se unisci stagform devbranch, invece di avere l'unione in conflitto con il file config.xml, il file config.xml di stag branch conserva la versione originariamente disponibile.


16
Ma cosa succede se non c'è conflitto? Come mantenere sempre un determinato file durante l'unione?
Igor Yalovoy

2
@IgorYalovoy: Se non c'è conflitto ... beh, questo è un po 'complicato in quanto funziona effettivamente dagli ID hash, ma: se config.xmlè completamente invariato dalla base di unione a una versione di punta di ramo, Git prende solo la versione modificata, senza guardando l' merge.ours.driverambiente. Quindi hai ragione ad essere preoccupato.
torek

1
copia-incolla da Git Docs: Merge Strategies - Git attributes. Link
kyb

Questo metodo si traduce in "merge commits" ogni volta che FYI.
rsmets

2
"nostro" sembra essere un nome arbitrario per la nuova strategia introdotta. L'ho trovato confuso, perché theirsè una strategia di unione incorporata. Ma sembra che si possa scrivere <pattern> merge=foo, quindi git config --global merge.foo.driver true, e funzionerà allo stesso modo.
Kyle Strand

8

Puoi iniziare usando git merge --no-commite quindi modificare l'unione come preferisci, ad esempio annullando lo stage config.xmlo qualsiasi altro file, quindi eseguire il commit. Sospetto che vorresti automatizzarlo ulteriormente usando gli hook, ma penso che varrebbe la pena farlo manualmente almeno una volta.


2
Non git attributesoffrire alcuna soluzione diretta? Non sono in grado di capirlo. git-scm.com/book/en/…
Kevin Rave

4

Potresti usare .gitignoreper tenere config.xmlfuori dal repository, e quindi usare un hook post commit per caricare il config.xmlfile appropriato sul server.


1
So che è una specie di hack. Sto cercando di trovare una soluzione pulita. Che mi dici di git attributes. Qualche idea su come funziona? Non sono in grado di capirlo. git-scm.com/book/en/…
Kevin Rave

1
Non ne ho sentito parlare, sto cercando di applicare l'attributo merge = ours, sembra promettente.
tlehman

1
Gli attributi di Git sono fantastici! Puoi anche dire a git come diffondere file non di testo, quindi puoi usare pdf2text per diffondere PDF!
tlehman

2

Esempio:

  1. Hai due rami: master,develop
  2. Hai creato il file nel developramo e desideri ignorarlo durante la fusione

Codice:

git config --global merge.ours.driver true
git checkout master
echo "path/file_to_ignore merge=ours" >> .gitattributes
git merge develop

Puoi anche ignorare i file con la stessa estensione

ad esempio tutti i file con .txtestensione:

echo "*.txt merge=ours" >> .gitattributes

1

Qui git-update-index - Registra il contenuto del file nell'albero di lavoro nell'indice.

git update-index --assume-unchanged <PATH_OF_THE_FILE>

Esempio:-

git update-index --assume-unchanged somelocation/pom.xml


È bello quando si spinge ma si lamenta ancora quando il tiro potrebbe sovrascrivere il file.
Rolf

1
hai provato ad aggiungere la tua voce di file nel file .gitignore. @Rolf
Sireesh Yarlagadda
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.