Git रेपो से कई फ़ाइलों को हटाना जो पहले ही डिस्क से हटा दिए गए हैं


1311

मेरे पास एक Git रेपो है जिसे मैंने चार फ़ाइलों को उपयोग करने rm( नहीं git rm ) से हटा दिया है , और मेरी Git स्थिति इस तरह दिखती है:

#    deleted:    file1.txt
#    deleted:    file2.txt
#    deleted:    file3.txt
#    deleted:    file4.txt

मैं इन फ़ाइलों को Git से मैन्युअल रूप से जाने के बिना कैसे निकालूँ और प्रत्येक फ़ाइल को इस तरह से जोड़ूँ:

git rm file1 file2 file3 file4

आदर्श रूप से, मैं किसी ऐसी चीज़ की तलाश कर रहा हूं जो उसी तरह से काम करती git add .है, यदि यह संभव है।


2
kch

10
@ सेठ, यह हमेशा उपयोग करने के लिए सुविधाजनक नहीं है git rm, निष्कासन एक अलग उपकरण, आईडीई या फ़ाइल प्रबंधक से हो सकता है। फ़ाइलों को हटाने / नाम बदलने पर किसी के लिए विज़ुअल स्टूडियो एक दर्द हो सकता है।
ब्रेट रायन

67
उह, यह पूछना कि कोई उपयोग क्यों नहीं करता है, यह पूछना git rmथोड़ा सा है कि वे उपयोग क्यों नहीं करते git vimया git cd। यह करना एक बेवकूफी की बात है, और git के पास अंतर्निहित फ़ाइलों को हटाने से हटाने के लिए एक अंतर्निहित कमांड या उपनाम होना चाहिए, और आपको इसे अपने लंच ब्रेक पर SO पेज पर या मैन पेज पढ़ने के लिए नहीं देखना चाहिए।
WCWedin

7
वरिंदर का जवाब एक अच्छा तरीका नहीं है। Git ऐड -u पर विचार करें जैसा कि कोड़ी ने सुझाव दिया था और जो इस सवाल का जवाब भी है: stackoverflow.com/questions/1402776/…
रोलाण्ड

जवाबों:


2300

Git 1.x के लिए

$ git add -u

यह git को स्वचालित रूप से ट्रैक की गई फ़ाइलों को स्टेज करने के लिए कहता है - जिसमें पहले से ट्रैक की गई फ़ाइलों को हटाना शामिल है।

जीआईटी 2.0 के लिए

अपने पूरे काम के पेड़ को स्टेज करने के लिए:

$ git add -u :/

केवल वर्तमान पथ को चरणबद्ध करने के लिए:

$ git add -u .

133
ध्यान दें कि यह सभी परिवर्तित, ट्रैक की गई फ़ाइलों को जोड़ देगा - हटा दिया गया और अद्यतन किया गया।
इयान हंटर

19
@ बीनलैंड, आपको केवल उस विशिष्ट फ़ाइल को पथ प्रदान करना है जिसे आप संशोधित करना चाहते हैं यदि आप यह नहीं चाहते हैं कि यह उन सभी को प्राप्त हो। जैसे git add -u [path]
पॉल प्रीवेट

27
यह भी git add -u folder/एक फ़ोल्डर में इस ऑपरेशन को चलाने के लिए
c ..

2
FYI करें: यह उत्तर stackoverflow.com/questions/1402776/…
Shog9

1
यह वह प्रश्न हो सकता है जो लोग इस पृष्ठ पर आने पर पूछ रहे थे, और यह वही हो सकता है जो ओपी वास्तव में पूछने के लिए था, लेकिन यह पूछे गए सटीक प्रश्न का उत्तर नहीं देता है।
रीलेक्वेस्टल

1362
git ls-files --deleted -z | xargs -0 git rm 

हो सकता है कि तुम क्या देख रहे हो .. यह मेरे लिए काम करता है ..


5
खिड़कियों के लिए Evan Moran 'remove =! git ls-files --deleted -z द्वारा ऊपर बताए गए उद्धरणों के बिना अपने विन्यास में निम्नलिखित उपनाम जोड़ने की कोशिश करें। xargs -0 git rm '
CLS

