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 ufal-smt-playground a 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 tady.
git clone <url>… naklonovat existující repozitář (dělá se na začátku podobně jakosvn checkout, ale sémantika není stejná)git status… v jakém stavu jsou jednotlivé soubory? (untracked / committed / modified / staged)git add <file>… 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 <file>… vyřadit soubor ze staging oblastigit checkout – <file>… zapomenout změny v pracovní kopii a vrátit se k verzi souboru uložené v repozitářigit commit -m 'log'… uložit soubory ze staging oblasti do (lokálního!) repozitáře; na vzdálený server to pořád nemá vlivgit 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 oblastigit diff –cached… co jsem změnil a zkopíroval do staging oblastigit log… historie uložených verzígitk… grafický program, který vizualizuje výstupgit log
git rm <file>… odstranit soubor z pracovní složky a říct gitu, že ho má přestat sledovatgit rm –cached <file>… přestat sledovat soubor, ale jeho kopii v pracovní složce ponechatgit mv <file1> <file2>… přejmenovat nebo přesunout souborgit 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 <shortname> <url>… přidat vzdálený repozitář, se kterým se můžeme synchronizovatgit 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žkygit checkout -b testing… zkratka: vytvořit novou větev a hned se do ní přepnoutgit checkout -b testing dfcb57a2… vrátit se k revizi (commitu) s kódemdfcb57a2, na něm vytvořit novou větevtestinga 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 jinougit 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 <basebranch> <topicbranch>… 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
.svns 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žkugitplaygroundmůž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
