2016-08-10 4 views
7

गिट कमांड के नाम के बाद फ़ाइल का पालन करने के लिए एक उपयोगी कमांड है, जैसा कि git log --follow path/to/some/file में है। दुर्भाग्यवश, यह केवल एक व्यक्तिगत फ़ाइल के लिए काम करता है। मैं git log --follow some/directory के बराबर करने में सक्षम होना चाहता हूं।क्या गिट लॉग करने के लिए कोई चाल है - एक निर्देशिका का नाम बदल दिया गया है जिसका नाम बदल दिया गया है?

ऐसा करने का एक तरीका शायद git ls-tree के आउटपुट को मालिश करना होगा और लूप में ऐसा करना होगा, लेकिन तब समस्या यह हो जाती है कि कई फाइलों को प्रभावित करने से एक प्रतिबद्धता में "सहवास" नहीं किया जाएगा।

क्या ऐसा करने का कोई बेहतर तरीका है? नोट: का उपयोग कर Git 2.7.4

+0

अच्छा सवाल। क्या आपको अभी तक कोई जवाब मिला है? – hsalimi

उत्तर

4

सं

Git निर्देशिका, केवल फ़ाइलों को स्टोर नहीं करता है। जब आप git log या git diff जैसे आदेशों पर किसी भी पथ नाम का उपयोग करते हैं जो पूरे कामों को देखते हैं, तो गिट अनिवार्य रूप से "पूरी प्रतिबद्धता से शुरू होता है, फिर उस पथ से मेल खाने वाली फाइलों को संक्षिप्त करें"। यहां निर्देशिकाएं में निर्देशिका में प्रत्येक फ़ाइल का चयन करने के लिए बस हवाएं बनती हैं।

--follow विकल्प केवल एक फ़ाइल का पालन कर सकते हैं। इसलिए यदि आप इसे किसी निर्देशिका पर लागू करने के लिए प्रबंधित कर सकते हैं, तो गिट पहले निर्देशिका को फ़ाइलों के एक सेट में बदल देगा, फिर उन फ़ाइलों में से एक चुनें और केवल उस का पालन करें।

(वास्तविक --follow कोड बहुत hacky है यह नाम बदलने का पता लगाने कोड बंद का लाभ उठाता है, लेकिन केवल जब प्रतिबद्ध में तुलना की जा रही हैं काम करता है नए-से-बड़े आदेश:।। यदि आप --reverse जोड़ने के लिए, --follow कभी नहीं सब पर काम करता है शायद पूरी चीज को फेंकने और फिर से कोड करने की जरूरत है। शायद इसे दोबारा कोड करके, आप इसे कई फाइल नामों और यहां तक ​​कि फाइलों से भरे निर्देशिकाओं को भी संभाल सकते हैं।)

+0

मुझे पता है कि केवल फाइलें संग्रहीत हैं; मैंने सोचा कि शायद किसी ने एक समाधान किया है, यहां तक ​​कि हैकिश ... कौन जानता है :) – fge

0

एक अंतर्निहित तरीका प्रतीत नहीं होता है यह करने के लिए।

  • प्रत्येक फ़ाइल के लिए प्रतिबद्ध इसके साथ जुड़े की एक सूची उत्पन्न
  • सभी सूचियां संयोजित और उन पर एक स्थिर तरह ऐसा करते हैं (:

    एक यह एक स्क्रिप्ट का उपयोग कर और एक सरल एल्गोरिथ्म निम्न कर सकते हैं मुश्किल है, क्योंकि प्रतिबद्ध की निर्धारित करने के आदेश यह सब कम

के माध्यम से यहाँ एक हैक है सीधा)

  • Iteratively करता और पाइप से प्रत्येक के लिए Git लॉग निष्पादित नहीं है yy python 3 और sh मॉड्यूल का उपयोग करके ऐसा करने का तरीका, विभिन्न कारणों से विंडोज पर काम नहीं करेगा।

    #!/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:]) 
    

    अब, यह स्क्रिप्ट में केवल अपनी जरूरतों को पूरा नहीं करता है, क्योंकि यह फ़ाइलों की एक सूची लेता है, लेकिन आप एक ग्लोब का उपयोग कर इसे निष्पादित कर सकते हैं और यह आपके लिए क्या देख रहे हैं करेंगे।

    ./script.py src/* 
    
  • संबंधित मुद्दे

     संबंधित मुद्दे