Kan een Git hook automatisch bestanden aan de commit toevoegen?

Ik zou graag een automatisch gegenereerd bestand aan dezelfde commit willen toevoegen met behulp van een pre- of post-commit hook in Git, afhankelijk van de bestanden die in die commit zijn gewijzigd. Hoe zou ik dit aanpakken?

Ik heb dit geprobeerd als een pre-commit hook, maar geen geluk:

#!/bin/sh
files=`git diff --cached --name-status`
re="<files of importance>"
if [[ $files =~ $re ]]
then
  echo "Creating files"
  exec bundle exec create_my_files
  exec git add my_files
  exec git commit --amend -C HEAD
fi

Dit voegt ze met succes toe aan de repository, maar voegt ze niet toe aan de commit. Ik heb ook geprobeerd de laatste twee exec-regels in een post-commit hook samen met de pre-commit-inspectie te gebruiken, maar ook niet goed.


Antwoord 1, autoriteit 100%

Aangezien git add ook niet voor mij werkte in een pre-commit, volgde ik Mark’s idee om een ​​.commit-bestand te gebruiken en het proces op te splitsen in pre- en post-commit.

Hier is wat code die gemakkelijk te begrijpen moet zijn

In de pre-commit:

  • Raak een bestand .commit of zoiets aan. (voeg dit toe aan .gitignore)
#!/bin/sh 
echo 
touch .commit 
exit

In de post-commit:

Als .commit bestaat, weet je dat er zojuist een commit heeft plaatsgevonden, maar a
post-commit is nog niet uitgevoerd. U kunt hier dus uw codegeneratie doen.
Test bovendien op .commit en of het bestaat:

  • voeg de bestanden toe
  • commit –amend -C HEAD –no-verify (vermijd looping)
  • verwijder .commit-bestand
#!/bin/sh
echo
if [ -e .commit ]
    then
    rm .commit
    git add yourfile
    git commit --amend -C HEAD --no-verify
fi
exit

Ik hoop dat dit het voor mensen met weinig bash-kennis gemakkelijker maakt om het idee van Mark te volgen.


Antwoord 2, autoriteit 51%

Het is mogelijk om te doen wat je wilt met pre-commit hooks. We doen iets soortgelijks voor een heroku-implementatie (koffiescript compileren naar javascript). De reden dat je script niet werkt, is omdat je de opdracht execonjuist hebt gebruikt.

Van de man-pagina:

De ingebouwde exec wordt gebruikt om de huidige afbeelding van het shells-proces te vervangen door een nieuwe opdracht. Na succesvolle voltooiing komt exec nooit meer terug. exec kan niet binnen een pijplijn worden gebruikt.

Alleen uw eerste exec-opdracht wordt uitgevoerd. Daarna wordt je script in principe beëindigd.

Probeer zoiets als dit eens (als een pre-commit hook):

#!/bin/sh
files=`git diff --cached --name-status`
re="<files of importance>"
if [[ $files =~ $re ]]
then
  echo "Creating files"
  bundle exec create_my_files
  git add my_files
fi

Antwoord 3, autoriteit 20%

#!/bin/sh
#
#  .git/hooks/pre-commit
#
git add file.xyz

Dit werkte prima voor mij.
Het zal deel uitmaken van de huidige commit.

git version 1.7.12.4 (Apple Git-37)


Antwoord 4, autoriteit 14%

Je zou een combinatie van een pre- en post-commit-script kunnen gebruiken.

In de pre-commit:

  • Raak een bestand .commit of zoiets aan. (voeg dit toe aan .gitignore)

In de post-commit:

Als .commit bestaat, weet je dat er zojuist een commit heeft plaatsgevonden, maar dat er nog geen post-commit is uitgevoerd. U kunt hier dus uw codegeneratie doen. Test bovendien op .commit en of het bestaat:

  • voeg de bestanden toe
  • commit –amend -C HEAD –no-verify (vermijd looping)
  • verwijder .commit-bestand

Dit is ongeveer het proces dat ik gebruik om een ​​.metadata-bestand op te slaan in de repository die is gegenereerd vanuit metastore.

Als iemand een betere manier weet, ik ben een en al oor, maar voor nu lijkt het te werken.


Antwoord 5, autoriteit 13%

U kunt update-indexgebruiken:

git update-index --add my_files


Antwoord 6, autoriteit 3%

Als de bestanden automatisch worden gegenereerd en ze overal kunnen worden gegenereerd (impliciet in je wens om ze in de Git pre-commit hook te bouwen), dan zou je ze in de eerste plaats niet onder bronbeheer moeten plaatsen. U dient alleen bronbestanden te beheren — gegenereerde bestanden moeten worden gegenereerd als onderdeel van de buildscripts.

De enige reden om een ​​gegenereerd bestand onder broncontrole te plaatsen, is wanneer het unieke/bevoorrechte bronnen vereist om te genereren (zoals een gelicentieerd programma) of wanneer het een aanzienlijke hoeveelheid tijd kost om te genereren.

