'गिट लॉग' बनाना कुछ रास्तों के लिए परिवर्तनों को अनदेखा करता है


121

मैं git logकेवल वही दिखावा कैसे कर सकता हूं जो मेरे द्वारा निर्दिष्ट की गई फ़ाइलों के अलावा बदल गई हो?

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

मुझे जो चाहिए वो मुझे मिल सकता है

git log --format="%n/%n%H" --name-only | ~/filter-log.pl | git log --stdin --no-walk

कहाँ filter-log.plहै:

#!/usr/bin/perl
use strict;
use warnings;

$/ = "\n/\n";
<>;

while (<>) {
    my ($commit, @files) = split /\n/, $_;

    if (grep { $_ && $_ !~ m[^(/$|.etckeeper$|lvm/(archive|backup)/)] } @files) {
        print "$commit\n";
    }
}

सिवाय इसके कि मैं उससे कुछ अधिक सुरुचिपूर्ण चाहता हूं।

ध्यान दें कि मैं यह नहीं पूछ रहा हूँ कि फ़ाइलों को कैसे अनदेखा करें। इन फ़ाइलों को ट्रैक और प्रतिबद्ध किया जाना चाहिए । यह सिर्फ इतना है कि, ज्यादातर समय, मुझे उन्हें देखने में कोई दिलचस्पी नहीं है।

संबंधित प्रश्न: कैसे 'इनट लॉग -ग्रेप = <पैटर्न>' को उलटा करें या कैसे गेट लॉग को दिखाएं कि यह एक पैटर्न से मेल नहीं खाता है यह पथ के बजाय प्रतिबद्ध संदेशों को छोड़कर एक ही सवाल है।

2008 से इस विषय पर फोरम चर्चा: पुन: git-diff से फ़ाइलों को छोड़कर यह आशाजनक लग रहा था लेकिन धागा सूख गया है।


