2016-08-10 17 views
7

Git komutunun, git log --follow path/to/some/file'daki gibi, bir ad verildikten sonra bir dosyayı takip etmek için kullanışlı bir komutu vardır. Ne yazık ki, sadece tek bir dosya için çalışır. git log --follow some/directory eşdeğerini yapabilmek istiyorum.Git kaydı için bir numara var mı - yeniden adlandırılmış bir dizini takip ediyor musunuz?

Bunu yapmanın bir yolu muhtemelen git ls-tree çıkışına masaj yapmak ve bunu bir döngüde yapmak olabilir, ancak sorun daha sonra birden çok dosyayı etkileyen işlemlerin tek bir işlemde "birleştirilemeyeceği" olur.

Bunu yapmanın daha iyi bir yolu var mı? Not: kullanarak git 2.7.4

+0

İyi soru. Henüz bir cevap buldunuz mu? – hsalimi

cevap

4

sayılı

Git dizinleri, dosyaları saklamaz. Tüm işlemlerin tümüne bakacak şekilde git log veya git diff gibi komutlara herhangi bir yol adı kullandığınızda Git, esas olarak "tüm işlemle başla, sonra da bu yolla eşleşen dosya (lar) 'a küçült" der. Buradaki dizinler, numaralı dizindeki her dosya için 'u seçer.

--follow seçeneği yalnızca bir dosyayı izleyebilir. Yani bir şekilde bir dizine başvurmayı başarmış olsaydınız, Git dizini önce bir dizi dosyaya dönüştürür, ardından bu dosyalardan birini seçer ve sadece onu takip eder. .

(gerçek --follow kod O adlandırma algılama kodunu kapalı güçlendirir korkunç hacky, ama sadece kaydedilmesini karşılaştırıldığında ediliyor çalışır yeni-to-yaşlı sırayla:. Eğer --reverse eklerseniz, --follow asla hiç çalışır Muhtemelen her şeyin dışarı atılması ve yeniden kodlanması gerekir. Belki de yeniden kodlayarak, birden çok dosya adını ve hatta dosyalarla dizinleri bile başarabilirsiniz.)

+0

Sadece dosyaların saklandığını biliyorum; Belki birisinin bir çözüm ürettiğini, hatta hack olduğunu düşündüm ... Kim bilir :) – fge

0

Yerleşik bir yol yok gibi görünüyor. Bunu yapmak için. (

  • tüm listeleri birleştirin ve üzerlerinde istikrarlı bir sıralama yapmak onunla ilişkili taahhüt eder bir listesini oluşturmak

    • her dosya için bu:

      biri bu bir komut dosyası kullanarak ve basit bir algoritma aşağıdakileri yapabilirsiniz kaydedilmesini belirleyici sipariş hepsi İşte kesmek az

    aracılığıyla

  • yinelemeli kaydedilmesini ve borunun her biri için git günlüğünü yürütmek) kolay değildir, çünkü zordur python 3 ve sh modülünü kullanarak bunu yapmanın yolu, çeşitli nedenlerle Windows üzerinde çalışmayacaktır.

    #!/usr/bin/env python3 
    
    import os 
    import shlex 
    import sys 
    import tempfile 
    
    import sh 
    
    def _get_commits(fname): 
        # Ask for the commit and the timestamp 
        # .. the timestamp doesn't guarantee ordering, but good enough 
        for c in sh.git('log', '--follow', '--pretty=%ct %h', fname, 
            _tty_out=False, _iter=True): 
         c = c.strip().split() 
         yield int(c[0]), c[1] 
    
    def git_log_follow_multi(filenames): 
        if len(filenames) == 0: 
         print("Specify at least one file to log") 
        elif len(filenames) <= 1: 
         os.system('git log --follow -p %s' % filenames[0]) 
        else: 
         # Use git log to generate lists of commits for each file, sort 
         commits = [] 
         for fname in filenames: 
          commits += _get_commits(fname) 
    
         # Sort the lists (python's sort is stable) 
         commits.sort(reverse=True) 
    
         # Uniquify (http://www.peterbe.com/plog/uniqifiers-benchmark) 
         seen = set() 
         seen_add = seen.add 
         commits = [c for c in commits if not (c in seen or seen_add(c))] 
    
         # Finally, display them 
         tname = None 
    
         try: 
          file_list = ' '.join(shlex.quote(fname) for fname in filenames) 
    
          with tempfile.NamedTemporaryFile(mode='w', delete=False) as fp: 
           tname = fp.name 
           for _, commit in commits: 
            fp.write('git log -p -1 --color %s %s\n' % (commit, file_list)) 
    
          # Use os.system to make our lives easier 
          os.system('bash %s | less -FRX' % tname) 
         finally: 
          if tname: 
           os.unlink(tname) 
    
    
    if __name__ == '__main__': 
        git_log_follow_multi(sys.argv[1:]) 
    

    Şimdi, dosyaların bir listesini alır çünkü bu komut dosyası tam olarak ihtiyaçlarını karşılamak değil, ama bir topak kullanarak yürütebileceği ve bunu aradığınızı yapacağız.

    ./script.py src/* 
    
  • İlgili konular