Git
Chapters ▾ 2nd Edition

7.5 Git Alətləri - Axtarış

Axtarış

Təxminən hər hansı bir ölçülü kod bazası ilə tez-tez bir funksiyanın çağırıldığı və ya təyin olunduğu yeri tapmaq və ya bir metodun tarixini göstərmək lazımdır. Git kodu araşdırmaq üçün bir neçə faydalı vasitə təqdim edir və verilənlər bazasında tez və asanlıqla saxlanılır. Onlardan bir neçəsindən keçəcəyik.

Git Grep

Hər hansı bir düzəldilmiş ağacdan, işçi qovluqdan və ya hətta bir simli və ya adi bir ifadə üçün asanlıqla axtarış etməyə imkan verən grep adlı bir əmr ilə birlikdı gəlir. Sonrakı nümunələr üçün Git mənbə koduna baxacağıq.

Varsayılan olaraq, git grep işçi qovluğunuzdakı fayllara baxacaqdır. Birinci variasiya olaraq, Git’in uyğunlaşmaları tapdığı sətir nömrələrini çap etmək üçün -n və ya --line-number seçimlərindən birini istifadə edə bilərsiniz:

$ git grep -n gmtime_r
compat/gmtime.c:3:#undef gmtime_r
compat/gmtime.c:8:      return git_gmtime_r(timep, &result);
compat/gmtime.c:11:struct tm *git_gmtime_r(const time_t *timep, struct tm *result)
compat/gmtime.c:16:     ret = gmtime_r(timep, result);
compat/mingw.c:826:struct tm *gmtime_r(const time_t *timep, struct tm *result)
compat/mingw.h:206:struct tm *gmtime_r(const time_t *timep, struct tm *result);
date.c:482:             if (gmtime_r(&now, &now_tm))
date.c:545:             if (gmtime_r(&time, tm)) {
date.c:758:             /* gmtime_r() in match_digit() may have clobbered it */
git-compat-util.h:1138:struct tm *git_gmtime_r(const time_t *, struct tm *);
git-compat-util.h:1140:#define gmtime_r git_gmtime_r

Yuxarıda göstərilən əsas axtarışa əlavə olaraq, git grep bir çox digər maraqlı variantları dəstəkləyir.

Məsələn, bütün uyğunlaşmaları çap etmək əvəzinə axtarış sətirində hansı sənədlərin olduğunu və hər bir faylda -c və ya --count seçiminindən istifadə edərək neçə uyğunlaşmanın olduğunu göstərən git grep-dən nəticəni ümumiləşdirməsini istiyə bilərsiniz.

$ git grep --count gmtime_r
compat/gmtime.c:4
compat/mingw.c:1
compat/mingw.h:1
date.c:3
git-compat-util.h:2

Bir axtarış sətirinin konteksti ilə maraqlanırsınızsa, hər bir uyğun sətir üçün enclosing metodunu və ya funksiyasını -p və ya --show-function seçimlərindən birini göstərə bilərsiniz:

$ git grep -p gmtime_r *.c
date.c=static int match_multi_number(timestamp_t num, char c, const char *date,
date.c:         if (gmtime_r(&now, &now_tm))
date.c=static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt)
date.c:         if (gmtime_r(&time, tm)) {
date.c=int parse_date_basic(const char *date, timestamp_t *timestamp, int *offset)
date.c:         /* gmtime_r() in match_digit() may have clobbered it */

Gördüyünüz kimi, gmtime_r rutin date.c faylındakı match_multi_numbermatch_digit funksiyalarını çağırır (üçüncü uyğunlaşma yalnız şərhdə görünən sətri təmsil edir).

Ayrıca mətnin eyni sətirində birdən çox uyöunlaşmanın meydana gəlməsini təmin edən --and flag-ı ilə kompleks birləşmələri axtara bilərsiniz.

Məsələn, adı “LINK” və ya “BUF_MAX” alt hissələrindən hər hansı bir sabit olanı müəyyənləşdirən hər hansı bir sətri, özəlliklə də v1.8.0 etiketi ilə təmsil edilən Git kod bazasında köhnə versiyasında axtaraq. (nəticənin daha oxunaqlı olması üçün kömək edən --break--heading seçimlərindən istifadə edəcəyik)

$ git grep --break --heading \
    -n -e '#define' --and \( -e LINK -e BUF_MAX \) v1.8.0
v1.8.0:builtin/index-pack.c
62:#define FLAG_LINK (1u<<20)

v1.8.0:cache.h
73:#define S_IFGITLINK  0160000
74:#define S_ISGITLINK(m)       (((m) & S_IFMT) == S_IFGITLINK)

v1.8.0:environment.c
54:#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS

v1.8.0:strbuf.c
326:#define STRBUF_MAXLINK (2*PATH_MAX)

v1.8.0:symlinks.c
53:#define FL_SYMLINK  (1 << 2)

v1.8.0:zlib.c
30:/* #define ZLIB_BUF_MAX ((uInt)-1) */
31:#define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */

git grep əmrinin grepack kimi normal axtarış əmrləri ilə müqayisədə bir sıra üstünlüklərə malikdir. Birincisi, həqiqətən sürətlidir, ikincisi, yalnız işləyən qovluğda deyil, Git-də hər hansı bir ağacdan axtarış edə bilərsiniz. Yuxarıdakı nümunədə gördüyümüz kimi hazırda yoxlanılan versiyada deyil, Git mənbə kodunun köhnə bir versiyasında terminlər axtara bilirik.

Git Log Axtarışı

Bəlkə də bir terminin harda mövcud olduğunu deyil, nə zaman mövcud olduğunu və tətbiq edildiyini axtarırsınız. git log əmrində mesajlarının məzmununa və ya təklif etdikləri fərqə əsaslanaraq müəyyən hərəkətləri tapmaq üçün bir sıra güclü vasitələr var.

Məsələn, ZLIB_BUF_MAX sabitinin nə vaxt tətbiq olunduğunu bilmək istəyiriksə, Git-in yalnız bizə göstərməsini söyləmək üçün -S seçimini istifadə edə bilərik.

$ git log -S ZLIB_BUF_MAX --oneline
e01503b zlib: allow feeding more than 4GB in one go
ef49a7a zlib: zlib can only process 4GB at a time

Verilənlərin fərqinə baxsaq, görərik ki, ef49a7a-da sabitlik qoyulmuşdur və e01503b də dəyişdirilmişdir.

Daha konkret olmağınız lazımdırsa, -G seçimi ilə axtarış aparmaq üçün adi bir ifadə verə bilərsiniz.

Line Log Axtarışı

Olduqca faydalı olan daha bir inkişaf etmiş axtarış xətti tarixidir. Sadəcə -L seçimi ilə git log-u işlədin və bu kod bazasında bir funksiya və ya kod xətti tarixini göstərəcəkdir.

Məsələn, zlib.c faylında git_deflate_bound funksiyasına edilən hər bir dəyişikliyi görmək istəsək, git log -L :git_deflate_bound:zlib.c işlədə bilərik. Bu funksiyanın hüdudlarının nə olduğunu anlamağa çalışacaq və sonra tarixə nəzər salacaq və funksiyaya edilən dəyişikliklərin hamısını funksiyanın ilk yaradıldığı vaxtdan geri qalmış bir sıra patch-lar şəklində göstərəcəkdir.

$ git log -L :git_deflate_bound:zlib.c
commit ef49a7a0126d64359c974b4b3b71d7ad42ee3bca
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 10 11:52:15 2011 -0700

    zlib: zlib can only process 4GB at a time

diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -85,5 +130,5 @@
-unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+unsigned long git_deflate_bound(git_zstream *strm, unsigned long size)
 {
-       return deflateBound(strm, size);
+       return deflateBound(&strm->z, size);
 }


commit 225a6f1068f71723a910e8565db4e252b3ca21fa
Author: Junio C Hamano <gitster@pobox.com>
Date:   Fri Jun 10 11:18:17 2011 -0700

    zlib: wrap deflateBound() too

diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -81,0 +85,5 @@
+unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+{
+       return deflateBound(strm, size);
+}
+

Git bir proqramlaşdırma dilində bir funksiya və ya metodla necə uyğunlaşa biləcəyini bilmirsə, onu regular bir ifadə ilə təmin edə bilərsiniz (və ya regex). Məsələn, yuxarıdakı nümunə ilə eyni işi görmüş olardı: git log -L '/unsigned long git_deflate_bound/',/^}/:zlib.c. Ayrıca bir sıra sətir və ya bir sətir nömrəsi verə bilərsiniz və eyni cür nəticə əldə edəcəksiniz.