J'ai donc trouvé la question de savoir comment afficher l'historique des modifications d'un fichier, mais l'historique des modifications de ce fichier particulier est énorme et je ne m'intéresse vraiment qu'aux modifications d'une méthode particulière. Alors, serait-il possible de voir l'historique des modifications pour cette méthode en particulier?
Je sais que cela nécessiterait git d'analyser le code et que l'analyse serait différente pour différentes langues, mais les déclarations de méthode / fonction semblent très similaires dans la plupart des langues, alors j'ai pensé que quelqu'un a peut-être implémenté cette fonctionnalité.
Le langage avec lequel je travaille actuellement est Objective-C et le SCM que j'utilise actuellement est git, mais je serais intéressé de savoir si cette fonctionnalité existe pour n'importe quel SCM / langage.
Réponses:
Les versions récentes de
git log
appris une forme spéciale du-L
paramètre:En d'autres termes: si vous demandez à Git de le faire
git log -L :myfunction:path/to/myfile.c
, il affichera désormais avec plaisir l'historique des modifications de cette fonction.la source
L'utilisation
git gui blame
est difficile à utiliser dans les scripts, et biengit log -G
quegit log --pickaxe
chacun puisse vous montrer quand la définition de la méthode est apparue ou a disparu, je n'ai trouvé aucun moyen de leur faire lister toutes les modifications apportées au corps de votre méthode.Cependant, vous pouvez utiliser
gitattributes
et letextconv
propriété pour reconstituer une solution qui fait exactement cela. Bien que ces fonctionnalités aient été initialement destinées à vous aider à travailler avec des fichiers binaires, elles fonctionnent tout aussi bien ici.La clé est que Git supprime du fichier toutes les lignes sauf celles qui vous intéressent avant d'effectuer des opérations de comparaison. Alors
git log
,git diff
etc. ne verront que la zone que vous intéresse.Voici les grandes lignes de ce que je fais dans une autre langue; vous pouvez le modifier selon vos propres besoins.
Écrivez un court script shell (ou un autre programme) qui prend un argument - le nom d'un fichier source - et ne produit que la partie intéressante de ce fichier (ou rien si rien de tout cela n'est intéressant). Par exemple, vous pouvez utiliser
sed
comme suit:Définir un Git
textconv
filtre pour votre nouveau script. (Voir lagitattributes
page de manuel pour plus de détails.) Le nom du filtre et l'emplacement de la commande peuvent être tout ce que vous voulez.Dites à Git d'utiliser ce filtre avant de calculer les différences pour le fichier en question.
Maintenant, si vous utilisez
-G.
(notez le.
) pour lister tous les commits qui produisent des changements visibles lorsque votre filtre est appliqué, vous aurez exactement ces commits qui vous intéressent. Toutes les autres options qui utilisent les routines de diff de Git, telles que--patch
, obtenez également cette vue restreinte.Voilà!
Une amélioration utile que vous voudrez peut-être apporter est que votre script de filtrage prenne un nom de méthode comme premier argument (et le fichier comme deuxième). Cela vous permet de spécifier une nouvelle méthode intéressante simplement en appelant
git config
, plutôt que d'avoir à modifier votre script. Par exemple, vous pourriez dire:Bien sûr, le script de filtrage peut faire tout ce que vous voulez, prendre plus d'arguments ou autre: il y a beaucoup de flexibilité au-delà de ce que j'ai montré ici.
la source
git log a une option '-G' qui peut être utilisée pour trouver toutes les différences.
Donnez-lui simplement une expression régulière du nom de la fonction qui vous intéresse. Par exemple,
la source
--oneline
par-p
La chose la plus proche que vous puissiez faire est de déterminer la position de votre fonction dans le fichier (par exemple, disons que votre fonction
i_am_buggy
est aux lignes 241 à 263 defoo/bar.c
), puis exécutez quelque chose comme:Cela ouvrira moins (ou un téléavertisseur équivalent). Maintenant, vous pouvez taper
/i_am_buggy
(ou votre équivalent pager) et commencer à parcourir les modifications.Cela peut même fonctionner, en fonction de votre style de code:
Cela limite la recherche à partir du premier hit de cette expression régulière (idéalement votre déclaration de fonction) à trente lignes après cela. L'argument de fin peut également être une expression rationnelle, bien que détecter cela avec les expressions rationnelles est une proposition plus incertaine.
la source
-L ":int myfunc:foo/bar.c"
et vous limiter à la fonction portant ce nom. C'est fantastique - merci pour le pointeur! Maintenant, si seulement la fonction de détection était un peu plus fiable ...La bonne façon est d'utiliser
git log -L :function:path/to/file
comme expliqué dans la réponse eckes .Mais en plus, si votre fonction est très longue, vous voudrez peut-être voir uniquement les changements introduits par divers commit, et non les lignes de fonction entières, incluses non modifiées, pour chaque commit qui ne touche peut-être qu'une de ces lignes. Comme une normale
diff
.Normalement,
git log
peut afficher les différences avec-p
, mais cela ne fonctionne pas avec-L
. Vous devez doncgrep
git log -L
afficher uniquement les lignes impliquées et l'en-tête commits / files pour les contextualiser. L'astuce ici est de faire correspondre uniquement les lignes colorées du terminal, en ajoutant un--color
commutateur, avec une expression régulière. Finalement:Notez que cela
^[
doit être réel, littéral^[
. Vous pouvez les saisir en appuyant sur ^ V ^ [en bash, c'est-à-dire Ctrl+ V, Ctrl+ [. Référence ici .Dernier
-3
interrupteur également, permet d'imprimer 3 lignes de contexte de sortie, avant et après chaque ligne correspondante. Vous voudrez peut-être l'ajuster à vos besoins.la source
git blame vous montre qui a changé en dernier chaque ligne du fichier; vous pouvez spécifier les lignes à examiner afin d'éviter de récupérer l'historique des lignes en dehors de votre fonction.
la source
git gui blame
vous pouvez parcourir les anciennes révisions.Afficher l'historique des fonctions avec
git log -L :<funcname>:<file>
comme indiqué dans la réponse d'eckes et git docS'il ne montre rien, reportez-vous à la section Définition d'un en-tête de morceau personnalisé pour ajouter quelque chose comme
*.java diff=java
au.gitattributes
fichier pour prendre en charge votre langue.Afficher l'historique des fonctions entre les validations avec
git log commit1..commit2 -L :functionName:filePath
Afficher l'historique des fonctions surchargées (il peut y avoir plusieurs fonctions avec le même nom, mais avec des paramètres différents) avec
git log -L :sum\(double:filepath
la source