21
उनके नाम से रिक्त स्थान वाली फाइलों से सावधान रहें
maazza

44
@DaveEverittgit ls-files --deleted -z | xargs -0 git rm
मैक्स नानसी

15
git add -u के रूप में कोड़ी ने सुझाव दिया कि एक बहुत ही सरल और सुरक्षित तरीका है, गलती से फ़ाइलों को हटाने का कोई जोखिम नहीं है।
रोलैंड

4
इसे डाउनवोट करना क्योंकि यह कुछ फ़ाइलों के लिए काम करने पर भी गलत उत्तर है। नीचे "git add -u" का उपयोग करें। बस यही बात है।
n13

733

आप उपयोग कर सकते हैं

git add -u

हटाए गए फ़ाइलों को स्टेजिंग क्षेत्र में जोड़ने के लिए, फिर उन्हें प्रतिबद्ध करें

git commit -m "Deleted files manually"

100
कृपया Google उपयोगकर्ता पर ध्यान दें: यह संशोधित ट्रैक की गई फ़ाइलों को स्टेजिंग क्षेत्र में भी जोड़ता है।
erenon

4
यह कमांड तभी चलाएं जब आपने सिर्फ फाइलें निकाली थीं और उन्हें तुरंत स्टेज करना चाहते थे।
आर्यो

1
मैं बिटबकेट रेपो से फाइल नहीं निकाल पा रहा हूं]
श्रीनिवास गौड़ा

356

यदि आप बस चलाते हैं:

git add -u

git अपने इंडेक्स को यह जानने के लिए अपडेट करेगा कि आपने जो फाइलें डिलीट की हैं, वे वास्तव में अगले कमिट का हिस्सा होना चाहिए। फिर आप उस परिवर्तन में जाँच करने के लिए "कमिट कमिट" चला सकते हैं।

या, यदि आप चलाते हैं:

git commit -a

यह स्वचालित रूप से इन परिवर्तनों (और किसी भी अन्य) को ले जाएगा और उन्हें प्रतिबद्ध करेगा।

अद्यतन : यदि आप केवल हटाई गई फ़ाइलों को जोड़ना चाहते हैं, तो प्रयास करें:

git ls-files --deleted -z | xargs -0 git rm
git commit

1
ठीक है, git commit -aमैं वही करूंगा जो मैं चाहता हूं, कुछ मामलों में मेरे पास ऐसी फाइलें हैं जिन्हें मैं कमिट नहीं करना चाहता, इसलिए मैं मैन्युअल रूप से कमिट तैयार करना चाहता हूं।
इगोर ज़ेवाका

2
प्रतिबद्ध-ए अनिवार्य रूप से पहले "ऐड -यू" करता है; यह ज्ञात फ़ाइलों में किसी भी परिवर्तन के साथ सूचकांक को अपडेट करेगा (वे विलोपन या सरल परिवर्तन हो)। आप निश्चित रूप से अधिक विशिष्ट हो सकते हैं और केवल उन फाइलों को जोड़ / आरएम कर सकते हैं जो आप चाहते हैं। git.or.cz/gitwiki/… मददगार हो सकता है।
एमिल सीट

2
"अपडेट: .." के नीचे कमांडेट एक आकर्षण की तरह काम करता है। धन्यवाद!
जे टेलर टेलर

10
'Git ls-files --deleted | के लिए बहुत बहुत धन्यवाद xargs git rm '!
मीत

18
"git ls-files --deleted | xargs git rm" सही उत्तर है! धन्यवाद!
रीटो

166

आप शायद देख रहे हैं:

git add -A

यह git ऐड-यू के समान है, लेकिन नई फाइलें भी जोड़ता है। यह लगभग hg के addremoveकमांड के बराबर है (हालांकि चाल पहचान स्वचालित है)।


8
एक त्वरित पक्ष नोट पर, यू का उपयोग करके ट्रैक की गई फ़ाइलों में ऐड को सीमित किया जाता है और -a में अनट्रैक की गई फ़ाइलें भी शामिल होंगी। बस मैंने सोचा था कि मैं अंतर बताऊंगा।
स्पाकार्की 21