मुझे यकीन नहीं है कि अगर कोई अंतर्निहित तरीका है, और आपका पर्ल समाधान बहुत सभ्य है। यदि आप इसे कमांड-लाइन तर्कों के रूप में पथों को स्वीकार करने के लिए संशोधित करते हैं, तो आप बस कुछ और जैसा एक उपनाम बना सकते हैं !f() { git log ... | path/to/filter-log.pl "$@" | git log --stdin --no-walk; f, या उस पाइपलाइन भाग को स्क्रिप्ट में भी लपेट सकते हैं।
Cascabel

वर्कअराउंड के रूप में, मैं findउन डाइरेक्टरीज़ को फ़िल्टर करने के लिए उपयोग करता हूँ जिनके कॉमेट्स मैं देखना नहीं चाहता। अगर मैं रूट-स्तरीय निर्देशिका में किए गए कमिट से लॉग एंट्रीज़ को नज़रअंदाज़ करना चाहता था, SiteConfigतो मैं कहूँगा:git log `find . -type d -mindepth 1 -maxdepth 1 ! -name *SiteConfig`
नूह सुस्मान

Git 1.9 / 2.0 (Q1 2014) के लिए, नीचे मेरा उत्तर देखें : git log --oneline --format=%s -- . ":!sub"काम करेंगे ( pathspec मैजिक :(exclude)और इसके संक्षिप्त रूप के साथ:! )
VONC

जवाबों:


214

इसे अब लागू किया गया है (git 1.9 / 2.0, Q1 2014) परिचय पथस्पेक जादू के साथ :(exclude)और इसके संक्षिप्त रूप:! में ef79b1f और 1649612 प्रतिबद्ध है , Nguy Thn Thái Ngọc Duy ( pclouds) द्वारा , प्रलेखन यहां पाया जा सकता है

अब आप सब-फोल्डर सामग्री को छोड़कर सब कुछ लॉग कर सकते हैं:

git log -- . ":(exclude)sub"
git log -- . ":!sub"

या आप उस उप-फ़ोल्डर के भीतर विशिष्ट तत्वों को बाहर कर सकते हैं

  • एक विशिष्ट फ़ाइल:

      git log -- . ":(exclude)sub/sub/file"
      git log -- . ":!sub/sub/file"
    
  • किसी भी फ़ाइल के भीतर sub:

      git log -- . ":(exclude)sub/*file"
      git log -- . ":!sub/*file"
      git log -- . ":(exclude,glob)sub/*/file"
    

आप उस अपवर्जन मामले को असंवेदनशील बना सकते हैं!

git log -- . ":(exclude,icase)SUB"

जैसा कि केनी एविट ने नोट किया

यदि आप बैश शेल में गिट चला रहे हैं, तो त्रुटियों से बचने के लिए उपयोग करें ':!sub'या ":\!sub"इसके बजायbash: ... event not found


नोट: Git 2.13 (Q2 2017) एक पर्याय जोड़ देगा ^करने के लिए!

देखें प्रतिबद्ध 859b7f1 , प्रतिबद्ध 42ebeb9 (08 फ़र, 2017) द्वारा लिनुस टोर्वाल्ड ( torvalds)
( जूनियो सी gitsterहमानो द्वारा विलय - - में 015fba3 , 27 फरवरी 2017)

pathspec जादू: ' ^' के रूप में उपनाम के लिए ' !' जोड़ें

!नकारात्मक पैथस्पेक के लिए ' ' का चुनाव न केवल उन बदलावों के लिए होता है जो हम संशोधन के लिए करते हैं, यह शेल विस्तार के लिए एक भयानक चरित्र है क्योंकि इसे उद्धृत करने की आवश्यकता है।

तो ^एक छोड़कर अन्य pathspec प्रविष्टि के लिए वैकल्पिक उपनाम के रूप में ' ' जोड़ें ।


ध्यान दें कि, Git 2.28 (Q3 2020) से पहले, कार्यशील पेड़ में अनट्रैक वाले सहित रास्तों को इकट्ठा करते हुए, नकारात्मक पाथसेक का उपयोग टूट गया था।

Elijah Newren ( ) द्वारा प्रतिबद्ध f1f061e (05 जून 2020) देखें । (द्वारा विलय Junio सी Hamano - - में प्रतिबद्ध 64efa11 , 18 जून 2020)newren
gitster

dir: नकारात्मक रोगाणुओं के उपचार को ठीक करें

रिपोर्ट-बाय: जॉन मिलिकिन
साइन-ऑफ-बाय: एलिजा न्यूरेन

do_match_pathspec()के रूप में match_pathspec_depth_1()और शुद्धता के लिए जीवन शुरू किया था केवल से बुलाया जाना चाहिए था match_pathspec_depth() match_pathspec_depth()बाद में इसका नाम बदल दिया गया था match_pathspec(), इसलिए आज हम जिस अपरिवर्तनीय की उम्मीद करते हैं, do_match_pathspec()उसका कोई प्रत्यक्ष कॉल करने वाला नहीं है match_pathspec()

दुर्भाग्य से, इस इरादे को दो कार्यों के नाम के साथ खो दिया गया था, और अतिरिक्त कॉल कॉमा 75a6315f74do_match_pathspec() में जोड़े गए थे (" : सबमॉडुल्स के लिए पैथस्पेक मिलान जोड़ें", 2016-10-07, Git v2.11.0-rc0 - मर्ज में सूचीबद्ध बैच # 11 ) और 89a1f4aaf7 (" : यदि हमारा पैथस्पेक एक डीआईआर के तहत फाइलों से मेल खा सकता है, तो इसमें पुनरावृत्ति करें", 2019-09-17, Git v2.24.0-rc0)।ls-filesdir

बेशक, do_match_pathspec()एक महत्वपूर्ण अधिकार था match_pathspec()- match_pathspec()दो मूल्यों में से एक को झंडे को हार्डकोड करेगा, और इन नए कॉलर्स को झंडे के साथ कुछ अन्य मूल्य पारित करने की आवश्यकता थी।

हालांकि, हालांकि do_match_pathspec()सीधे कॉल करना गलत था, लेकिन अवलोकन योग्य अंतिम आउटपुट में कोई अंतर होने की संभावना नहीं थी, क्योंकि बग का मतलब सिर्फ यही था कि fill_diretory()अनावश्यक निर्देशिकाओं में पुनरावृत्ति होगी।

चूंकि बाद में निर्देशिका के तहत व्यक्तिगत पथों पर यह पथ-मिलान-मिलान जाँच होती है, जिससे उन अतिरिक्त पथों को फ़िल्टर किया जा सकता है, गलत फ़ंक्शन का उपयोग करने से एकमात्र अंतर अनावश्यक संगणना था।

उन बुरे कॉलों में से दूसरा do_match_pathspec()शामिल था - या तो सीधे आंदोलन के माध्यम से या प्रतिलिपि + संपादन के माध्यम से - बाद के कई रिफ्लेक्टरों में।

देखें 777b420347 (" dir: सिंक्रनाइज़ करें treat_leading_path()और read_directory_recursive()", 2019-12-19, Git v2.25.0-rc0 - मर्ज ), 8d92fb2927 (" dir: एक रैखिक एक के साथ घातीय एल्गोरिथ्म को बदलें", 2020-04-01, git v2.27.0 -rc0 - बैच # 5 में सूचीबद्ध मर्ज ), और 95c11ecc73 ("त्रुटि-प्रवण विकलांगता को ठीक करें ", इसे केवल माचिस लौटाएं ", 2020-04-01, Git v2.27.0-rc0 - बैच 5 में सूचीबद्ध मर्ज ) ।fill_directory()

उनमें से अंतिम ने do_match_pathspec()एक व्यक्तिगत फ़ाइल के उपयोग की शुरुआत की , और इस तरह व्यक्तिगत पथ वापस आ गए जो नहीं होना चाहिए।

इसके do_match_pathspec()बजाय कॉलिंग के साथ समस्या यह match_pathspec()है कि किसी भी नकारात्मक पैटर्न जैसे '`:! अवांछित_पथ`` को अनदेखा किया जाएगा

match_pathspec_with_flags()विशेष झंडे को निर्दिष्ट करने की आवश्यकताओं को पूरा करने के लिए एक नया फ़ंक्शन जोड़ें, जबकि अभी भी नकारात्मक पैटर्न की सही तरीके से जांच कर रहे हैं, do_match_pathspec()दूसरों को इसका दुरुपयोग करने से रोकने के लिए ऊपर एक बड़ी टिप्पणी जोड़ें , और do_match_pathspec()इसके बजाय match_pathspec()या तो उपयोग करने के लिए वर्तमान कॉलर्स को सही करें match_pathspec_with_flags()

एक अंतिम नोट यह है कि DO_MATCH_LEADING_PATHSPECकाम करते समय विशेष रूप से विचार की आवश्यकता है DO_MATCH_EXCLUDE

मुद्दा DO_MATCH_LEADING_PATHSPECयह है कि अगर हमारे पास एक रास्ता जैसा है

*/Makefile

और हम जैसे निर्देशिका पथ की जाँच कर रहे हैं

src/module/component

हम इसे एक मैच पर विचार करना चाहते हैं, ताकि हम निर्देशिका में पुनरावृत्ति करें क्योंकि इसमें _might_ Makefileनीचे कहीं नाम की एक फ़ाइल है ।

हालाँकि, जब हम एक बहिष्करण पैटर्न का उपयोग कर रहे हैं, अर्थात हमारे पास एक pathspec जैसा है

:(exclude)*/Makefile

हम यह नहीं कहना चाहते कि एक निर्देशिका पथ जैसा है

src/module/component

एक नकारात्मक (नकारात्मक) मैच है।

हालाँकि उस निर्देशिका के नीचे कहीं 'मेकफाइल' नाम की एक फाइल हो सकती है, वहीं दूसरी फाइलें भी हो सकती हैं और हम उस निर्देशिका से बाहर की सभी फाइलों को पूर्व-खाली नहीं कर सकते हैं; हमें अलग-अलग फ़ाइलों की पुनरावृत्ति और जाँच करने की आवश्यकता है।

DO_MATCH_LEADING_PATHSPECकेवल सकारात्मक pathspecs के लिए सक्रिय होने के लिए तर्क समायोजित करें ।


7
क्या आप कई फाइलें कर सकते हैं?
जस्टिन थॉमस

12
@JustinThomas मुझे विश्वास है (अभी तक परीक्षण नहीं किया गया है) कि आप कई बार उस पथ बहिष्करण पैटर्न को दोहरा सकते हैं ":(exclude)pathPattern1" ":(exclude)pathPattern2", इसलिए कई फ़ोल्डर्स या फ़ाइलों की अनदेखी कर सकते हैं।
VonC

7
यदि आप बैश शेल में गिट चला रहे हैं, तो त्रुटियों':!sub' से बचने केbash: ... event not found लिए उपयोग करें । ":\!sub"काम नहीं करता है।
केनी एविट

1
@KennyEvitt आपके संपादन और टिप्पणी के लिए धन्यवाद। मैंने उत्तरार्द्ध को अधिक दृश्यता के लिए उत्तर में शामिल किया है।
VonC

2
उन लोगों के लिए जो इस कार्यक्षमता पर आधिकारिक दस्तावेज हैं, देखें git help glossary(जो मुझे git help -g[जिसे मैंने सुझाव दिया है git help] में सूचीबद्ध पाया )।
रेवरॉन

4

tl; डॉ: shopt -s extglob && git log !(unwanted/glob|another/unwanted/glob)

यदि आप बैश का उपयोग कर रहे हैं, तो आपको केवल आवश्यक फ़ाइलों को प्राप्त करने के लिए विस्तारित ग्लोबिंग सुविधा का उपयोग करने में सक्षम होना चाहिए :

$ cd -- "$(mktemp --directory)" 
$ git init
Initialized empty Git repository in /tmp/tmp.cJm8k38G9y/.git/
$ mkdir aye bee
$ echo foo > aye/foo
$ git add aye/foo
$ git commit -m "First commit"
[master (root-commit) 46a028c] First commit
 0 files changed
 create mode 100644 aye/foo
$ echo foo > bee/foo
$ git add bee/foo
$ git commit -m "Second commit"
[master 30b3af2] Second commit
 1 file changed, 1 insertion(+)
 create mode 100644 bee/foo
$ shopt -s extglob
$ git log !(bee)
commit ec660acdb38ee288a9e771a2685fe3389bed01dd
Author: My Name <jdoe@example.org>
Date:   Wed Jun 5 10:58:45 2013 +0200

    First commit

आप इसे globstarपुनरावर्ती कार्रवाई के लिए जोड़ सकते हैं ।


7
यह उन फ़ाइलों को प्रभावित नहीं करता है जो अब मौजूद नहीं हैं। बहुत करीबी और अच्छा हैक सभी समान।
अनाम

-2

आप अस्थायी रूप से फ़ाइल में परिवर्तनों को अनदेखा कर सकते हैं :

git update-index --skip-worktree path/to/file

आगे बढ़ते हुए, उन फ़ाइलों के सभी परिवर्तनों को अनदेखा कर देगा git status, git commit -aआदि जब आप उन फ़ाइलों को प्रतिबद्ध करने के लिए तैयार हैं, बस इसे रिवर्स:

git update-index --no-skip-worktree path/to/file

और सामान्य रूप से प्रतिबद्ध रहें।


9
यह कुछ अलग स्थिति को संबोधित करता है। पहले से ही किए गए कमिट को फ़िल्टर करने का git update-index --skip-worktreeकारण नहीं है git log
बेनामी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.