2011-08-22 15 views
21

में फ़ाइल आकार सीमित करना मैं वर्तमान में अपने वीसीएस (सबवर्सन से) को गिट में बदलने की सोच रहा हूं। क्या गिट रिपोजिटरी में किसी प्रतिबद्धता के भीतर फ़ाइल आकार को सीमित करना संभव है? ई के लिए जी। उपversण एक हुक है: http://www.davidgrant.ca/limit_size_of_subversion_commits_with_this_hookगिट रिपॉजिटरी

मेरे अनुभव से लोगों, विशेष रूप से जो अनुभवहीन हैं, कभी-कभी ऐसी फाइलें करते हैं जो वीसीएस (ई। जी। बड़ी फाइल सिस्टम छवियों) में नहीं जाना चाहिए।

उत्तर

2

हां, गिट में हुक भी है (git hooks)। लेकिन यह वास्तव में काम-प्रवाह पर निर्भर करता है जिसका आप उपयोग करेंगे।

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

2

आप hook, या तो pre-commit हुक (क्लाइंट पर), या update हुक (सर्वर पर) का उपयोग कर सकते हैं। git ls-files --cached (प्री-प्रतिबद्ध के लिए) या git ls-tree --full-tree -r -l $3 (अपडेट के लिए) करें और तदनुसार कार्य करें।

git ls-tree -l कुछ इस तरह देना होगा:

100644 blob 97293e358a9870ac4ddf1daf44b10e10e8273d57 3301 file1 
100644 blob 02937b0e158ff8d3895c6e93ebf0cbc37d81cac1  507 file2 

ले लो आगे स्तंभ, और यह आकार है। सबसे बड़ी फ़ाइल प्राप्त करने के लिए git ls-tree --full-tree -r -l HEAD | sort -k 4 -n -r | head -1 का उपयोग करें। cut निकालने के लिए, if [ a -lt b ] आकार, आदि के लिए

क्षमा करें, मुझे लगता है कि यदि आप प्रोग्रामर हैं, तो आप इसे स्वयं करने में सक्षम होना चाहिए।

+10

bullsh के लिए डाउनवॉटेड ** इसे स्वयं टिप्पणी करें। –

+0

@ जे -16 एसडीआईजेड बहुत अपरिपक्व उत्तर। – nash

0

एक और तरीका .gitignore संस्करण है, जो किसी भी फ़ाइल को किसी निश्चित एक्सटेंशन के साथ स्थिति में दिखाने के लिए रोक देगा।
तुम अब भी हुक के साथ-साथ (नीचे की ओर या नदी के ऊपर पर, के रूप में अन्य उत्तर ने सुझाव दिया) हो सकता है, लेकिन कम से कम सब नीचे की ओर रेपो शामिल कर सकते हैं कि .gitignore जोड़ने से बचने के लिए .exe, .dll, .iso, ...

+0

नोट: हुक क्लोन के माध्यम से प्रचारित नहीं होते हैं: http://stackoverflow.com/questions/5165239/why-it-is-not-possible-to-git-add-git-hooks-my-hook/5165299#5165299) – VonC

0

यह 200 एमबी या इससे भी अधिक आकार की फ़ाइल कहने पर मैंने जो देखा है उससे बहुत दुर्लभ मामला होने जा रहा है।

जबकि आप सर्वर साइड हुक का उपयोग करके इसे रोकने से रोक सकते हैं (क्लाइंट साइड हुक के बारे में सुनिश्चित नहीं है क्योंकि आपको हुक स्थापित करने वाले व्यक्ति पर भरोसा करना है) जैसा कि आप एसवीएन में कैसे करेंगे, आपको भी इसमें लेना होगा खाता है कि गिट में, भंडार से ऐसी फ़ाइल/प्रतिबद्धता को हटाना बहुत आसान है। आपके पास एसवीएन में इतनी लक्जरी नहीं थी, कम से कम एक आसान तरीका नहीं था।

+0

वास्तव में, गिट में यह अधिक कठिन नहीं है? फ़ाइल का 'गिट आरएम' वास्तव में इसे रेपो से नहीं हटाता है, यह सिर्फ बाद के संशोधन में दिखाई नहीं देता है। आप अभी भी इसके लिए स्पेस/बैंडविड्थ बर्बाद कर सकते हैं। –

+0

@ जोसेफ गारविन - कैसे? 'git rm' वर्तमान प्रतिबद्धता से फ़ाइल को निकालने का आदेश है। यह इतिहास नहीं बदलता है। आपके पास अन्य आदेश हैं जैसे कि 'गिट प्रतिबद्ध --amend' और' गिट फ़िल्टर-शाखा ' – manojlds

19

क्योंकि मैं थोड़ी देर के लिए इसके साथ संघर्ष कर रहा था, यहां तक ​​कि विवरण के साथ भी, और मुझे लगता है कि यह दूसरों के लिए भी प्रासंगिक है, मैंने सोचा कि मैं J16 SDiZ described को कार्यान्वित करने के तरीके के कार्यान्वयन को पोस्ट करूंगा।

तो, सर्वर साइड update हुक भी बड़ी फ़ाइलों को रोकने पर मेरी ले पर लाई जानी:

#!/bin/bash 

# Script to limit the size of a push to git repository. 
# Git repo has issues with big pushes, and we shouldn't have a real need for those 
# 
# eis/02.02.2012 

# --- Safety check, should not be run from command line 
if [ -z "$GIT_DIR" ]; then 
     echo "Don't run this script from the command line." >&2 
     echo " (if you want, you could supply GIT_DIR then run" >&2 
     echo " $0 <ref> <oldrev> <newrev>)" >&2 
     exit 1 
