2016-07-27 4 views
5

एक यादृच्छिक फ़ाइल को देखते हुए, क्या कमांड लाइन से निर्धारित करने के लिए एक कैननिकल विधि है कि फ़ाइल किसी विशेष प्रतिबद्धता से संबंधित है या नहीं?फ़ाइल को कौन सा गिट प्रतिबद्ध करता है?

यह स्टैक ओवरफ़्लो प्रश्न find-out-which-git-commit-a-file-was-taken-from के समान है, सिवाय इसके कि मैं इसे स्क्रिप्ट में उपयोग करने में सक्षम होना चाहता हूं और एक अस्थायी शाखा भी नहीं बना सकता।

+0

@ ब्रिस का कारण यह है कि मैं पूछता हूं कि (गिट के साथ) मुझे हमेशा संदेह है कि "git ls-tree --do-something-magical जैसा कुछ आदेश है जो मैं चाहता हूं। जैसा कि मैंने पाया" गिट हैश- ऑब्जेक्ट "पाइथन में एक आसान गिट शा -1 कैलकुलेटर लिखने के कुछ मिनट बाद! – Xevious

+1

एक उदाहरण तब होगा जब कोई पोस्ट मॉर्टम या निदान के लिए दिए जाने तक समर्थन स्तर तक कॉन्फ़िगरेशन फ़ाइल (हार्डवेयर से पुनर्प्राप्त) भेजता है। क्या प्रतिबद्धता या रिलीज यह आया था? रास्ते के दिनों में, हमने इस उद्देश्य के लिए आरसीएस (और अंततः सीवीएस) कीवर्ड विस्तार का उपयोग किया। मुझे पूरा यकीन है कि हम नकली कीवर्ड विस्तार जोड़ने के लिए प्रतिबद्धता और चेकआउट हुक का उपयोग कर सकते हैं, लेकिन यह इतनी कड़वाहट है कि मैं यह भी उल्लेख करने के लिए थोड़ा शर्मिंदा है। – Xevious

+1

लिंक बताता है, और यह आपकी दूसरी टिप्पणी से स्पष्ट है, कि आप एक ऐसी फाइल के बारे में बात कर रहे हैं जो आपके काम करने वाले पेड़ का हिस्सा नहीं है - लेकिन वें ई सवाल स्वयं यह नहीं कहता है। ऐसा लगता है कि आप सिर्फ 'गिट लॉग -1 - $ फाइलनाम' (संभवतः "संबंधित" के अर्थ पर कुछ भ्रम के साथ पूछ रहे हैं)। क्या आप इसे थोड़ा सा कर सकते हैं? – trentcl

उत्तर

2

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

FILE=$1 

# git hash for file 
HASH=`git hash-object $FILE` 

# git revisions for file 
REVS=`git log --pretty=%H -- $FILE` 

# check each revision for checksum match 
for rev in $REVS; do 
    POSSIBLE=`git ls-tree $rev $FILE | awk '{print $3}'` 
    if [[ $HASH == $POSSIBLE ]]; then 
     echo $rev 
    fi 
done 
+2

'git log --pretty = ... '' git rev-list --all - $ FILE' को बदलने के अलावा मैं आपके उत्तर के बारे में कुछ भी नहीं बदलूंगा। –

1

क्या आपका मतलब है, फाइल को प्रतिबद्धता में संशोधित किया गया था? यदि ऐसा है, तो git log --oneline -- filePathName जैसे कुछ को हेड से काम करना चाहिए जहां यह मामला है।

दूसरे पढ़ने पर, मुझे लगता है कि आप केवल उन कामों के लिए पूछ रहे हैं जिनमें फ़ाइल है, चाहे वह बदले या नहीं। यदि हां, तो क्या आपके एलएस-पेड़ को अपने उप-पेड़ों (उपधारा) में भर्ती करने के लिए एक झंडा की आवश्यकता नहीं है? यदि आप सिर्फ शा पर मेल खाते हैं, तो किसी भी नाम के तहत फ़ाइल की कोई प्रतियां पाई जाएंगी।

+1

ऐसा लगता है कि उस फ़ाइल नाम से जुड़े सभी कामों को वापस करने के लिए प्रतीत होता है - लेकिन उस विशिष्ट प्रतिबद्धता में जिसमें सटीक स्थिति में फ़ाइल शामिल है, जो फिलहाल है। – Xevious

+0

आह, ठीक है, तो आप उस फ़ाइल का सटीक मिलान ढूंढ रहे हैं। तो फिर भी, क्या आप उस फ़ाइल के शा के साथ रिकॉर्ड्स (उपरोक्त) नहीं हो सकते हैं और प्रत्येक ब्लॉब के शास के मिलान की तलाश कर रहे हैं, जिसे आप मिलान करने का प्रयास कर रहे हैं? – DavidN

1

Your approach तुच्छ मतभेद (जैसे लाइन न खत्म होने वाली शैली, या/धब्बा फिल्टर साफ करने के लिए कारण मतभेद) फ़ाइल के स्थानीय और भंडार संस्करणों के बीच के मामले में काम करने के लिए विफल हो सकता है।

निम्न स्क्रिप्ट हैश पर निर्भर होने के बजाय git diff के माध्यम से काम करती है। यह फ़ाइल नाम के बाद diff विकल्प स्वीकार करता है।

उपयोग के उदाहरण:

# list all commits that introduce the file README.md in its local state 
list_introducing_commits README.md 

# list all commits that introduce the file README.md in its local state 
# ignoring any difference in whitespace 
list_introducing_commits README.md -w 

list_introducing_commits (एक बेहतर नाम नहीं पा सके):

#!/bin/bash 

if [ $# -eq 0 ] 
then 
    echo "Usage: $(basename $0) path/to/file [<diff-options>]" 
    exit 1 
fi 

file="$1" 
shift 1 

for rev in $(git log --pretty=%H -- "$file") 
do 
    if git diff --exit-code [email protected] $rev -- $file &> /dev/null 
    then 
     echo $rev 
    fi 
done 
1

बिल्डिंग DavidN के answer पर, अगर फ़ाइल वर्तमान में है वर्कट्री, और वर्कट्री हेड के साथ सिंक हो रही है, यह आपको फ़ाइल की वर्तमान सामग्री से संबंधित प्रतिबद्धता प्राप्त करेगी:

git log --pretty="%H" -1 -- path/to/file 

लेकिन आप "git diff --exit-code /path/to/file" के माध्यम से समय से आगे उन मान्यताओं का परीक्षण करने और $? पर एक नज़र ले जा सकते हैं।

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