इस स्तर पर आप कमिट-फ़्लैग के माध्यम से सभी को जोड़ सकते हैं।
ज़ैक ग्रियर्सन

94

केवल हटाई गई फ़ाइलों को चरणबद्ध करने के लिए :

for x in $(git status | grep deleted | awk '{print $2}'); do git rm $x; done

या (xargs तरीका):

git status | awk '/deleted/ {print $2}' | xargs git rm

आप कर सकते हैं उर्फ सुविधाजनक बाद में उपयोग के लिए अपना पसंदीदा कमांड सेट।


2
@ सैब कतार के बारे में समझते हैं, लेकिन xargsमास्टर के बारे में 15 मिनट हैं।
एरिक विल्सन

11
git status | awk '/deleted/ {print $3}' | xargs git rmऐसा करने का एक छोटा तरीका होगा। grep | awk... जस्ट सांग नं।
मार्क रीड

58
git rm $(git ls-files --deleted)इस और अधिक सुविधाजनक (से कॉपी नहीं किया है इस )।
होट्सचे

1
xargs या उपरोक्त $ () प्रतिस्थापन यदि आपको पता है कि सूची बहुत बड़ी नहीं है। यदि सूची बहुत बड़ी है: git ls-files --deleted | while read f; do git rm $f; done
एंड्रयू

2
@Andrew xargsशायद एक विशाल सूची के लिए थोड़ी देर के लूप से अधिक कुशल है, क्योंकि यह हर बार एक से अधिक तर्क पास करता है git rmgit rmयह निष्पादित होने पर हर बार पारित किए गए तर्कों की संख्या को सीमित करने के लिए, -nविकल्प का उपयोग करें :git ls-files --deleted | xargs -n 15 git rm
Ajedi32

61
git rm test.txt

वास्तविक फ़ाइल को हटाने से पहले या उसके बाद।


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

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

2
वास्तव में यह प्रश्न की अंतिम पंक्ति के अनुसार सबसे अच्छा उत्तर होना चाहिए "मुझे बस एक कमांड चाहिए जो कि डिस्क से हटाए गए गिट से सभी फाइलों को हटा दे।"
रामशरण

2
@ रामशरण नहीं, क्योंकि यह बिल्कुल नहीं है। यह एक एकल फ़ाइल को हटाता है; ।
आदम

1
@ रामशरण नहीं, वह बिंदु है - लगभग सभी मामलों में आप बस एक वाइल्डकार्ड का उपयोग नहीं कर सकते हैं (कोई वाइल्डकार्ड नहीं है जो मेल खाएगा)। यही कारण है कि मुख्य जवाब इतना अधिक जटिल है।
एडम

49

'-All' या '--update' विकल्पों के साथ git-add का उपयोग करके आप अपनी इच्छानुसार अधिक प्राप्त कर सकते हैं। नई और / या संशोधित फ़ाइलों को भी सूचकांक में जोड़ा जाएगा। मेरे पास एक बैश उर्फ ​​सेटअप है जब मैं अन्य फ़ाइलों को छूने के बिना गिट से हटाई गई फ़ाइलों को हटाना चाहता हूं:

alias grma='git ls-files --deleted -z | xargs -0 git rm'

फ़ाइल सिस्टम से हटा दी गई सभी फ़ाइलों को हटाए गए के रूप में सूचकांक में जोड़ा जाता है।


39

ऐसा नहीं है कि यह वास्तव में मायने रखता है, लेकिन मैं चुने हुए उत्तर से असहमत हूं:

git add -u 

... यदि कार्यशील ट्री में संबंधित फ़ाइलों को हटा दिया गया है, तो सूचकांक से फ़ाइलों को हटा देगा, लेकिन यह ट्रैक की गई फ़ाइलों की संशोधित नई सामग्री को भी चरणबद्ध करेगा।

git rm $(git ls-files --deleted)

... दूसरी तरफ केवल हटाए गए फ़ाइलों को ही ट्रैक किया जाएगा।

इसलिए मेरे विचार में बाद वाला बेहतर विकल्प है।