Toegevoegd

Van http://git-scm.com/docs/githooks:

pre-commitDeze hook wordt aangeroepen door git
commit, en kan worden omzeild met
–no-verify optie. Het heeft geen parameter nodig en wordt eerder aangeroepen
het voorgestelde commit-logboek verkrijgen
bericht en het maken van een commit. Afsluiten
met een niet-nul status van dit script
zorgt ervoor dat de git commit wordt afgebroken.

De standaard pre-commit hook, wanneer
ingeschakeld, vangt de introductie van lijnen op
met volgspaties en afgebroken
de commit wanneer zo’n regel wordt gevonden.

Alle git commit hooks worden aangeroepen
met de omgevingsvariabele
GIT_EDITOR=: als de opdracht dat niet doet
breng een editor naar voren om de . te wijzigen
commit bericht.

De bedoeling van de pre-commit hook is een pass-fail check van de staat van de werkruimte en de inhoud van de commit, voordat de commit wordt gedaan. Proberen om de inhoud van de commit te veranderen zal niet werken.

Mijn aanbeveling zou zijn om twee stappen aan je buildscripts toe te voegen: (1) een stap die alle verouderde bestanden bouwt die moeten worden gegenereerd (en ze toevoegt aan de werkruimte), en (2) een stap die controleert of alle gegenereerde bestanden up-to-date zijn en een statuscode die niet nul is, retourneert. Je Git pre-commit hook zou de tweede stap moeten uitvoeren. Uw ontwikkelaars moeten worden getraind om de eerste stap indien nodig uit te voeren.


Antwoord 7, autoriteit 3%

Wat dacht je van het schrijven van een post-commitscript dat je bestanden genereert, en dan datlaat doen (iets in de trant van) git add my_files; git commit --amend.


Antwoord 8

Ik had dezelfde behoefte en deze aanpak werkte redelijk goed voor mij:

#!/bin/sh
files='git diff --cached --name-only'
re="<files of importance>"
if [[ $files =~ $re ]]
then
   echo "Creating files"
   create_my_files && git add my_files
fi

waar “create_my_files” uitvoerbaar zou moeten zijn, bijvoorbeeld als het een python-bestand is, zou je het kunnen uitvoeren als “python create_my_files && git add my_files”

en het is waar dat je geen pre-commit nodig hebt om opnieuw te committen (dat zou een oneindige vervelende lus creëren :p)


Antwoord 9

Ja, je kunt automatisch gegenereerde bestanden toevoegen aan de commit met behulp van git hooks! Maar het vereist een lastig script.

Hier vindt u het probleem opgelost. Daar werkt het de bestandsversie bij elke commit bij, voegt een nieuw aangepast bestand toe en wijzigt de commit zoals je het nodig hebt. Het werkt volledig:
https://github.com/evandrocoan/.versioning

Vervolgens vervang je gewoon het ‘Version File Replacement’ algoritme op het bestand ‘updateVersion.sh’, door jouw algoritme. Misschien moet je een paar dingen veranderen, zoals de branch-beperking verwijderen, want daar wordt het script alleen uitgevoerd als je in de ‘develop’-branch bent.

Bovendien zal het alleen het gespecificeerde bestand veranderen als het gestaged is. Als het bestand niet gestaged is, zal het niets anders doen dan de normale/gebruikelijke commit. Om precies te zijn, het drukt uit wat het bij elke stap doet.

Ik ga het uitleggen, die truc. Het is nogal lastig. Op de prepare-commit-msg-hook detecteert het of het gewenste bestand wordt gestaged en vastgelegd. Daarna maakt het een vlagbestand aan en stopt de prepare-commit-msg-hook.
Later op de post-commit-hook controleert het of het vlagbestand bestaat. Zo ja, dan wijzigt het de bestanden op de commit.

Let op, het zou een oneindige lus creëren omdat het opnieuw de prepare-commit-msg-hook zou aanroepen (zoals we aan het wijzigen zijn). Maar het gebeurt niet vanwege het vlagbestand. Wanneer de prepare-commit-msg-hook wordt uitgevoerd en het vlagbestand vindt, “weet” het wat er gebeurt. Vervolgens verwijdert u gewoon het vlagbestand en maakt u het niet opnieuw. Als je dit doet, blokkeert het de post-commit-hook van het opnieuw wijzigen van de commits, waardoor de commit voorgoed kan eindigen.


Antwoord 10

Ik had hetzelfde probleem met de pre-commit hook. Ik was één bestand aan het wijzigen en aan het committen, maar het nam een vorig bestand en niet het bijgewerkte bestand, dus door git command (zoals hieronder) toe te voegen aan de pre-commit hook, is het opgelost.

git add $file

opmerking: $fileis uw bestand dat moet worden toegevoegd.

Bedankt,

Other episodes