fi 

# Test that tab replacement works, issue in some Solaris envs at least 
testvariable=`echo -e "\t" | sed 's/\s//'` 
if [ "$testvariable" != "" ]; then 
     echo "Environment check failed - please contact git hosting." >&2 
     exit 1 
fi 


# File size limit is meant to be configured through 'hooks.filesizelimit' setting 
filesizelimit=$(git config hooks.filesizelimit) 

# If we haven't configured a file size limit, use default value of about 100M 
if [ -z "$filesizelimit" ]; then 
     filesizelimit=100000000 
fi 

# Reference to incoming checkin can be found at $3 
refname=$3 

# With this command, we can find information about the file coming in that has biggest size 
# We also normalize the line for excess whitespace 
biggest_checkin_normalized=$(git ls-tree --full-tree -r -l $refname | sort -k 4 -n -r | head -1 | sed 's/^ *//;s/ *$//;s/\s\{1,\}/ /g') 

# Based on that, we can find what we are interested about 
filesize=`echo $biggest_checkin_normalized | cut -d ' ' -f4,4` 

# Actual comparison 
# To cancel a push, we exit with status code 1 
# It is also a good idea to print out some info about the cause of rejection 
if [ $filesize -gt $filesizelimit ]; then 

     # To be more user-friendly, we also look up the name of the offending file 
     filename=`echo $biggest_checkin_normalized | cut -d ' ' -f5,5` 

     echo "Error: Too large push attempted." >&2 
     echo >&2 
     echo "File size limit is $filesizelimit, and you tried to push file named $filename of size $filesize." >&2 
     echo "Contact configuration team if you really need to do this." >&2 
     exit 1 
fi 

exit 0 
+0

इसका उपयोग कैसे करें? काम करने से पहले हर बार इस फाइल का निष्पादन करें? – Gank

+0

@ गैंक आपने जो जवाब मुझसे लिंक किया है उसे पढ़ा है? – eis

+0

हां। लेकिन मुझे नहीं पता कि इसे गिट में कैसे कॉन्फ़िगर किया जाए। – Gank

0

मैं gitolite उपयोग कर रहा हूँ और अद्यतन हुक पहले से ही किया जा रहा था - के बजाय अद्यतन हुक का उपयोग कर के, मैंने पूर्व-प्राप्त हुक का उपयोग किया।स्क्रिप्ट Chriki द्वारा पोस्ट की गई अपवाद है कि डेटा stdin के माध्यम से पारित कर दिया है साथ fabulously काम किया - तो मैं एक पंक्ति परिवर्तन किया:

- refname=$3 
+ read a b refname 

(वहाँ है कि करने के लिए एक और अधिक सुरुचिपूर्ण तरीका हो सकता है, लेकिन यह काम करता है)

4

यदि आप गिटोलाइट का उपयोग कर रहे हैं तो आप वीआरईएफ को भी आजमा सकते हैं। डिफ़ॉल्ट रूप से पहले से ही एक वीआरईएफ प्रदान किया गया है (कोड गिटोलाइट/src/VREF/MAX_NEWBIN_SIZE में है)। इसे MAX_NEWBIN_SIZE कहा जाता है। यह इस तरह काम करता है:

repo name 
RW+  = username 
- VREF/MAX_NEWBIN_SIZE/1000 = usernames 

कहाँ 1000 बाइट्स में उदाहरण सीमा है।

यह वीआरईएफ एक अद्यतन हुक की तरह काम करता है और यदि आपके द्वारा धक्का देने वाली एक फ़ाइल थ्रेसहोल्ड से अधिक है तो यह आपके धक्का को अस्वीकार कर देगा।

6

ईआईएस और जे -16 एसडीआईजेड के उत्तर गंभीर समस्या से पीड़ित हैं। वे केवल अंतिम $ 3 या $ newrev प्रतिबद्धता की स्थिति की जांच कर रहे हैं। उन्हें यह भी जांचना होगा कि अन्य में $ 2 (या $ oldrev) और $ 3 (या $ newrev) के बीच udpate हुक में सबमिट किया जा रहा है।

जे -16 एसडीआईजेड सही उत्तर के करीब है।

बड़ा दोष किसी जिसका विभागीय सर्वर यह मुश्किल तरीके से पता चलेगा की रक्षा के लिए स्थापित इस अद्यतन हुक है कि यह है कि:

Git rm का उपयोग कर तो बड़ी फ़ाइल गलती में जाँच की जा रही है, को दूर करने के बाद वर्तमान पेड़ या आखिरी प्रतिबद्धता केवल ठीक रहेगी, और यह बड़ी फ़ाइल सहित, हटाई गई पूरी फाइल में खींच जाएगी, जो एक सूजन दुखी वसा इतिहास बना रहा है जो कोई भी नहीं चाहता है।

समाधान के लिए या तो प्रत्येक स्वीकृति $ oldrev से $ newrev तक जांचने के लिए है, या पूरी रेंज $ oldrev .. $ newrev निर्दिष्ट करने के लिए है। यह सुनिश्चित करें कि आप केवल $ newrev की जांच नहीं कर रहे हैं, या यह आपके गिट इतिहास में बड़े पैमाने पर जंक के साथ विफल हो जाएगा, के साथ साझा करने के लिए बाहर धकेल दिया जाएगा और उसके बाद इसे हटाने के लिए मुश्किल या असंभव होगा।

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