29

यदि वे केवल परिवर्तन हैं, तो आप बस कर सकते हैं

git commit -a

सभी परिवर्तनों को करने के लिए। जिसमें हटाई गई फाइलें शामिल होंगी।


3
यकीन नहीं होता कि मैं नीचे क्यों आया; git उन फ़ाइलों की पहचान करने का एक अच्छा काम करता है, जिन्हें हटा दिया गया है, भले ही आपने git rm का उपयोग करके इसे स्पष्ट रूप से नहीं बताया हो।
स्पूनमाइज़र

आप नीचे उतर गए क्योंकि "-a" स्वीकार्य स्विच नहीं है, यह "-ए" है। अपने उत्तर का संपादन।
शेहरी

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

मामले में केवल एक चीज जो आप कर रहे हैं वह हटाई गई फ़ाइल है, स्विच जोड़ें
Billrichards

गलती से, वास्तव में - खाली-खाली की केवल आवश्यकता होती है यदि आपने rm
cached

20
git ls-files --deleted | xargs git rm 

केवल हटाई गई फ़ाइलों को जोड़ने का सबसे अच्छा विकल्प है।

यहाँ कुछ अन्य विकल्प हैं।

git add .  => Add all (tracked and modified)/new files in the working tree.

git add -u => Add all modified/removed files which are tracked.

git add -A => Add all (tracked and modified)/(tracked and removed)/new files in the working tree.

git commit -a -m "commit message" - Add and commit modified/removed files which are tracked.

16

git add -u

-u --update केवल कार्यशील ट्री के बजाय अनुक्रमणिका में पहले से ट्रैक की गई फ़ाइलों के विरुद्ध मेल खाता है। इसका मतलब है कि यह नई फ़ाइलों को कभी भी मंचित नहीं करेगा, लेकिन यह ट्रैक की गई फ़ाइलों की संशोधित नई सामग्री को चरणबद्ध करेगा और यदि यह कार्यशील ट्री में संबंधित फ़ाइलों को हटा दिया गया है तो यह सूचकांक से फ़ाइलों को हटा देगा।

यदि कोई नहीं दिया गया है, तो डिफ़ॉल्ट रूप से ";"; दूसरे शब्दों में, वर्तमान निर्देशिका और उसकी उपनिर्देशिकाओं में सभी ट्रैक की गई फ़ाइलों को अपडेट करें।


शीर्ष मतदान जवाब पहले से ही उपयोग करने के लिए कहता है git add -u। आपके उत्तर में अन्य सभी सामान कहां से आया है, प्रलेखन? आपको दस्तावेज़ीकरण से लिंक करना चाहिए और यदि ऐसा होता है तो इसे ब्लॉकचोट करना चाहिए।
TheWarriorNamedFoo

14

यह सरल समाधान मेरे लिए ठीक काम करता है:

git rm $(git ls-files --deleted)

मुझे लगता है कि आपको हमेशा मौजूदा वर्किंग डायरेक्टरी
हाउससम बद्री

2
यह अच्छा और सरल है, लेकिन पुनरावर्ती फ़ोल्डर्स के साथ काम नहीं करता है।
DrB

@BehnazChangizi मुझे लगता है कि यह करता है, stackoverflow.com/questions/1054044/…
गृहिणी बद्री

@PddL ने स्वीकार नहीं किया कि रास्ते में रिक्त स्थान os-specefic समस्या है
गृहिणी बद्री

11

यदि आप इसे अपने .gitconfigऐसा करने के लिए जोड़ना चाहते हैं :

[alias]
  rma = !git ls-files --deleted -z | xargs -0 git rm

फिर आपको बस इतना करना है:

git rma

1
और cmd लाइन सेgit config --global alias.rmd '!git ls-files --deleted -z | xargs -0 git rm'
केसी

9
git ls-files --deleted -z | xargs -0 git rm --cached

यह उन सभी हटाई गई फ़ाइलों को हटा देगा जो पिछली बार गिट द्वारा ट्रैक की गई थीं, साथ ही उस मामले को भी संभालती हैं जहां आपके फ़ाइलनाम में रिक्त स्थान हैं।

