Git recevoir/mettre à jour les crochets et les nouvelles branches

J'ai un problème avec le crochet 'update'. Dans le cas d'une nouvelle branche, il obtient un 0000000000000000000000000000000000000000 comme 'oldrev'. Et je ne sais pas comment gérer cette affaire.

Nous avons l'exigence, que chaque message de validation référence un problème JIRA valide. J'ai donc installé un crochet "update" sur notre référentiel central. Ce crochet obtient un "oldrev" et un "newrev". Je passe ensuite ceux-ci à "git rev-list" comme ceci:

git rev-list $oldrev..$newrev

Cela me donne la liste de tous revs, que je peux ensuite parcourir, et faire tout ce que je dois faire.

Le problème est que lorsque l'utilisateur pousse une nouvelle branche, le hook obtient 000000000000000000000000000000000000000000 comme oldrev. Et "git rev-list" se plaint simplement avec:

fatal: Invalid revision range 0000000000000000000000000000000000000000..21bac83b2

Alors, comment puis-je obtenir la liste de tous les régimes qui sont sur cette nouvelle branche? J'ai cherché sur le net depuis un certain temps maintenant, et je n'ai rien trouvé. L'exemple de crochets que j'ai trouvé soit

  • ne gérez pas le problème et échouez avec le message d'erreur ci-dessus
  • essayez incorrectement de résoudre le problème en définissant oldrev sur"", ce qui renvoie les mauvais résultats de rev-list
  • tout simplement abandonner quand ils rencontrent que oldrev

Aucun de ces sons particulièrement excitant.

Alors quelqu'un a-t-il une idée de comment obtenir la bonne réponse dans ce cas? Je pensais à interroger git pour "Donnez-moi tous les revs qui sont accessibles depuis newrev, mais pas depuis l'une des autres branches (=toutes les branches à l'exception de la nouvelle)". Mais même cela donnerait la mauvaise réponse s'il y avait eu une fusion de la nouvelle branche à l'une des anciennes.

29
demandé sur marc.guenther 2010-08-18 14:23:24

4 réponses

Le terme "bonne réponse" est un peu ambigu dans ce cas. Je pense en fait que "tous les régimes accessibles depuis newrev mais nulle part ailleurs" est tout à fait correct. Cela est vrai même s'il y a eu une fusion - dans ce cas, vous devriez voir les commits uniques à la nouvelle référence, et le commit de fusion, mais pas les commits qui ont été fusionnés.

Donc, je dirais, vérifiez si le "oldrev" est tous des zéros, et si c'est le cas, agissez en conséquence:

if [ "$oldrev" -eq 0 ]; then
    # list everything reachable from newrev but not any heads
    git rev-list $(git for-each-ref --format='%(refname)' refs/heads/* | sed 's/^/\^/') "$newrev"
else
    git rev-list "$oldrev..$newrev"
fi
15
répondu Cascabel 2013-01-11 09:11:31

Lorsque $oldrev est tous des zéros, une commande git rev-list différente fait tout ce dont vous avez besoin:

git rev-list $newrev --not --branches=*

Vous donnera une liste de révisions accessibles depuis {[3] } mais pas depuis des branches.

Notez que cela fait certainement Pas Faire la même chose que git rev-list $oldrev..$newrev Quand oldrev est Pas tous les zéros, donc vous voudrez vérifier dans quel cas vous êtes et choisir la commande appropriée à exécuter.

11
répondu Joseph 2014-06-19 17:15:51

Je viens de le comprendre moi-même.

Git log newref --pas otherheads

Est la clé pour obtenir tous les journaux d'une branche qui ne sont sur aucune autre branche. Voici mon script python pour vérifier la longueur de ligne maximale correcte des messages de validation.

import sys
import commands

ref = sys.argv[1]
old = sys.argv[2]
new = sys.argv[3]

x = 0

# only a tag is pushed to server, nothing to check
if ref.find('refs/tags/') >= 0:
  if len(ref.strip('refs/tags/')) > 25:
    print 'tag name is longer than 25 characters'
    exit(1)
  else:
    exit(0)
# either a new branch is pushed or an empty repo is being pushed
if old == '0000000000000000000000000000000000000000':
  heads = commands.getoutput("git for-each-ref --format='%(refname)' 'refs/heads/*'")
  heads = heads.replace(ref+'\n','').replace('\n',' ')
  hashes = commands.getoutput('git log '+new+' --pretty=%H --not '+heads).split('\n')
else:
  hashes = commands.getoutput('git log '+old+'..'+new+' --pretty=%H').split('\n')

for hash in hashes:
  subject = commands.getoutput('git show '+hash+' --format=%s --summary').split('\n')
  body = commands.getoutput('git show '+hash+' --format=%b --summary').split('\n')

  if len(subject[0]) > 75:
    print
    print 'commit: '+hash
    print 'bad commit message(s): header line is too long or second line is not blank (max 75 chars)'
    print 'bad line: "%s"' % subject[0]
    print 'length of header line: %d' % len(subject[0])
    print 'try again with correct message format'
    print
    x = 1

  for line in body: 
    if len(line) > 75:
      print
      print 'commit: '+hash
      print 'bad commit message(s): description lines are too long (max 75 chars)'
      print 'bad line: "%s"' % line
      print 'length of  line: %d' % len(line)
      print 'try again with correct message format'
      print
      x = 1

if x == 0:
  exit(0)
else:
  exit(1)
7
répondu mattmilten 2011-03-23 16:22:52

J'ai résolu cela pour mon crochet de mise à jour en utilisant ce qui suit:

if [ "$oldrev" -eq 0 ]; then
git log "$(git show-branch --merge-base)".."$newrev"; else
foo;
fi
2
répondu bender bending rodriguez 2012-06-01 14:26:48