Fejlesztői eszközök használatáról
Git
A git belső működésének megértése sokat segít a vele való munkában, és nem is nagy kihívás, mivel a lényeg unixosan egyszerű. A Pro git meg egy remek könyv róla.
A git elosztott verziókezelő, a rendszerben nincsen műszakilag kitüntetett központi repository -- persze szervezetileg minden többfejlesztős rendszerben van ilyen. Ennek megfelelően a központi, gitlabos repóról klónt kell készítenünk (ami műszaki értelemben pont olyan, mint a távoli), a két független életet élő repó között a pull és push műveletekkel próbálunk szinkront tartani.
Klónozás, branchek
A munka megkezdéséhez a git clone <uri>
paranccsal létrehozunk egy klónt. Így minden branchből lesz egy másolatunk. A távoli branchek utolsó ismert állapotát is tárolja a rendszer, a távoli repóra alapból origin
néven hivatkozik a rendszer. Ezeket tudjuk a git fetch
paranccsal frissíteni.
A git checkout <branchnév>
paranccsal lehet a brancheket betölteni, alapból a master-ben vagyunk.
A branch létrehozásához menjünk a kiindulási branchbe, és adjuk ki a git checkout -b feature-blabla
parancsot. Ezzel egyben létrehozunk egy lokális branchet és azt checkoutoljuk is. A git branch
listázza a lokális brancheket. Ezután commitolhatunk a branchbe. A git push origin feature-blabla
paranccsal tudjuk feltölteni a klónozott repóba a commitokat.
Ha nincs push-jogod, forkold a repót (gitlabon van rá egy gomb), és abba tudsz feltölteni. A merge request ugyanúgy mutathat erre is.
Commit
A szokásos fejlesztés módja még egyszer, máshogy:
Egy git checkout -b akarmi
paranccsal csinálsz egy akarmi nevű lokális branchet, és ugyanakkor erre váltasz. Itt elvégzed a fejlesztést – mondjuk egy issue feloldását, közben néhányat commitolsz. (Úgy szeretjük, ha csak a közvetlenül összetartozó módosítások kerülnek egy commitba. Ha már van az összefoglalóban "és", akkor az inkább legyen kettő. Nem kerül semmibe. Ha nagyobb módosítást egyben kell kipróbálni, és nem akarsz közben commitolni, akkor a git add -i
hasznos lehet, mert a diffet interaktívan fel lehet vele darabolni. Commit előtt mindig nyomj egy git status
-t.)
A git add -i
(vagy git add --interactive
) a legkényelmesebb a kommit elkészítésével, segítségével gyorsan össze lehet szedni, mit is akarunk kommitolni. A menüben: u
a git add
-nak felel meg (ha kész vagyunk, csak üssünk egy üres entert), az a
az új fájlokat veszi bele a repóba, a p
a git add -p
-nek felel meg. Ha kb kész vagyunk, a d
-vel meg tudjuk nézni a kommit diffjét, fájlokra lebontva. q-ra kilép, jöhet a kommit.
A fenti add
meg a commit
összevonása a git commit --interactive
, ami az add után rögtön committol is. Jól jöhet hozzá a -v
(--verbose
) kapcsoló, ami az üzenetszerkesztő aljára odateszi a kommit tartalmát (kb a diffet). Ha valaki a git commit -m ....
parancsot ajánlja, ne hallgassatok rá.
Ha nem tetszik az alap kommitszerkesztő editor, a git config --global core.editor vim
tetszeni fog.
Az interaktív diff daraboláshoz segítség, kb fontossági sorrendben: sorban jönnek a darabok, y
elfogad, n
elutasít, s
tovább darabol, q
kilép (amit eddig le lett okézva, az bekerül a kommitba, a maradék nem), a
a maradékot is beveszi a kommitba, j
passzol, majd később visszatérsz rá (k
ugyanez, csak visszafele irányban). Az e
trükkös válasz, itt neked kell diffet írnod a felajánlott helyett: amilyen diffet elmentesz, azok a változások kerülnek be a kommitba, a maradék marad unstaged.
A master ágba csak a core developerek tudnak pusholni, a developerek a többi branchben garázdálkodhatnak, a többiek pedig forkolhatják a repot. Ha megmutatásra érdemes állapotba kerül a branch, pusholjátok, és készítsetek a gitlabon egy merge requestet, amiben leírjátok, hogy mit is tudnak a módosítások és hogy teszteltétek(e) a működést – ha minden rendben, majd innen mergelünk a masterbe.
A cloud repóban a djangohoz kapcsolódó fejlesztések vannak, minden más a CIRCLE csoport többi repójában. Ide nyugodtan lehet új cuccot tenni, akinek nincs hozzá joga, szóljon, vagy csinálja a saját nevében.
A forkot érdemes szinkronban tartani az eredeti fejlesztéssel. Ehhez vegyük föl remote-ként az eredetit: git remote add eredeti git@git.ik.bme.hu:circle/....git
, majd ezután a git pull eredeti/master
paranccsal tudjuk az aktuális branchbe húzni a master-beli módosításokat. Ezt a változatlan saját masterünkbe érdemes pl. Az is jó, ha az eredetit klónozod, és csak később, az első push előtt csinálsz forkot. Ekkor azt kell fölvenni remote-ként, és abba lehet pusholni.
Log
Ha a hajad téped, mert valaki gonosz módon beleszerkesztett a fájlodba, a git blame path/to/file
megmondja ki volt az (minden sorról elárulja, ki nyúlt hozzá utoljára). Ehhez persze az kell, hogy kommitnál rendesen legyen nevünk (GIT_AUTHOR_NAME).
A repó történelmét (!) a git log
parancs mutatja meg, amiből egy jóval tömörebb (és takarosabb) változat a
git log --graph --all --decorate --date-order --pretty='%C(yellow)%h%Cred%d%Creset - %C(cyan)%an %Creset: %s %Cgreen(%ar)'
amire röviden git prettylog
nével lehet hivatkozni, ha csinálunk aliast hozzá:
git config --global alias.prettylog 'log --graph --all --decorate --date-order --pretty="%C(yellow)%h%Cred%d%Creset - %C(cyan)%an %Creset: %s %Cgreen(%ar)"'
Ilyen aliasokat érdemes csinálni, pl ha vissza akarunk vonni minden módosítást az utolsó kommit óta, akkor egy git reset --hard
kell, helyett csinálhatunk rá aliast: git config --global alias.undo 'reset --hard'
(és máris lesz git undo
parancsunk, amivel minden munkánkat eldobhatunk!)
Ha nem színes valamiért a konzol, a git config --global color.ui true
segíthet.
Screen
A fejlesztői szervereket néha screen-ben indítjuk, amivel egyrészt kihasználjuk a termináltöbbszöröző képességét, másrészt az ssh-kapcsolat megszakadása esetén sem kell újraindítani mindent. Emiatt egyébként is érdemes screenben dolgozni. (Az előkészített devenvben az összes szerver fut upstartból, a kimenetük a /var/log/upstart/ alatt található.)
A screen több ablakot kezel, amelyek között a ^A
<szám>
vagy ^A
<szóköz>
parancsokkal lehet váltani. A már futó screent a screen -r
paranccsal lehet csatolni, abból kilépni a ^A
d
paranccsal lehet.
Mivel a screenben futó shellek nem tudják örökölni a csatlakozó shell környezeti változóit, ezért az agent forward és a git szerző nevének beállításához trükközni kell. Ehhez a ˙~/.bash_login˙ fájlba ezt írjuk:
echo "export SSH_AUTH_SOCK='$SSH_AUTH_SOCK'" >/tmp/$USER-env
echo "export GIT_AUTHOR_EMAIL='$GIT_AUTHOR_EMAIL'" >>/tmp/$USER-env
echo "export GIT_AUTHOR_NAME='$GIT_AUTHOR_NAME'" >>/tmp/$USER-env
echo "export GIT_COMMITTER_EMAIL='$GIT_COMMITTER_EMAIL'" >>/tmp/$USER-env
echo "export GIT_COMMITTER_NAME='$GIT_COMMITTER_NAME'" >>/tmp/$USER-env
míg a ~/.bashrc
-be ezt:
function fixenv()
{
source /tmp/$USER-env
echo $GIT_AUTHOR_NAME
}
Így az egyes screen-ablakokban a fixenv
paranccsal betölthető az utoljára indított ssh-kapcsolat alapján a szükséges környezet.
A tájékozódásban sokat segít, ha engedélyezzük a státuszsort. Ehhez vegyük föl a ~/.screenrc fájlba pl. ezt a sort: (ha már fut a screen, ^A
:
után adjuk is ki parancsként)
caption always "%{= 11}%{+b w}%-Lw%{= BW}%50>%n%f* %t%{-}%+Lw%<"
SSH
A fejlesztői gépeket SSH-n keresztül használjuk. Mivel egyes gépeket többen is, és ott célszerű a git commitok elkészítése, ezért egyrészt ssh agent forwardot használunk, amely segítségével a gépünkön lévő ssh privát kulcsokat tudjuk használni a gitlab eléréséhez. Másrészt az ssh képes a környezeti változók átvitelére is, amivel a git számára átadható a szerző neve.
sendenv
A git commitokhoz állítsuk be saját gépünkön, például a ~/.bashrc
-ben a git commitokban használt nevünket: (a már futó shellekben hajtsuk is végre ezeket a parancsokat)
export GIT_AUTHOR_NAME="Gipsz Jakab"
export GIT_AUTHOR_EMAIL=gipsz.jakab@cloud.bme.hu
export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
Ezen kívül engedélyeznünk kell ssh kliensünknek ezen változók elküldését.
Ehhez a ~/.ssh/config fájlban vegyük fel a következő beállítást:
Host *
SendEnv GIT_*
A szerver oldalon is engedélyezni kell a változók átvételét a /etc/ssh/sshd_config
fájlban az AcceptEnv GIT_*
beállítás felvételével és az sshd újratöltésével (ez is be van állítva a devenven).
ssh-agent
Az ssh-agent egy olyan szerver, amit azon a gépen illik futtatni, amelyik előtt ülsz, és annyit tud, hogy bele lehet tölteni ssh privát kulcsokat (ssh-add
), és ezeket egy socketen keresztül odaadja, ha az ssh-nak aláírhatnékja van. Az ssh-add
az ssh-agent
-re tud panaszkodni, ilyenkor egy eval $(ssh-agent)
kell neki. Amiért ez érdekes, az az, hogy az ssh magával tudja vinni ezt a socketet, így a távoli gépről is tudunk a kulcsunkkal ssh-zni (és gitelni), anélkül, hogy a privát kulcsot ténylegesen odaadtuk volna. Mivel ez annyira nem vicces, ha más is hozzáfér a távoli géphez, ezért csak megbízható gépre engedjük továbbítani az agentet (egyébként ssh -A ...
vagy a .ssh/config megfelelő hostjához ForwardAgent yes
kell hozzá), ezért az ssh-add -c
jobb választás – ez minden használatkor kérdez.
Windows
Cygwin-t kell beszerezni, onnan sima ügy, az ssh-add
az ssh-agent
-re tud panaszkodni, ilyenkor egy eval $(ssh-agent)
kell neki. (Putty+Pageant is működik.)
Vim
A csapatban mindenki Vimet használ (önként és dalolva). Ehhez a python_mode nevű bővítményt telepítjük, ami sokmindent tud, de mi a kódellenőrzési képességéért szertjük leginkább. A kezdő tutorialokban szereplő dolgokon kívül a Ctrl+x
Ctrl+o
hasznos, ez végez kódkiegészítést.
Ha már megemlítettem: a projektben minden python-kód a pep8-at követi, és négy szóközzel húzunk be. A flake8-nak pedig le kell futnia, mert különben piros lesz a buildbot. Ennek az ellenőrzéséhez hasznos a cloud repo snippetjei között található pre-commit hook, amit a .git/hooks/pre-commit
néven kell elmenteni, hogy ne engedjen commitolni, ha szintaktikai hibás a kód.
A Django teszteket pedig workon circle
és cd ~/circle/circle
után a ./manage.py test --settings=circle.settings.test
-tel lehet futtatni. Első alkalommal egy pip install -r ../requirements/test.txt
is kell.
Virtualenv
A Python-programok általában sok külső modult használnak. Ezeket érdemes virtualenv-be telepíteni, így nem akadnak össze például a rendszerszintűekkel. A virtualenv egy könyvtár, ahol elfér az adott projekthez szükséges összes modul. Az aktiválásához a virtualenvwrapper nevű csomagot használjuk, ami biztosítja a workon <virtenv_neve>
parancsot, amivel az adott környezetre lehet váltani. Újat pedig az mkvirtualenv
-vel lehet csinálni. A ~/.virtualenvs/blabla/bin/postactivate
szkriptbe szoktuk tenni a futáshoz szükséges környezeti változókat, amiket a workon betölt. Így nem kell a kódon módosítani az adatbázisjelszó beállításához.