Hei!
Koodailen C++:lla pientä kirjastoa OpenGL:n käytön helpottamiseksi. Nyt kuitenkin tuli ongelma, että miten kannattaa yhdistää kaksi otsikko-tiedostoa yhdeksi. Eli minulla on tiedostot vec2.h
, vec3.h
ja vec4.h
, jotka haluaisin yhdistää tiedostoksi nimeltä vec.h
. Miten tämä kuuluu tehdä oikein? Githän ei kai ymmärrä, jos vain kopioin toisen tiedoston sisällön toisen perään, että yhdistin tiedostot, joten samalla kai katoaa muokkaushistoria. Vai onko tämä edes tärkeää yleensä?
Ei se historiatieto tietenkään minnekään katoa. Versionhallinnan idea on pitää versiot tallessa. Voit koska tahansa kaivaa lokeista vec2.h:n ja vec3.h:n ja muidenkin myöhemmistä versioista poistettujen tiedostojen commit-historiat.
Hennkka kirjoitti:
Githän ei kai ymmärrä [..] että yhdistin tiedostot
Olet oikeassa, git ei ymmärrä tiedostojen yhdistämistä tai yhden tiedoston jakamista useampaan. Sellaisen commitin diffissä on paljon toistoa, ja esimerkiksi git blame
ei toimi hyvin.
Käytännössä tämä on harvoin ongelma, koska hyvin pieni osa commiteista tekee tuollaisia muutoksia. Jos joskus tulee tarvetta tutkia yhdistetyin tiedoston historiaa, se onnistuu manuaalisesti. Oletettavasti vec.h:n lisäämän commitin viestistä näkee ilman diffin katsomistakin, että tiedostoja yhdistettiin, ja aiempi historia pitää vaan hakea manuaalisesti käskemällä git log -- vec2.h
tms.
Kiitos. Tiedän kyllä, ettei historia oikeasti mihinkään katoa, vaan että se säilyy vaikka poistaisinkin tiedostoja. Tarkoitin juurikin sitä, että tiedostoon liittyvä muokkaushistoria liittyisi edelleen siihen tiedostoon (niin, että git ymmärtää sen eikä esimerkiksi tallenna samaa tietoa useampaan otteeseen). Tämä ei kuitenkaan ilmeisesti onnistu, joten voinen siis turvallisesti yhdistää tiedostot. En ajatellutkaan, että tässä projektissa tuosta olisi erityisesti haittaa, mutta halusin varmistaa tulevaisuutta varten, että teen asiat oikein.
Voit tehdä esimerkiksi niin, että nimeät uudelleen vec2.h-tiedoston git mv:llä vec.h:ksi ja copypastetat siihen muista tiedostoista lopun sisällön niin, että lopputuloksena on haluamasi yhdistelmä.
Lisäksi kannattaa poistaa vec3.h ja vec4.h gitin omalla rm:llä, jotta versiohistoriaan jää merkintä siitä, että jatkossa tuollaisia tiedostoja ei enää ole olemassa.
Git kyllä älyää sen ihan itsestäänkin, että tiedosto on poistettu.
The Alchemist kirjoitti:
Git kyllä älyää sen ihan itsestäänkin, että tiedosto on poistettu.
Gitille kyllä pitää joka tapauksessa kertoa, minkä tiedostojen muutokset halutaan committiin, ja tiedoston poiston kohdalla git rm on tähän mielestäni luontevampi tapa kuin jokin git add -viritelmä.
touch file3 #empty
git merge-file file1 file3 file2
Huomioi tässä se, että kamat kopioituu file1:seen, tyhjän file3:sen sijasta.
groovyb, tuo on aivan väärä komento tähän tilanteeseen: tuolla ei ole tarkoitus yhdistää eri tiedostoja vaan saman tiedoston eri versioita.
eikös tuossa kysytty, että miten yhdistän tiedostot vec2.h, vec3.h ja vec4.h yhdeksi tiedostoksi (vec.h)? mergettäähän voi toki muutakin kuin saman tiedoston eri versioita. yhdistämistä se kaikki on loppupelissä, oli sitten saman tiedoston eri versiota tai täysin eri. Git tekee tarkistuksia, mutta se lähinnä tarkistaa että onko tiedostonimi yhtään samaan suuntaan. esim file1.h ja file2.h menisi mergestä läpi.
Lopputulos ei ole tuolla komennolla järkevä. Otetaanpa esimerkiksi seuraavat tiedostot:
struct vec2 { int x, y; };
struct vec3 { int x, y, z; };
struct vec4 { int x, y, z, w; };
Komento: git merge-file vec2.h vec3.h vec4.h
Lopputulos:
<<<<<<< vec2.h struct vec2 { int x, y; ======= struct vec4 { int x, y, z, w; >>>>>>> vec4.h };
Onko tässä mielestäsi vec.h, jossa on yhdistettynä tiedot alkuperäisistä tiedostoista?
kokeileppa noin kuin kirjoitin.
touch vec5.h #empty
git merge-file vec2.h vec5.h vec3.h
git merge-gile vec2.h vec5.h vec4.h
groovyb kirjoitti:
kokeileppa noin kuin kirjoitin.
Kokeilisit itse, niin olisi kaikilla helpompaa. Ensimmäisestä nimittäin tulee ihan samanlainen sotku, ja toisesta tulee tietenkin vielä hurjempi sotku, kun jo syötteessä on sotkua.
git merge-file -p vec2.h empty vec3.h > vec2-vec3.h
<<<<<<< vec2.h struct vec2 { int x, y; ======= struct vec3 { int x, y, z; >>>>>>> vec3.h };
git merge-file -p vec2-vec3.h empty vec4.h > vec2-vec3-vec4.h
<<<<<<< vec2-vec3.h <<<<<<< vec2.h struct vec2 { int x, y; ======= struct vec3 { int x, y, z; >>>>>>> vec3.h ======= struct vec4 { int x, y, z, w; >>>>>>> vec4.h };
Sitä paitsi olipa tulos mikä hyvänsä, komento ei mitenkään vastaa alkuperäiseen kysymykseen, joka koski Gitin historian säilyttämistä eikä suinkaan tiedostojen teknistä yhdistämistä. Tämä komento nimittäin vain yhdistää tiedostot teknisesti eikä varsinaisesti liity Gitin versionhallintaan millään tavalla.
Aihe on jo aika vanha, joten et voi enää vastata siihen.