564 votes

Récupérer le journal de validation pour une ligne spécifique dans un fichier?

Y a-t-il un moyen d'obtenir que git vous donne un journal de validation pour les commits qui ont touché une ligne particulière dans un fichier?

Comme git blame , mais git blame vous montrera le LAST commit qui a touché une ligne particulière.

Je voudrais vraiment avoir un journal similaire, pas la liste des commits vers n'importe où dans le fichier, mais juste les commits qui ont touché une ligne particulière.

709voto

Matt McClure Points 1519

Voir aussi Git: découvrir qui commet jamais touché à un ensemble de lignes.


Depuis Git 1.8.4, git log a -L pour voir l'évolution d'un ensemble de lignes.

Par exemple, supposons que vous regardez git blamesortie de:

((aa27064...))[mlm@macbook:~/w/mlm/git]
$ git blame -L150,+11 -- git-web--browse.sh
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 150)            die "The browser $browser is not
a180055a git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:36 +0100 151)    fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 152) fi
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 153) 
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 154) case "$browser" in
81f42f11 git-web--browse.sh (Giuseppe Bilotta 2010-12-03 17:47:38 +0100 155) firefox|iceweasel|seamonkey|iceape)
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 156)    # Check version because firefox < 2.0 do
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 157)    vers=$(expr "$($browser_path -version)" 
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 158)    NEWTAB='-new-tab'
5d6491c7 git-browse-help.sh (Christian Couder 2007-12-02 06:07:55 +0100 159)    test "$vers" -lt 2 && NEWTAB=''
a0685a4f git-web--browse.sh (Dmitry Potapov   2008-02-09 23:22:22 -0800 160)    "$browser_path" $NEWTAB "$@" &

Et vous voulez savoir l'histoire de ce qui est maintenant la ligne 155.

Alors:

((aa27064...))[mlm@macbook:~/w/mlm/git]
$ git log --topo-order --graph -u -L 155,155:git-web--browse.sh
* commit 81f42f11496b9117273939c98d270af273c8a463
| Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
| Date:   Fri Dec 3 17:47:38 2010 +0100
| 
|     web--browse: support opera, seamonkey and elinks
|     
|     The list of supported browsers is also updated in the documentation.
|     
|     Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
|     Signed-off-by: Junio C Hamano <gitster@pobox.com>
| 
| diff --git a/git-web--browse.sh b/git-web--browse.sh
| --- a/git-web--browse.sh
| +++ b/git-web--browse.sh
| @@ -143,1 +143,1 @@
| -firefox|iceweasel)
| +firefox|iceweasel|seamonkey|iceape)
|  
* commit a180055a47c6793eaaba6289f623cff32644215b
| Author: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
| Date:   Fri Dec 3 17:47:36 2010 +0100
| 
|     web--browse: coding style
|     
|     Retab and deindent choices in case statements.
|     
|     Signed-off-by: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
|     Signed-off-by: Junio C Hamano <gitster@pobox.com>
| 
| diff --git a/git-web--browse.sh b/git-web--browse.sh
| --- a/git-web--browse.sh
| +++ b/git-web--browse.sh
| @@ -142,1 +142,1 @@
| -    firefox|iceweasel)
| +firefox|iceweasel)
|  
* commit 5884f1fe96b33d9666a78e660042b1e3e5f9f4d9
  Author: Christian Couder <chriscool@tuxfamily.org>
  Date:   Sat Feb 2 07:32:53 2008 +0100

      Rename 'git-help--browse.sh' to 'git-web--browse.sh'.

      Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
      Signed-off-by: Junio C Hamano <gitster@pobox.com>

  diff --git a/git-web--browse.sh b/git-web--browse.sh
  --- /dev/null
  +++ b/git-web--browse.sh
  @@ -0,0 +127,1 @@
  +    firefox|iceweasel)

68voto

Adam Dymitruk Points 34999

Vous pouvez obtenir un ensemble de commits en utilisant pick-ax.

 git log -S'the line from your file' -- path/to/your/file.txt
 

Cela vous donnera tous les commits qui ont affecté ce texte dans ce fichier. Si le fichier a été renommé à un moment donné, vous pouvez ajouter --follow-parent.

Si vous souhaitez inspecter les commits à chacune de ces modifications, vous pouvez les afficher comme suit:

 git log ... | xargs -n 1 git show
 

11voto

Jefromi Points 127932

Je ne crois pas qu'il y a quelque chose de construit pour cela. Elle est rendue délicate par le fait qu'il est rare qu'une seule ligne à changer plusieurs fois sans le reste du fichier de modification substantielle de trop, de sorte que vous aurez tendance à finir avec les numéros de ligne beaucoup changé.

