Git
Chapters ▾ 2nd Edition

7.10 Git Araçları - Git’le Hata Ayıklama

Git’le Hata Ayıklama

Git, öncelikle sürüm kontrolüne yönelik olmasının yanı sıra, kaynak kodu projelerinizde hata ayıklamanıza yardımcı olacak birkaç komut da sağlar. Git neredeyse her türlü içeriği işleyecek şekilde tasarlandığından, bu araçlar oldukça genel amaçlı olsa dahi; işler ters gittiğinde hata veya sorumluyu bulmanıza yardımcı olabilirler.

Dosya Açıklaması (git blame)

Eğer kodunuzda bir hatayı bulduğunuzda, ne zaman ve neden eklendiğini öğrenmek istiyorsanız; herhangi bir dosyanın her bir satırını değiştiren son katkıyı gösteren dosya açıklaması genellikle en iyi aracınızdır. Hir. Bu nedenle, projenizde hatalı bir kod olduğunu görürseniz, git blame ile dosyayı açımlayarak; o satırın eklenmesinden sorumlu olan katkıyı belirleyebilirsiniz.

Aşağıdaki örnekte, Linux çekirdeğindeki Makefile satırlarının hangisinden, hangi katkı ve katkılayıcının sorumlu olduğunu belirlemek için git blame kullanılır ve daha da ileri giderek, -L seçeneğini kullanarak bu dosyanın 69 ile 82 satırları arasındaki acıklamanın çıktısı kısıtlanır:

$ git blame -L 69,82 Makefile
b8b0618cf6fab (Cheng Renquan  2009-05-26 16:03:07 +0800 69) ifeq ("$(origin V)", "command line")
b8b0618cf6fab (Cheng Renquan  2009-05-26 16:03:07 +0800 70)   KBUILD_VERBOSE = $(V)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) ifndef KBUILD_VERBOSE
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73)   KBUILD_VERBOSE = 0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75)
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 76) ifeq ($(KBUILD_VERBOSE),1)
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 77)   quiet =
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 78)   Q =
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 79) else
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 80)   quiet=quiet_
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 81)   Q = @
066b7ed955808 (Michal Marek   2014-07-04 14:29:30 +0200 82) endif

Dikkat ederseniz, ilk alan, bu satırı son değiştiren katkının kısmi SHA-1’idir. Sonraki iki alan, bu katkıdan çıkarılan değerlerdir — katkı yazarı ve katkı tarihi — böylece bu satırı kimin ve ne zaman değiştirdiğini kolayca görebilirsiniz. Sonrasında satır numarası ve dosyanın içeriği gelir. Ayrıca, ^1da177e4c3f4 katkı satırlarına dikkat edin, burada ^ ön eki, repo’nun ilk katkısında tanıtılan ve o zamandan beri değişmeden kalan satırları belirtir. Git’in bir katkının SHA-1’ini değiştirmek için ^ ön ekini en az üç farklı şekilde kullandığını gördüğünüz için bu biraz kafa karıştırabilir, ancak burada ne anlama geliyor!

Git’in başka harika bir özelliği de dosya adı değişikliklerini açıkça izlemiyor olmasıdır. Anlık pozları kaydeder ve neyin ne şekilde yeniden adlandırıldığını sonradan örtük olarak çözmeye çalışır. Bunun ilginç bir yanı da, ona kod hareketlerini çözmesini isteyebilmenizdir. git blame komutuna -C seçeneğini işlerseniz, işaretlediğiniz dosyayı analiz eder ve eğer içindeki kod parçaları başka yerden kopyalanmışsa, orijinal olarak nereden geldiğini bulmaya çalışır. Örneğin, GITServerHandler.m adlı bir dosyayı, içlerinden biri GITPackUpload.m adında, birden fazla dosyaya böldüğünüzü düşünelim. GITPackUpload.m komutunu -C seçeneği ile işaretlediğinizde, kodun hangi bölümlerinin orijinal olarak nereden geldiğini görebilirsiniz:

