===== 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