page header

oktober 2009 Archieven

Git Hash filters


Geplaatst door tonk op do okt 1 13:58:58 CEST 2009 | Permanente link | Reacties: 0

Enige tijd geleden schreven Miek en ik hier op het blog over de evolutie van scripts. Het gebruikte script, met de naam vigit is enige tijd naar tevredenheid op onze systemen gebruikt. Maar er zat mij toch iets dwars. Wanneer een bestand met behulp van vigit bewerkt werd, dan werd het wel netjes in de git repository ingechecked, maar daarna werd ook automatisch de Hash:: regel aangepast. Het commando

git diff

leverde dan ook altijd veel verschillen ten opzichte van de respository op.

Weer eens zwervend op het wereld wijde web ontdekte ik plotseling iets over Git filters. Dat bracht mij op de gedachte om de Hash:: verandering door een filter te laten doen, zodat de inhoud van de repository overeenkomt met de huidige versie.

Als eerste dient Git te weten welk filter gebruikt moet worden en waar de onderdelen van dit filter staan. Per filter zijn twee filter mogelijkheden aanwezig, namelijk clean; die wordt gebruikt bij het inchecken en smudge, die wordt gebruikt bij het uitchecken.

In het bestand ~/.gitconfig staan nu de volgende regels:

[filter "git_vi"]
    smudge = /usr/local/bin/git.expand
    clean = /usr/local/bin/git.collapse

Hierbij zijn natuurlijk ook de twee filter programma's nodig.

Dit is git.expand

#!/bin/bash
spc="$(printf "%80s" "")"
who=${SUDO_USER:-${LOGNAME}}
id=$(git show -s --pretty=format:"%H (${who})")
id="${id}${spc}"
sed -e 's!\([[:space:]]*\$[H]ash::\).*\$:!\1 '"${id:0:66}"'\$:!'

en git.collapse

#!/bin/bash
spc="$(printf "%80s" "")"
sed -e 's!\([[:space:]]*\$[H]ash::\).*\$:!\1 '"${spc:0:66}"'\$:!'

Maar, git moet ook weten voor welk bestand welk filter aangeroepen moet worden. Deze informatie staat in het bestand .gitattributes in de directory waar ook de .git repository directory staat.

De inhoud van dit bestand is:

*.[ch]  filter=git_vi
*.sh    filter=git_vi
*.pl    filter=git_vi
*.tex   filter=git_vi
*.cls   filter=git_vi

Wanneer dit allemaal geconfigureerd is, dan wordt bij een checkin het filter programma git.collapse uitgevoerd, dat de Hash:: regel netjes opruimt. In de Git repository staat dan ook geen Hash:: informatie in de ingecheckte bestanden.

Bij een checkout wordt het git.expand filter-programma uitgevoerd. Dit programma haalt de Hash informatie voor dit bestand uit Git en plaatst dat op de Hash:: regel van het bestand.

Om dit allemaal mogelijk te maken, waren ook wat veranderingen nodig aan het vigit programma. Om problemen te voorkomen is het programma dan ook omgedoopt tot git.vi.

Het volledige git.vi programma is hier te vinden.