===== Přechod na nové úložiště Redmine/git ===== ÚFALí server Redmine je na adrese https://redmine.ms.mff.cuni.cz/projects. Ondra na něj v říjnu 2012 přestěhoval podstatnou část repozitáře StatMT z svn/trac (https://svn.ms.mff.cuni.cz/trac/statmt). Konkrétně jsou tu teď projekty [[https://redmine.ms.mff.cuni.cz/projects/ufal-smt-playground|ufal-smt-playground]] a [[https://redmine.ms.mff.cuni.cz/projects/eman|eman]] (na něj se z playgroundu odkazuje jako na podmodul). Pro vybalení hřiště Ondra doporučil studentům následující příkaz. Předpokládám, že studenti, neznajíce Ondrovo heslo, to museli volat bez toho ''ondrej.bojar@'' na začátku a získali nějaký read-only přístup. A já na rozdíl od nich můžu použít daniel.zeman a získám přístup i pro zápis. git clone https://ondrej.bojar@redmine.ms.mff.cuni.cz/ufal-smt-playground.git jmeno_pracovni_kopie # Raději pracovat na 64bitovém stroji kvůli kompilacím. ssh sol12 cd /net/cluster/TMP/zeman git clone https://daniel.zeman@redmine.ms.mff.cuni.cz/ufal-smt-playground.git redplayground Eman jako podmodul se asi neaktualizuje sám. Nějakou verzi k nějakému datu zřejmě získám automaticky s hřištěm, ale pokud chci mít jistotu, že budu mít ten aktuální, můžu/měl bych? udělat cd redplayground git submodule init git submodule update Další Ondrova doporučení (ale to druhé, vizualizace commitů, bude asi fungovat jen v ixech): git svn crashcourse gitk -a Dokumentace ke gitu je například [[http://git-scm.com/documentation|tady]]. * ''git clone '' ... naklonovat existující repozitář (dělá se na začátku podobně jako ''svn checkout'', ale sémantika není stejná) * ''git status'' ... v jakém stavu jsou jednotlivé soubory? (untracked / committed / modified / staged) * ''git add '' ... zkopírovat změněný soubor do staging oblasti nebo zahrnout do verzování dosud neverzovaný soubor (rovnou se dostane do staging oblasti) * ''git reset HEAD '' ... vyřadit soubor ze staging oblasti * ''git checkout -- '' ... zapomenout změny v pracovní kopii a vrátit se k verzi souboru uložené v repozitáři * ''git commit -m 'log''' ... uložit soubory ze staging oblasti do (lokálního!) repozitáře; na vzdálený server to pořád nemá vliv * ''git commit -a'' ... přeskočit stageování a uložit i soubory, které už sledujeme, změnily se, ale nejsou ve staging oblasti * ''.gitignore'' ... soubor se jmény či šablonami jmen souborů, které se nemají verzovat a nemají se ani hlásit jako neverzované * ''git diff'' ... co jsem změnil, ale ještě nezkopíroval do staging oblasti * ''git diff --cached'' ... co jsem změnil a zkopíroval do staging oblasti * ''git log'' ... historie uložených verzí * ''gitk'' ... grafický program, který vizualizuje výstup ''git log'' * ''git rm '' ... odstranit soubor z pracovní složky a říct gitu, že ho má přestat sledovat * ''git rm --cached '' ... přestat sledovat soubor, ale jeho kopii v pracovní složce ponechat * ''git mv '' ... přejmenovat nebo přesunout soubor * ''git remote -v'' ... zobrazit názvy nakonfigurovaných vzdálených repozitářů včetně jejich URL. "origin" je ten, ze kterého jsme se naklonovali. * ''git remote add '' ... přidat vzdálený repozitář, se kterým se můžeme synchronizovat * ''git fetch origin'' ... stáhnout nové změny ze vzdáleného repozitáře origin. Stáhnou se jako nová větev a neslijí se s mou aktuální větví, dokud to neudělám ručně. * ''git pull origin'' ... stáhnout nové změny a pokusit se je automaticky slít s mými. Musíme mít nakonfigurováno automatické sledování vzdálené větve. Ale u originu to tak defaultně je. * ''git push origin master'' ... odeslat změny v mé hlavní (master) větvi zpět na server, ze kterého jsem se naklonoval (origin) * ''git remote show origin'' ... zobrazit informace o stavu vzdáleného repozitáře ve vztahu ke mně * ''git branch testing'' ... vytvořit novou větev testing (rozvětvení bude na aktuálním commitu), ale zatím do ní nepřepínat (na aktuální větev ukazuje ukazatel HEAD) * ''git checkout testing'' ... přepnout se do existující větve testing a vybalit její soubory do pracovní složky * ''git checkout -b testing'' ... zkratka: vytvořit novou větev a hned se do ní přepnout * ''git checkout -b testing dfcb57a2'' ... vrátit se k revizi (commitu) s kódem ''dfcb57a2'', na něm vytvořit novou větev ''testing'' a hned se do ní přepnout. Při návratu k revizi, která současně není na konci nějaké větve, se doporučuje založit novou větev, aby HEAD vždy ukazovalo na větev a ne na pouhou revizi. Předchází se tím případným problémům, ke kterým může dojít, jestliže nad touto revizí provedeme nové změny: fakticky by vznikla nová větev, ta by ale neměla název a systém by mohl usoudit, že ji smaže, protože není potřeba. * ''git merge testing'' ... slít větev testing s mou aktuální větví * ''git branch -d testing'' ... zrušit větev, kterou už nepotřebujeme, protože jsme ji slili s jinou * ''git checkout -b serverfix origin/serverfix'' ... založit větev serverfix na základě nové větve, kterou jsme získali fetchem ze serveru origin, a přepnout se do ní. Současně tím vzniká vztah mezi novou lokální a vzdálenou větví. Tento vztah se vezme v potaz při synchronizaci pomocí push a pull. * ''git push origin :serverfix'' ... smazat větev serverfix na serveru origin ("na mé straně před dvojtečkou vezmi nic a udělej z toho aktuální stav větve serverfix na straně serveru") * ''git rebase '' ... práce se záplatami (patches) je jiný způsob, jak slít dvě větve. Výsledek je stejný, ale historie je přímější, samostatná větev v ní nebude vidět. Rebase přehraje na větvi base změny provedené ve větvi topic. ALE: Nemají se rebaseovat commity, které už jsme odeslali do veřejného repozitáře. Rebasing vyrábí nové commity, které mají stejný obsah, ale nejsou stejné. Pokud spolupracuji s někým jiným, kdo měl v ruce ty předchozí, nyní zavržené commity, vznikne binec, který budeme obtížně dávat dohromady. ===== Strategie přechodu ===== * Získat stav ve chvíli, kdy Ondřej stěhoval hřiště pod git. Čili vybalit nějaký historický stav gitu. Této verzi bude odpovídat nějaký historický stav mého svn. * Vyrobit si větev dansvn (v gitu) a nějak do ní promítnout aktuální stav v mém svn. * Přepnout se do Ondřejovy (hlavní) větve a vybalit (pull) její aktuální stav (HEAD). * Teď už teoreticky kdykoli můžeme obě větve opět slít. ALE! * Já ještě potřebuju zařídit, aby moje pracovní kopie svn začala být pracovní kopií větve dansvn v gitu, aniž bych musel její obsah kopírovat (jsou tam ty obří neverzované hardlinky, které by se kopírováním rozpojily a zabíralo by to ještě více místa). * Mějme dvě složky: gitplayground a svnplayground. Obě jsou pracovní kopií téže verze hřiště, ale jedna je navázaná na tuto verzi v gitu a druhá na odpovídající verzi v svn. Složka gitplayground kromě toho obsahuje už jen případné pomocné soubory gitu a nic jiného. Složka svnplayground obsahuje pomocné soubory svn a navíc neverzované podsložky-bumbrlíčky. * Neverzované bumbrlíčky nechceme stěhovat, ty musí zůstat na místě. Proto musíme kolem nich uklidit, aby se k nim mohl nastěhovat git. Odstraníme všechny verzované podsložky svnplayground, všechny verzované soubory a složku ''.svn'' s pomocnými soubory svn. * Veškerý obsah složky gitplayground, včetně pomocných souborů git, rekurzivně zkopírujeme do složky svnplayground vedle neverzovaných bumbrlíčků. * Ověříme, zda tato kopie funguje a ví, že je pracovní kopií repozitáře git. * Přejmenujeme tuto kopii na ''playground''. Složku ''gitplayground'' můžeme smazat. * Vlastní Eman byl na podzim přesunut do samostatného repozitáře, aby bylo možné ho někomu poskytnout bez vazeb na strojový překlad. Po nějakou dobu byl v repozitáři Playgroundu vložen jako submodul, ale přineslo to víc škody než užitku, takže nakonec byl vykopnut úplně. Nyní tedy musíme někde zvlášť vybalit projekt Eman, najít v něm to hlavní, tedy skript ''eman'', a zařídit, abychom ho měli v cestě, když pracujeme s hřištěm. # Zkusit si, zda lze repozitář git jen tak kopírovat a on nadále funguje. ssh sol12 cd /net/cluster/TMP/zeman cp -R redplayground gitplayground cd gitplayground # Sesynchronizovat můj git. Tím dostanu všechny revize až do současnosti. git pull origin # Vrátit se mezi commity přenesené z svn k poslednímu mému. # Označit to jako novou větev dansvn. git checkout -b dansvn dfcb57a2 # Někde vedle si vyrobit čistý checkout nejnovější verze v svn, bez těch neverzovaných bumbrlíčků. cd .. svn --username zeman checkout https://svn.ms.mff.cuni.cz/svn/statmt/trunk cleansvnplayground # Zkopírovat poslední verze souborů v relevantních složkách z svn do gitu. cd cleansvnplayground cp -R playground ../gitplayground cp -R scripts ../gitplayground cp -R src ../gitplayground cd ../gitplayground # Odstranit pomocné složky .svn ze všech složek ve zkopírovaném stromu. find -type d -regex '.*\.svn' -print -exec rm -rf '{}' \; # Podívat se, které soubory se změnily a které mám teď navíc. # Těch navíc se Ondřej při stěhování zbavil a já je chci nejspíš taky ručně smazat. # Výjimkou jsou soubory, které jsem si do svn přidal sám a chci je zachovat. Ty nemazat, svezou se s git add. git status rm ... # Označit všechny změny v existujících souborech v svn, + případně přidané nesmazané soubory, ke commitu. git add . # Zapamatovat si změny a uložit je v místním repozitáři. git commit -m 'Danovy změny v svn po odštěpení git verze.' # Vyrobit protějšek nové větve i na serveru. git push origin dansvn # Slít změny z obou větví. Součástí musí být vyřešení konfliktů. # V tomto případě byl navíc soubor scripts/eman vyčleněn do samostatného repozitáře git, to ošetřil Aleš. # Po vyřešení konfliktů promítnout změnu na server. git checkout master git merge dansvn git push origin master # Po slití už větev dansvn nepotřebujeme, smazat u nás i na serveru. # (Neměníme tím rozvětvenou historii, pouze zapomínáme pojmenovanou záložku, která do ní ukazuje.) git branch -d dansvn git push origin :dansvn # Naroubovat nové hřiště verzované gitem na to staré, které navíc obsahuje složky s pokusy. cd ../statmt/playground # Chceme zachovat neverzované složky s experimenty. Jejich název začíná "s.". # Vše ostatní je buď verzované, nebo jsou to pomocné soubory, které lze vyhodit. for i in `ls -A1 | grep -vP '^s\.'` ; do rm -rf $i ; done cd .. rm -rf .svn addicter addicter-experiments joshua-scripts papers perl projects scripts src cp -R ../gitplayground/.git ../gitplayground/scripts ../gitplayground/src ../gitplayground/.git* . cd playground cp -R ../../gitplayground/playground/* . cp ../../gitplayground/.gitignore . cp ../../gitplayground/.vimrc . cd .. git status # Vybalit Emana, je teď v samostatném repozitáři. cd /home/zeman/nastroje git clone https://daniel.zeman@redmine.ms.mff.cuni.cz/eman.git # Nakonec si dát do .bashrc, resp. u mne do path.pl cestu # /home/zeman/nastroje/eman/bin vim ~/bin/path.pl