Si vous êtes assez chanceux que la ligne a toujours certaines caractéristiques, par exemple, une affectation à une variable dont le nom n'a jamais changé, vous pouvez utiliser les regex choix pour git blame -L. Par exemple:

git blame -L '/variable_name *= */',+1

Mais cela ne trouve que le premier match pour que la regex, donc si vous n'avez pas une bonne façon de correspondant à la ligne, il n'est pas trop utile.

On pouvait hacker quelque chose, je suppose. Je n'ai pas le temps d'écrire le code de tout à l'heure, mais... quelque chose le long de ces lignes. Exécutez git blame -n -L $n,$n $file. Le premier champ est la précédente livraison touché, et le deuxième champ est le numéro de la ligne dans que s'engager, car il pourrait avoir changé. Saisir ceux-ci, et exécutez git blame -n $n,$n $commit^ $file, c'est à dire la même chose à partir de la validation avant la dernière fois que le fichier a été modifié.

(Notez que cela ne fonctionne pas si le dernier commit qui a changé la ligne était une fusion de commettre. Le principal moyen de ce qui pourrait arriver si la ligne a été modifiée dans le cadre d'une fusion de la résolution des conflits.)

Edit: j'ai croisé cette liste de diffusion de poste à partir de Mars 2011 aujourd'hui, qui mentionne qu' tig et git gui disposent d'une fonctionnalité qui vous aidera à le faire. Il ressemble à la fonctionnalité a été pris en compte, mais pas fini, pour git lui-même.

8voto

Lucas Cimon Points 178

Voici une solution qui définit un alias git, de sorte que vous serez en mesure de l'utiliser comme ça :

git rblame -M -n -L '/REGEX/,+1' FILE

Exemple de sortie :

00000000 18 (Not Committed Yet 2013-08-19 13:04:52 +0000 728) fooREGEXbar
15227b97 18 (User1 2013-07-11 18:51:26 +0000 728) fooREGEX
1748695d 23 (User2 2013-03-19 21:09:09 +0000 741) REGEXbar

Vous pouvez définir l'alias dans votre .gitconfig ou exécutez simplement la commande suivante

git config alias.rblame !sh -c 'while line=$(git blame "$@" $commit 2>/dev/null); do commit=${line:0:8}^; [ 00000000^ == $commit ] && commit=$(git rev-parse HEAD); echo $line; done' dumb_param

C'est un laid-liner, voici donc une de-obfuscation équivalent bash fonction :

git-rblame () {
    local commit line
    while line=$(git blame "$@" $commit 2>/dev/null); do
        commit="${line:0:8}^"
        if [ "00000000^" == "$commit" ]; then
            commit=$(git rev-parse HEAD)
        fi
        echo $line
    done
}

La pioche solution ( git log --pioche-regex -S'REGEX' ) ne fera que vous donner ligne ajouts/suppressions, pas les autres modifications de la ligne contenant l'expression régulière.

Une limitation de cette solution est que git blâmer retourne uniquement le 1er REGEX match, donc si plusieurs correspondances existent la récursivité peut "sauter" pour suivre une autre ligne. Assurez-vous de vérifier l'historique de la sortie de repérer ces "sauts" et puis réparer votre REGEX pour ignorer les lignes parasites.

Enfin, voici une autre version qui exécutez git show sur chacun de s'engager à obtenir le diff complet :

git config alias.rblameshow !sh -c 'while line=$(git blame "$@" $commit 2>/dev/null); do commit=${line:0:8}^; [ 00000000^ == $commit ] && commit=$(git rev-parse HEAD); git show $commit; done' dumb_param

6voto

krlmlr Points 5572

Cela appellera git blame pour chaque révision significative pour montrer la ligne $LINE du fichier $FILE:

git log --format=format:%H $FILE | xargs -L 1 git blame $FILE -L $LINE,$LINE

Comme d'habitude, le blâme affiche le numéro de révision dans le début de chaque ligne. Vous pouvez ajouter

| sort | uniq -c

pour obtenir des résultats agrégés, quelque chose comme une liste de commits qui a changé cette ligne. (Pas tout à fait, si le code a été déplacé autour, ce qui pourrait montrer de la même commettre ID à deux reprises pour des contenus différents de la ligne. Pour une analyse plus détaillée que vous auriez à faire une comparaison à la traîne de l' git blame résultats pour adjacents s'engage. N'importe qui?)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X