Normal ifadeye dayalı olarak yalnızca bir farkın / yamanın ilgili bölümlerini görüntüle


20

git log -G<regex> -pbir kod tabanının geçmişini belirtilen kalıpla eşleşen değişiklikler için aramak için harika bir araçtır. Bununla birlikte, çoğunlukla ilgisiz iri denizde diff / patch çıktısında ilgili iri bulmak çok zor olabilir.

Elbette git logorijinal dizginin / regex'in çıktısını aramak mümkündür , ancak görsel paraziti ve ilgisiz birçok değişikliğin dikkatini dağıtmak için çok az şey yapar.

Okurken git log, --pickaxe-allistediğim şeyin tam tersi olduğunu görüyorum: çıktıyı genişletiyor (tüm değişiklik kümesine), oysa onu sınırlamak istiyorum (belirli bir hunk ile).

Esasen, fark / yamayı tek tek parçalara "akıllıca" ayrıştırmanın ve sonra her bir parçaya (sadece değişen satırları hedefleyen) karşı bir arama yürütmenin, eşleşmeyen parçaların atılmasının ve çıktıların alınmasının bir yolunu arıyorum öyle.

Anlattığım gibi bir araç var mı? Eşleşen / etkilenen yakışıklılıkları almak için daha iyi bir yaklaşım var mı?

Yaptığım bazı ilk araştırmalar ...

  • grepDiff / patch çıkışı mümkün olduğunda ve bağlam seçeneği değerlerini dinamik hale getirirse ( örneğin, satır sayıları yerine regexps aracılığıyla) bu yeterli olabilir. Ama greptam olarak bu şekilde inşa edilmedi (ne de bu özelliği talep etmiyorum).

  • Başlangıçta benim ihtiyaçlarına uygun gibi geliyordu patchutils paketi buldum . Ancak mansayfalarını okuduktan sonra , araçlar normal ifadelere dayalı eşleşen öbekleri işlemiyor gibi görünmüyor. (Bununla birlikte, bir parça listesini kabul edebilirler ...)

  • Sonunda , yamanın ayrıştırılmasını iyi işleyen splitpatch.rb ile karşılaştım , ancak okuma yamalarını ele almak stdin, istenen yakışıklılıkları eşleştirmek ve sonra iri parçaların çıktısını almak için önemli ölçüde artırılması gerekir .


1
Tam olarak ne istediğini değil ama git log deneyin -Gfoo | daha az + / foo
James Youngman

Yanıtlar:


7

burada /programming//a/35434714/5305907 aradığınızı yapmanın bir yolu açıklanmaktadır. etkili bir şekilde:

git diff -U1 | grepdiff 'console' --output-matching=hunk

Yalnızca belirtilen dize "konsol" ile eşleşen iri parçaları gösterir.


Teşekkürler. grepdifftemelde istediğim şey; onun hunk-eşleşen seçeneği kaçırmış olmalı! Bununla birlikte ... git kesin bilgisi kaldırılır grepdiff, bu yüzden ilgili iri parçayı bulduktan sonra, tamamlama sha'ını diff üstbilgisindeki nesne / damla sha'dan ayırmanız gerekir - oldukça pahalı bir işlem. ( stackoverflow.com/a/223890/2284440 adresine bakın ) böyle bir şey olurdugit find-object SHA --reverse | head -1 | cut -c 1-7 | { read sha ; git log -1 $sha; }
wrksprfct

ayrıca kabul edilen argümanlar açısından daha barebone olan bir golang versiyonunun olduğunugrepdiff unutmayın . eşleşen iri bir farkın son iri olduğunda, yanlış bir şekilde aşağıdaki taahhüdün git taahhüt başlığını içerir - neler olduğunu anlayana kadar beni tamamen şaşırtan bir şey!
wrksprfct

0

Tam olarak ne istediğinizi değil, yakışıklılıklardan kaçmanın bir yolu etkileşimli ekleme modudur. Bu, ilgilendiğiniz yamadan sonra taahhüdü kontrol etmenizi gerektirir

git checkout COMMIT_ID

VCS'de bir adım daha geriye gidin, ancak çalışma dizinine dönmeyin

git reset --soft HEAD^

(Bu noktada, dizin ile çalışma dizini arasındaki fark ilgilendiğiniz yamaya karşılık gelir.)

Şimdi çalıştırabilirsiniz git add -p. Bu, /bazı satırların normal ifadeyle eşleştiği öbekleri bulmanıza izin veren, seçeneği olan etkileşimli bir oturum başlatır . Bu yamaları daha fazla işlemek istiyorsanız özellikle yararlıdır (kısmi bir kiraz toplama hazırlamak gibi).

Ne yazık ki, en azından şu andaki /komut add -psadece tek bir dosyada çalışıyor, bu nedenle birkaç alakasız dosyayı atlamanız gerekebilir.


0

@Nagu tarafından verilen cevaba ve diğer bağlantılı cevaplara dayanarak, git log -Gsadece ilgili parçaları gösterebildim.

  1. Öncelikle bu içerikle $ PATH'nızda bir yerde bir komut dosyası oluşturun:

    #!/bin/bash
    
    # pickaxe-diff : external diff driver for Git.
    #                To be used with the pickaxe options (git [log|show|diff[.*] [-S|-G])
    #                to only show hunks containing the searched string/regex.
    
    path=$1
    old_file=$2
    old_hex=$3
    old_mode=$4
    new_file=$5
    new_hex=$6
    new_mode=$7
    
    filtered_diff=$(diff -u -p $old_file $new_file | \
                    grepdiff "$GREPDIFF_REGEX" --output-matching=hunk | \
                    grep -v -e '+++ ' -e '--- ')
    
    a_path="a/$path"
    b_path="b/$path"
    
    echo "diff --git $a_path $b_path"
    echo "index $old_hex..$new_hex $old_mode"
    echo "--- $a_path"
    echo "+++ $b_path"
    echo "$filtered_diff"
  2. git log -GGit'i arayın ve pickaxe-diffkomut dosyasını harici bir fark sürücüsü olarak kullanmasını söyleyin :

    export GREPDIFF_REGEX=<string>; 
    GIT_EXTERNAL_DIFF=pickaxe-diff git log -p --ext-diff -G $GREPDIFF_REGEX

    Bu, sadece farkları oluşturmak için kazma-diff komut dosyasını kullanır, böylece git logçıktının geri kalanına (taahhüt karması, mesaj vb.) Dokunulmaz.

Uyarı
Git kazma çalışma biçimi, çıktıları verilen dizeyi / normal ifadeyi değiştiren dosyalarla sınırlandırmasıdır . Bu, bu dosyalarda başka bir iri parça da arama dizesini / regex'i içeriyor, ancak değiştirmiyorsa, yukarıdaki komut dosyasıyla görüntülenmeye devam edeceği anlamına gelir. Bu grepdiff'in bir sınırlamasıdır. Patchutils projesinde grepdiff'e bir --only-matchingbayrak eklemek için açık bir çekme isteği var , bu da bu iri parçaların doğru bir şekilde filtrelenmesi için gerekli işlevselliği sağlayacaktır.


Bu özümde çözümümün bir yazısını yaptım .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.