-
1. Начало
- 1.1 За Version Control системите
- 1.2 Кратка история на Git
- 1.3 Какво е Git
- 1.4 Конзолата на Git
- 1.5 Инсталиране на Git
- 1.6 Първоначална настройка на Git
- 1.7 Помощна информация в Git
- 1.8 Обобщение
-
2. Основи на Git
-
3. Клонове в Git
-
4. GitHub
-
5. Git инструменти
- 5.1 Избор на къмити
- 5.2 Интерактивно индексиране
- 5.3 Stashing и Cleaning
- 5.4 Подписване на вашата работа
- 5.5 Търсене
- 5.6 Манипулация на историята
- 5.7 Мистерията на командата Reset
- 5.8 Сливане за напреднали
- 5.9 Rerere
- 5.10 Дебъгване с Git
- 5.11 Подмодули
- 5.12 Пакети в Git (Bundling)
- 5.13 Заместване
- 5.14 Credential Storage система
- 5.15 Обобщение
-
6. Настройване на Git
- 6.1 Git конфигурации
- 6.2 Git атрибути
- 6.3 Git Hooks
- 6.4 Примерна Git-Enforced политика
- 6.5 Обобщение
-
7. Git и други системи
- 7.1 Git като клиент
- 7.2 Миграция към Git
- 7.3 Обобщение
-
8. Git на ниско ниво
- 8.1 Plumbing и Porcelain команди
- 8.2 Git обекти
- 8.3 Git референции
- 8.4 Packfiles
- 8.5 Refspec спецификации
- 8.6 Транспортни протоколи
- 8.7 Поддръжка и възстановяване на данни
- 8.8 Environment променливи
- 8.9 Обобщение
-
9. Приложение A: Git в други среди
-
10. Приложение B: Вграждане на Git в приложения
- 10.1 Git от команден ред
- 10.2 Libgit2
- 10.3 JGit
- 10.4 go-git
- 10.5 Dulwich
-
A1. Приложение C: Git команди
- A1.1 Настройки и конфигурация
- A1.2 Издърпване и създаване на проекти
- A1.3 Snapshotting
- A1.4 Клонове и сливане
- A1.5 Споделяне и обновяване на проекти
- A1.6 Инспекция и сравнение
- A1.7 Дебъгване
- A1.8 Patching
- A1.9 Email команди
- A1.10 Външни системи
- A1.11 Административни команди
- A1.12 Plumbing команди
5.5 Git инструменти - Търсене
Търсене
Независимо от размера на даден проект, често ще ви се налага да потърсите къде дадена функция се вика или къде е дефинирана, или пък да покажете историята на метод. Git осигурява полезни инструменти за търсене в кода и къмитите в базата данни бързо и лесно. Ще разгледаме някои от тях.
Git Grep
Git идва с командата grep
, позволяваща ви лесно да търсите по стринг или регулярен израз във всяко къмитнато дърво, в работната директория и дори в индексната област.
За примерите, които следват ще търсим в сорс кода на самия Git.
По подразбиране, git grep
ще търси само във файловете от работната директория.
Като първи вариант, можете да използвате флага -n
или --line-number
за да отпечатете номерата на редовете, в които Git намира съвпадения:
$ 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
В допълнение към тази основна функционалност, git grep
поддържа множество интересни опции.
Например, вместо да отпечатвате всички попадения, може да инструктирате командата да съкрати изхода и да покаже само кои файлове съдържат търсения стринг и колко пъти чрез флага -c
или --count
:
$ 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
Ако се интересувате от контекста в който се използва търсения стринг, можете да покажете цялата функция/метод с опцията -p
или --show-function
:
$ 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 */
Както се вижда, gmtime_r
се извиква от функциите match_multi_number
и match_digit
във файла date.c
(третият намерен резултат съдържа търсения стринг в коментар).
Можете също да търсите за сложни комбинации от стрингове с флага --and
, което указва че на един ред трябва да има повече съвпадения.
Например, нека потърсим всички редове код, които дефинират константа, чието име съдържа кой да е от подстринговете “LINK” или “BUF_MAX” специфично в по-стара версия на Git сорса маркирана с тага v1.8.0
(ще подадем флаговете --break
и --heading
, които помагат да разделим изхода в по-четим формат):
$ 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
има няколко предимства пред нормалните команди за търсене като grep
и ack
.
Първо, тя е наистина много бърза и второ - позволява търсене във всяко дърво в Git, не само в работната директория.
Както видяхме в предния пример, ние търсехме в контекста на по-стара версия на сорс кода на Git, а не в текущата версия извлечена в работната ни област.
Търсене в Git Log
Може би търсите не къде съществува дадено нещо, а кога е съществувало или въведено.
Командата git log
има много мощни инструменти за намиране на специфични къмити по съдържанието на техните съобщения и дори по съдържанието на diff информацията, която въвеждат.
Ако например искаме да разберем кога константата ZLIB_BUF_MAX
е била първоначално въведена в кода, можем да използваме флага -S
(разговорно позната като Git “pickaxe” опция) за да укажем на Git да ни изведе само тези къмити, които са променили броя на срещанията на този стринг.
$ 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
Ако погледнем diff-а на тези къмити, можем да видим, че константата е била въведена в ef49a7a
и променена в e01503b
.
Ако се нуждаете от по-голяма прецизност, можете да подадете регулярен израз с -G
опцията.
Line Log търсене
Друга особено полезна възможност е опцията за търсене на историята на ред от код.
Просто пуснете git log
с флага -L
и ще получите историята на функция или ред от код в сорса.
Например, ако искаме да видим всяка промяна направена във функцията git_deflate_bound
от файла zlib.c
, можем да изпълним командата git log -L :git_deflate_bound:zlib.c
.
Тя ще опита да установи кои са границите на дефиницията на функцията и след това, гледайки през историята на промените, ще ни покаже всяка една редакция в кода като серия от пачове — чак до момента на дефинирането ѝ за първи път.
$ 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 не съумее да установи дефиницията на функция или метод във вашия програмен език, можете да подпомогнете търсенето с регулярен израз (regex).
Например, същото нещо от примера по-горе можем да получим с командата git log -L '/unsigned long git_deflate_bound/',/^}/:zlib.c
.
Можете също да подадете набор от редове или единичен ред и ще получите същия тип резултат.