आपके POSIX संस्करण के आधार पर, आपको उपयोग करने की आवश्यकता हो सकती है xargs -0 -r: यह कारण होगाxargs पाइप की अशक्त सामग्री के बाहर आने पर ख़ुशी से बाहर निकलने का ।

संपादित करें: --cachedऔर --deletedझंडे का उपयोग गलती से नष्ट हो चुकी फाइलों को हटाने के लिए किया जाता है।


7

उन फ़ाइलों को स्वचालित रूप से चरणबद्ध करने के लिए कमांड बताएं जिन्हें संशोधित और हटा दिया गया है, लेकिन आपने जिन नई फ़ाइलों के बारे में नहीं बताया है, वे प्रभावित नहीं होती हैं:

-ए -
लंबा

git add . && git commit -m -a "Your commit"

या

git add --all && git commit -m "Your commit"

1
git add --all && git प्रतिबद्ध -m "Your प्रतिबद्ध" यह मेरे लिए विंडोज़ -7 में काम किया, Git bash कमांड शेल का उपयोग किया।
किमीबार

1
निम्न कमांड ने मेरे लिए विंडोज़ -7 में काम किया, Git bash कमांड शेल का उपयोग करते हुए: $ git add-all && git कमिट-मी "प्रॉपर्टी फाइल्स को हटाएं" [मास्टर 58c41ac] प्रॉपर्टी फाइल्स 1 फाइल को हटा दें, 9 डिलीट (-)। .. फिर दूरस्थ रिपॉजिटरी में उन प्रतिबद्ध बदलावों को धकेलने के लिए: $ git पुश ओरिजिन .. गिनती की वस्तुओं: 10, किया।
किमीबार

6

निम्न कार्य करेगा, भले ही आपके पास संसाधित करने के लिए बहुत सी फाइलें हों:

git ls-files --deleted | xargs git rm

आप शायद एक टिप्पणी के साथ भी करना चाहते हैं।

विवरण के लिए, देखें: उपयोगी गिट लिपियों


6

कृपया -tयह देखने के लिए उपयोग करें कि वास्तव में किस कमांड को चलाया जा रहा है

मैंने सिर्फ वीरेंद्र को ऐसा करने के लिए जवाब दिया:

git ls-files --deleted -z | xargs -t -0 git rm

5

गिट-ऐड करने के लिए झंडे में से कोई भी केवल हटाए गए फ़ाइलों को चरणबद्ध नहीं करेगा; यदि आपने सभी संशोधित फाइलें हटा दी हैं, तो आप ठीक हैं, लेकिन अन्यथा, आपको git-status चलाने और आउटपुट पार्स करने की आवश्यकता है।

जेरेमी के जवाब से हटकर, मुझे यही मिला:

git status |  sed -s "s/^.*deleted: //" | grep "\(\#\|commit\)" -v | xargs git rm
  1. फ़ाइलों की स्थिति प्राप्त करें।
  2. हटाई गई फ़ाइलों के लिए, फ़ाइल का नाम अलग करें।
  3. #S के साथ शुरू होने वाली सभी पंक्तियों को हटा दें, साथ ही एक स्थिति रेखा जिसमें "हटाए गए" शब्द था; मुझे याद नहीं है कि यह वास्तव में क्या था, और यह अब नहीं है, इसलिए आपको विभिन्न स्थितियों के लिए इसे संशोधित करना पड़ सकता है। मुझे लगता है कि अभिव्यक्ति का समूहीकरण एक GNU- विशिष्ट विशेषता हो सकती है, इसलिए यदि आप अंगूर का उपयोग नहीं कर रहे हैं, तो आपको कई grep -vलाइनें जोड़नी पड़ सकती हैं ।
  4. फाइलों को पास करें git rm

अब एक खोल उर्फ ​​में चिपका ...


5

उल्लेखानुसार

git add -u

हटाने के लिए हटाए गए चरणों को चरणबद्ध करें, लेकिन अपडेट के लिए संशोधित फ़ाइलों को भी संशोधित करें।

आप कर सकते हैं संशोधित फ़ाइलों को अस्थिर करने के लिए