$ git blame -C -L 141,153 GITPackUpload.m
f344f58d GITServerHandler.m (Scott 2009-01-04 141)
f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC
f344f58d GITServerHandler.m (Scott 2009-01-04 143) {
70befddd GITServerHandler.m (Scott 2009-03-22 144)         //NSLog(@"GATHER COMMI
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 145)
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 146)         NSString *parentSha;
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 147)         GITCommit *commit = [g
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 148)
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 149)         //NSLog(@"GATHER COMMI
ad11ac80 GITPackUpload.m    (Scott 2009-03-24 150)
56ef2caf GITServerHandler.m (Scott 2009-01-05 151)         if(commit) {
56ef2caf GITServerHandler.m (Scott 2009-01-05 152)                 [refDict setOb
56ef2caf GITServerHandler.m (Scott 2009-01-05 153)

Bu gerçekten kullanışlıdır. Normalde, kodu kopyaladığınızda orijinal katkı, bu dosyadaki bu satırlara ilk dokunduğunuz zamandır. Git size, başka bir dosyada olsa bile, bu satırları yazdığınız orijinal katkıyı söyler.

Sorunun nerede başladığını bildiğinizde, dosyayı açıklamak daha olur. Eğer neyin bozulduğunu bilmiyorsanız ve kodun en son düzgün çalıştığını bildiğiniz durumdan bu yana onlarca veya yüzlerce katkı yapıldıysa, muhtemelen yardım için git bisect yöntemine başvuracaksınız. bisect komutu, bir sorunu tanımlamanıza yardımcı olmak için katkı geçmişinizde ikilik bir arama yapar ve olabildiğince hızlı bir şekilde hangi katkının soruna yol açtığını belirlemenize yardımcı olur.

Diyelim ki kodunuzu üretim ortamına yeni bir sürüm olarak gönderdiniz, geliştirme ortamınızda olmayan bir şey hakkında hata raporları alıyorsunuz ama kodun neden böyle bir şey yaptığını anlayamıyorsunuz. Koda geri dönüyorsunuz ve sorunu yeniden üretebildiğinizi fark ediyorsunuz, ancak neyin yanlış gittiğini yine anlayamıyorsunuz. Sorunu bulmak için bisect komutunu kullanarak kodunuzu bölebilirsiniz. Öncelikle işleri başlatmak için git bisect start komutunu çalıştırırsınız, sonra sistemde bulunduğunuz mevcut katkının bozuk olduğunu söylemek için git bisect bad komutu çalıştırırsınız. Daha sonra, en son bilinen iyi durumun ne zaman olduğunu bisect’e bildirmeniz gerekir, bunu git bisect good <iyi_katkı> kullanarak yaparsınız:

$ git bisect start
$ git bisect bad
$ git bisect good v1.0
Bisecting: 6 revisions left to test after this
[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] error handling on repo

Git, son iyi katkı olarak işaretlediğiniz katkı (v1.0) ile şu anki kötü sürüm arasında yaklaşık 12 katkı olduğunu çözümledi ve sizin için ortadakini getirdi. Bu noktada, bu katkı ile aynı sorunun var olup olmadığını görmek için testinizi çalıştırabilirsiniz. Eğer varsa, o zaman sorun bu ortadaki katkıdan önceki bir zamanda ortaya çıkmıştır; eğer yoksa, o zaman sorun bu ortadaki katkıdan sonra bir zamandaki bir katkıdan kaynaklanmıştır. Burada sorun olmadığını anlaşıldı ve bunu Git’e git bisect good yazarak bildirir ve yolculuğunuza devam edersiniz:

$ git bisect good
Bisecting: 3 revisions left to test after this
[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing

Şimdi, biraz önce test ettiğiniz katkıyla, kötü katkınız arasında bir katkıda bulunuyorsunuz. Testinizi tekrar çalıştırırsınız ve bu katkının da bozuk olduğunu bulursunuz, bu yüzden bunu Git’e git bisect bad ile bildirirsiniz:

$ git bisect bad
Bisecting: 1 revisions left to test after this
[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table

Bu katkı sorunsuzdur ve şimdi Git sorunun nerede başladığını belirlemek için gereken tüm bilgilere sahip olmuştur. İlk kötü katkının SHA-1’ini size söyler ve bu katkıda değiştirilen bazı dosyaların bilgilerini gösterir, böylece bu hataya yol açabilecek olan şeyin ne olduğunu anlayabilirsiniz:

$ git bisect good
b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit
commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04
Author: PJ Hyett <pjhyett@example.com>
Date:   Tue Jan 27 14:48:32 2009 -0800

    secure this thing

:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730
f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M  config

İşiniz bittiğinde, başladığınız yere HEAD’inizi sıfırlamak için git bisect reset komutunu çalıştırmalısınız, aksi takdirde garip bir durumda kalırsınız:

$ git bisect reset

Bu, bir projede ortaya çıkan bir hatayı kontrol etmek için yüzlerce katkıyı dakikalar içinde kontrol etmenize yardımcı olabilecek çok güçlü bir araçtır. Aslında, eğer proje iyiyse "0" (sıfır) ve proje kötüyse "non-0" (sıfırdışı) sonuç dönderecek bir betiğiniz varsa, git bisect 'i tamamen otomatik hale getirebilirsiniz. İlk olarak, bilinen kötü ve iyi katkıları belirterek bisect’in kapsamını tekrar söylersiniz. Bunu yapmak için: ilk olarak bilinen kötü katkıları ve ikinci olarak bilinen iyi katkıları, bisect start komutuyla listeleyebilirsiniz:

$ git bisect start HEAD v1.0
$ git bisect run test-error.sh

Bunu yaparak, Git’in ilk bozuk katkıyı bulana kadar her bir çıkan katkıda test-error.sh betiğini otomatik olarak çalıştırmasını sağlarsınız. Ayrıca, make veya make tests gibi sizin için otomatik testleri çalıştıran herhangi bir betiği de çalıştırabilirsiniz.

scroll-to-top