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ětevtesting
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 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
.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žkugitplayground
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