git reset HEAD <path>

यदि आप अपने कामों को व्यवस्थित और स्वच्छ रखना पसंद करते हैं।
नोट: यह हटाई गई फ़ाइलों को भी अस्थिर कर सकता है, इसलिए उन वाइल्डकार्ड के साथ सावधानी बरतें।



3

मुझे वही चाहिए था और git gui "स्टेज चेंज" बटन का इस्तेमाल किया। यह भी सभी को जोड़ता है।

और "मंच बदला" के बाद मैंने "कमिट" किया ...

इसलिए मेरी कार्यशील निर्देशिका फिर से साफ है।


अच्छी तरह से एक gui का उपयोग कर रहे है, योग्य! लेकिन तेजी से उन मामलों में जहां जीयूआई डिजाइनर ने आपकी जरूरतों को कवर किया। यह जानना अच्छा है कि 'हुड के नीचे क्या है' के साथ छेड़छाड़ कैसे करें।
डेनिस

1
FYI करें: यह उत्तर stackoverflow.com/questions/1402776/…
Shog9

3
git rm $(git ls-files -d)

git ls-filesकमांड द्वारा सूचीबद्ध सभी फाइलों को हटाता है (-d केवल हटाए गए फ़ाइलों को दिखाता है)। फ़ाइल नाम या पथ में रिक्त स्थान वाली फ़ाइलों के लिए काम नहीं करता है, लेकिन याद रखना आसान है


2

आप git add -u <filenames>हटाए गए फ़ाइलों को केवल चरणबद्ध करने के लिए उपयोग कर सकते हैं ।

उदाहरण के लिए, यदि आपने फ़ाइलों को हटा दिया है templates/*.tpl, तो उपयोग करें git add -u templates/*.tpl

उन -uफ़ाइलों को संदर्भित करने के लिए आवश्यक है जो रिपॉजिटरी में मौजूद हैं लेकिन अब कार्यशील निर्देशिका में मौजूद नहीं हैं। अन्यथा, git addकार्यशील निर्देशिका में फ़ाइलों को देखने के लिए डिफ़ॉल्ट है, और यदि आप उन फ़ाइलों को निर्दिष्ट करते हैं जो आपने वहां हटा दी हैं, तो यह उन्हें नहीं मिलेगा।


2

कमांड के रूप में हटाई गई फ़ाइलों के मंचन के लिए सिस्टम उपनाम जोड़ना rm-all

यूनिक्स alias rm-all='git rm $(git ls-files --deleted)'

खिड़कियाँ doskey rm-all=bash -c "git rm $(git ls-files --deleted)"

ध्यान दें

विंडोज bashस्थापित करने की आवश्यकता है ।


2

(फिर भी भिन्नता)

मैं डिस्क फ़ाइलों से पहले से ही हटाए गए सभी को हटाना चाहता था लेकिन एक विशिष्ट फ़ोल्डर से, अन्य फ़ोल्डर्स को अछूता छोड़कर। निम्नलिखित ने मेरे लिए काम किया:

git ls-files --deleted  | grep <folder-name> | xargs git rm


1

दृश्य स्टूडियो परियोजना के लिए

'git ls-files --deleted | sed 's/(.*)/"\1"/'| xargs git rm' 

जब डिलीट किए गए फ़ाइल पथ में स्थान हो तो उपयोगी है


-1

सबसे लचीला समाधान जो मैंने आज तक पाया है, वह है

git cola

और सभी हटाई गई फ़ाइलों का चयन करें जिन्हें मैं चरणबद्ध करना चाहता हूं।

(नोट मैं आमतौर पर git में सब कुछ कमांडलाइन करता हूं, लेकिन git हैंडल हटाए गए फ़ाइलों को थोड़ा अजीब है)।


वाइल्डकार्ड मेरे लिए काम नहीं कर रहे थे git add -u path/to/my/deleted-files-pattern-*.ymlइसलिए यह मेरे लिए सबसे अच्छा जवाब था (सभी हटाई गई फ़ाइलों को चरणबद्ध नहीं करना चाहता था, लेकिन एक सौ में से 50)।
mlncn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.