रिबेट पर असंबद्ध इतिहास को मर्ज करने से इनकार करते हैं


2143

git rebase origin/developmentनिम्न त्रुटि संदेश के दौरान Git से दिखाया गया है:

fatal: refusing to merge unrelated histories
Error redoing merge 1234deadbeef1234deadbeef

मेरा Git संस्करण 2.9.0 है। यह पिछले संस्करण में ठीक काम करता था।

नई रिलीज़ में जबरन ध्वज के साथ असंबंधित इतिहास को अनुमति देने वाले इस छूट को मैं कैसे जारी रख सकता हूं?


12
@ शशि सभी उचित सम्मान के साथ सबसे अधिक मतदान का जवाब इस प्रश्न को सीधे तरीके से हल नहीं करते हैं। प्रश्न git-rebaseस्थिति के लिए पूछता है, जबकि उत्तर के लिए एक झंडा देता हैgit-merge
शुभम चौधरी

13
@AsifMohammed वह नहीं है जो एक स्वीकृत उत्तर है। वोटों की डिफ़ॉल्ट छँटाई के कारण लोग स्वतः ही सबसे अधिक मतों के साथ उत्तर पाएंगे।
ग्लोरफाइंडेल

2
यदि किसी और ने भी यही गलती की है, तो मुझे यह त्रुटि मिलीgit pull [repo URL]git clone [repo URL]
rsoren


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

जवाबों:


2612

Git 2.9 के बाद से डिफ़ॉल्ट व्यवहार बदल गया है:

"गिट मर्ज" का उपयोग दो शाखाओं को मर्ज करने की अनुमति देता है, जिनके पास डिफ़ॉल्ट रूप से कोई सामान्य आधार नहीं है, जिसके कारण मौजूदा परियोजना का एक नया इतिहास बनाया गया और फिर एक अप्राप्य अनुचर द्वारा खींचा गया, जिसने एक अनावश्यक समानांतर इतिहास को मौजूदा परियोजना में विलय कर दिया। । आदेश को डिफ़ॉल्ट रूप से इसे अनुमति नहीं देने के लिए सिखाया गया है , एक भागने की हैच --allow-unrelated-historiesविकल्प के साथ एक दुर्लभ घटना में उपयोग किया जाता है जो दो परियोजनाओं के इतिहास को विलय करता है जो स्वतंत्र रूप से अपना जीवन शुरू करते हैं।

देखें Git रिहाई बदलाव का अधिक जानकारी के लिए।

आप --allow-unrelated-historiesमर्ज को होने के लिए मजबूर करने के लिए उपयोग कर सकते हैं ।


18
मर्ज परिवर्तन को जानें, लेकिन यह विकल्प रिबेस के साथ काम नहीं करेगा
शुभम चौधरी

3
क्या कोई विकल्प है जो --allow-unrelated-historiesस्थायी रूप से चालू होगा ?
22

4
@jmarceli "क्योंकि इस तरह के" दो प्रोजेक्ट मर्ज "एक दुर्लभ घटना है, ऐसे मर्ज को हमेशा अनुमति देने के लिए एक कॉन्फ़िगरेशन विकल्प नहीं जोड़ा गया है।"। तो नहीं।
131 बजे ब्लू

2
मैंने इस तरह से एक अलग रेपो के लिए एक शाखा को मर्ज करने की कोशिश की, लेकिन इसने मेरी वर्तमान शाखा पर एक नई प्रतिबद्धता बनाई और दूसरे रेपो से इतिहास नहीं रखा। फिर मैंने दूसरे रेपो से एक स्थानीय शाखा की जाँच की और तभी उसे विलय कर दिया और अचानक एक सामान्य मर्ज कमिट दिखाई दिया। अजीब।
mgol 13:13

13
उत्कृष्ट, साथ git pullही साथ काम करता है । उस "दुर्लभ घटना" में, दो परियोजनाओं के इतिहास को मिलाती है जो स्वतंत्र रूप से अपना जीवन शुरू करती हैं। git --work-tree="." pull --allow-unrelated-histories
पेट्रू ज़हरिया

1185

मेरे मामले में, त्रुटि fatal: refusing to merge unrelated historiesहर कोशिश पर थी , विशेष रूप से एक गिट रिपॉजिटरी को दूर से जोड़ने के बाद पहला पुल अनुरोध।

--allow-unrelated-historiesध्वज का उपयोग इस तरह से एक पुल अनुरोध के साथ काम किया:

git pull origin branchname --allow-unrelated-histories

231
मुझे हमेशा यह त्रुटि दिखाई देती है कि जब मैं एक README.md के साथ एक नया गितुब भंडार बनाता हूं, तो इसे पहली बार एक स्थानीय भंडार में खींच लें। गुस्सा कर देने वाला।
टीएन डू

29
नए रिपोज के लिए, पहले खींचता है, यह आमतौर पर ए के साथ शुरू करना बेहतर होता है git clone
छाता

3
@PardeepJain कृपया इस github.com/git/git/blob/master/Documentation/RelNotes/…
adi

2
यह मुझे कई घंटों के लिए रोक दिया, इससे पहले कि मुझे एहसास हुआ कि इस तरह की फ़ाइलों को विलय करने के लिए एक स्पष्ट संकल्प होना चाहिए अगर यह डिफ़ॉल्ट फ़ाइलों के लिए होता है - मुझे खुशी है कि मैं केवल वही हूं जो कम से कम इस समस्या का सामना नहीं कर रहा है!
ज़िबोबज़

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

579

निम्नलिखित कमांड आज़माएं:

git pull origin master --allow-unrelated-histories

इससे आपकी समस्या का समाधान हो जाना चाहिए।


264

मुझे यह त्रुटि तब मिली जब मैंने पहले एक स्थानीय भंडार स्थापित किया। फिर मैंने गिटहब में जाकर एक नया भंडार बनाया। फिर मैं भागा

git remote add origin <repository url>

जब मैंने धक्का देने या खींचने की कोशिश की, तो मुझे fatal: unrelated_historiesहर बार वही त्रुटि मिली ।

यहाँ मैंने इसे कैसे तय किया:

git pull origin master --allow-unrelated-histories
git merge origin origin/master
... add and commit here...
git push origin master

मुझे लगता है कि हम एक ही नाव में थे। कुछ जोड़ने के लिए: मेरी समस्या यह थी कि रिमोट रेपो पर पहले से ही कुछ था। इसलिए मेरे फोल्डर में, इसने फोल्डर को डिलीट कर दिया .git, git initदौड़ाया और मर्ज किए गए हिस्से को छोड़कर आदित्य ने जो कहा, वह किया।
कोडप्लेब

1
मैक पर INSERT बटन कैसे दबाएं? दरअसल, मुझे कमिट मैसेज टाइप करना है और कमांड लाइन से मर्ज करना है, लेकिन मुझे नहीं पता कि इसे कमांड लाइन से कैसे करना है।
शजील अफजल

क्या यह विम खोलता है? अगर ऐसा होता है, तो यह सिर्फ SHIFT + है:
Adithya Bhat

यहां तक ​​कि मैंने पहले GitHub रेपो बनाया था और रेपो को जोड़ने के उन आदेशों से गुजर रहा था।
श्री सूर्या झा

1
यह एक बहुत अच्छा जवाब है। मुद्दा यह है कि आपको खींचने के लिए मजबूर करना होगा फिर स्थानीय और दूरस्थ रेपो को मर्ज करना होगा।
एलानवेक्स

151

इसके लिए, कमांड दर्ज करें:

git pull origin branchname --allow-unrelated-histories

उदाहरण के लिए,

git pull origin master --allow-unrelated-histories

संदर्भ:

GitHub असंबंधित इतिहास मुद्दे


पहली बार मेरे लिए इसके कामों के लिए धन्यवाद "गिट पुल
ओरिजनल

135
git pull origin <branch> --allow-unrelated-histories

आपको एक विम एडिट विंडो में भेजा जाएगा:

  • प्रतिबद्ध संदेश डालें
  • फिर दबाएं Esc("इन्सर्ट" मोड से बाहर निकलने के लिए), फिर :(कोलन), फिर x(छोटा "x") और अंत Enterमें Vim से बाहर निकलने के लिए हिट करें
  • git push --set-upstream origin <branch>

5
Ctrl + X आपको Vim
Ruben

लेकिन :x<Enter>होगा
webKnjaZ


47

प्रयत्न git pull --rebase development


इससे मेरी समस्या हल हो गई। यहाँ बताया गया है कि समस्या की शुरुआत कैसे हुई
हार्लन नेल्सन

1
यह संभवतः होना चाहिए:git pull --rebase=preserve --allow-unrelated-histories development
रिकार्डो मुरी

3
@RiccardoMurri बस कोशिश कर रहा है, मैं फिर से ऐसा नहीं होगा। मेरे नए रेपो में कुछ नमूना आरंभीकरण फ़ाइलें थीं, और मेरे स्थानीय रेपो महीनों के लायक हैं। इसे चलाने (इसके newOrigin branchबजाय development) ने मेरी स्थानीय शाखा के शीर्ष पर प्रारंभिक प्रतिबद्ध को जोड़ा, प्रभावी रूप से लगभग हर चीज को हटा दिया। मैं चाहता था कि नए रिमोट से शुरुआती प्रतिबद्धता सबसे नीचे हो।
redOctober13

41

Android Studio और IntelliJ के लिए:

सबसे पहले, के लिए प्रतिबद्ध सब कुछ है और किसी भी संघर्ष को सुलझाने।

फिर आईडीई के नीचे से टर्मिनल खोलें और दर्ज करें:

git pull origin master --allow-unrelated-histories

अब तुम धक्का दे सकते हो।


38

इस रिपोर्ट को पूरी तरह से दूर करने के बाद फिर से पढ़ें

यह मेरे लिए काम किया:

git push origin master --force

1
लेकिन वास्तव में स्थानीय और दूरस्थ फ़ाइलों के साथ क्या होता है?
प्रथमेश मोर

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


बस एक डिस्क्लेमर शामिल करें कि यह कमांड मास्टर ब्रांच की सभी फाइलों को ओवरराइड करता है । मेरे लिए अच्छा काम किया। धन्यवाद।
फ्लावियो

1
यह काम करता है बल्कि कठोर है, --लाड-अनरेडल-हिस्ट्रीज़ अधिक विशिष्ट और उपयुक्त है
bdulac

32

चूँकि अन्य सभी उत्तर वास्तव में प्रश्न का उत्तर नहीं दे रहे हैं, यहाँ एक समाधान संबंधित प्रश्न पर इस उत्तर से प्रेरित है ।

तो आप अपनी गलती कर रहे हैं git rebase:

$ git rebase origin/development
fatal: refusing to merge unrelated histories
Error redoing merge 1234deadbeef1234deadbeef

यह त्रुटि वास्तव में रिबास को रद्द नहीं करती है, लेकिन अब आप इसके बीच में हैं:

$ git status
interactive rebase in progress; onto 4321beefdead
Last command done (1 command done):
   pick 1234deadbeef1234deadbeef test merge commit

तो अब आप हाथ से मर्ज कर सकते हैं। मूल मर्ज कमिट के मूल माता-पिता का पता लगाएं:

$ git log -1 1234deadbeef1234deadbeef
commit 1234deadbeef1234deadbeef
Merge: 111111111 222222222
Author: Hans Dampf
Date:   Wed Jun 6 18:04:35 2018 +0200

    test merge commit

पता करें कि दोनों मर्ज माता-पिता में से कौन एक है जिसे वर्तमान में विलय किया गया था (शायद दूसरा वाला, साथ सत्यापित करें git log 222222222), और फिर हाथ से मर्ज करें, मूल मर्ज कमिट के संदेश की नकल करें:

$ git merge --allow-unrelated 222222222 --no-commit
Automatic merge went well; stopped before committing as requested
$ git commit -C 1234deadbeef1234deadbeef
[detached HEAD 909af09ec] test merge commit
 Date: Wed Jun 6 18:04:35 2018 +0200
$ git rebase --continue
Successfully rebased and updated refs/heads/test-branch.

28

मुझे भी यही समस्या थी। समस्या यह है कि कुछ को रोकने के लिए दूरस्थ था।

मैंने पहली बार एक स्थानीय भंडार बनाया। मैंने अपने स्थानीय और प्रतिबद्ध में एक LICENSEऔर README.mdफ़ाइल जोड़ी ।

तब मुझे एक रिमोट रिपॉजिटरी चाहिए थी इसलिए मैंने GitHub पर एक बनाया। यहाँ मैंने "README के ​​साथ इस रिपॉजिटरी को आरम्भिक " जाँचने की गलती की , जिसने रिमोट में भी README.md बनाया।

इसलिए अब जब मैं भागा

git push --set-upstream origin master

मुझे मिला:

error: failed to push some refs to 'https://github.com/lokeshub/myTODs.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes
(e.g. hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

अब इसे दूर करने के लिए मैंने किया

git pull origin master

जिसके परिणामस्वरूप निम्न त्रुटि हुई:

From https://github.com/lokeshub/myTODs
branch            master     -> FETCH_HEAD
fatal: refusing to merge unrelated histories**

मैंने कोशिश की:

git pull origin master --allow-unrelated-histories

परिणाम:

From https://github.com/lokeshub/myTODs
 * branch            master     -> FETCH_HEAD
Auto-merging README.md
CONFLICT (add/add): Merge conflict in README.md
Automatic merge failed;
fix conflicts and then commit the result.

समाधान:

मैंने रिमोट रिपॉजिटरी को हटा दिया और एक नया बनाया (मुझे लगता है कि केवल हटाने वाली फ़ाइल READMEकाम कर सकती थी) और उसके बाद नीचे काम किया:

git remote rm origin
git remote add origin https://github.com/lokeshub/myTODOs.git
git push --set-upstream origin master

25
एक नया भंडार बनाना कोई समाधान नहीं है
Zach

3
git पुल
ओरिजिनल

git push --force ... इस विशेष मामले में चरण 1 पर एक उचित समाधान होगा
कॉन्स्टेंटिन पेलेपेलिन

2
यह कोई हल नहीं है। यदि आप शुरुआती हैं, तो आप ऐसा कर सकते हैं, लेकिन यदि आप कुछ वास्तविक परियोजनाओं के साथ काम कर रहे हैं, तो आपको उचित तरीके से निपटना चाहिए।
प्रथमेश मोर

27

यह आमतौर पर तब होता है जब आप पहली बार रिमोट रिपॉजिटरी में जाते हैं। जैसा कि त्रुटि स्पष्ट रूप से कहती है "असंबंधित इतिहास को विलय करने से इनकार करना", हमें उपयोग करने की आवश्यकता है - कुल-असंबंधित-हिस्ट्रीज़ ध्वज।

git pull origin master  --allow-unrelated-histories

अब कुछ संघर्ष होंगे जिन्हें हमें स्वयं हल करना होगा। इसके बाद बस कोड को कमिट करें और इसे पुश करें।


जैसा कि प्रश्न में उल्लेख किया गया है, मैं एक git-rebase करने की कोशिश कर रहा हूं और git-pull नहीं, git-rebase में --allow-unrelated-historiesध्वज नहीं है ।
शुभम चौधरी

24

ऐसा होने पर दो संभावनाएँ -

  1. आपने किसी प्रोजेक्ट को क्लोन कर लिया है और किसी तरह, .IT डायरेक्टरी डिलीट या करप्ट हो गई है। यह आपके स्थानीय इतिहास और इच्छा से अनजान होता है, इसलिए, जब आप दूरस्थ रिपॉजिटरी से पुश या खींचने का प्रयास करते हैं, तो यह त्रुटि फेंकने का कारण बनता है।

  2. आपने एक नया रिपॉजिटरी बनाया है, इसमें कुछ कमिट्स जोड़े हैं, और अब आप एक रिमोट रिपॉजिटरी से खींचने की कोशिश कर रहे हैं जिसमें पहले से ही कुछ कमिट्स हैं। Git भी इस मामले में त्रुटि को फेंक देगा, क्योंकि यह पता नहीं है कि दोनों परियोजनाएं कैसे संबंधित हैं।

समाधान

जीआईटी पुल ओरिजनल मास्टर - क्लो-असंबद्ध-इतिहास

रेफरी - https://www.educative.io/edpresso/the-fatal-refuse-to-merge-unrelated-histories-git-error


12

मैंने इसके साथ संघर्ष किया, लेकिन मैं एक समाधान खोजने में कामयाब रहा।

जब आप ऊपर की त्रुटि में भाग लेते हैं, तो केवल मर्ज कमिट को चुन लें और फिर रिबास जारी रखें:

git cherry-pick -m 1 1234deadbeef1234deadbeef
git rebase --continue

3
प्लेन अंग्रेजी में कृपया?
एजेंट ज़ेबरा

@AgentZebra जटिल विमान में किसी भी डिस्क के लिए एक निरंतर बंद पथ अभिन्न है 0.
Addem

12

सबसे पहले निम्नलिखित आदेश का उपयोग करके अपने स्थानीय में दूरस्थ परिवर्तन खींचें:

git pull origin branchname --allow-unrelated-histories

** शाखाय मेरे मामले में उस्ताद है।

जब पुल कमांड किया जाता है, तो संघर्ष होता है। आपको संघर्षों को हल करना चाहिए। संघर्षों को हल करने के लिए मैं एंड्रॉइड स्टूडियो का उपयोग करता हूं। यहां छवि विवरण दर्ज करें

जब संघर्ष हल हो जाता है, तो मर्ज हो जाता है!

अब आप सुरक्षित रूप से धक्का दे सकते हैं।


मैं Resolve Conflictएएस में बटन खोज रहा हूं । कभी-कभी दाईं ओर नीचे पॉपअप / बैलोन गायब हो जाता है और मैं कुछ भी करने में असमर्थ होता हूं। धन्यवाद @oiyio
मोचडवी


6

जब git pullमैं कर रहा था , तो मुझे fatal: refusing to merge unrelated histories रेपो मॉड्यूल के लिए यह संदेश मिला जहां मैंने थोड़ी देर के लिए स्थानीय प्रतिलिपि को अपडेट नहीं किया था।

मैंने स्थानीय से मूल को ताज़ा करने के लिए इस कमांड को चलाया। मैं बस रिमोट से नवीनतम चाहता था और किसी भी स्थानीय परिवर्तन की आवश्यकता नहीं थी।

git reset --hard origin/master

यह मेरे मामले में तय किया।


12
चेतावनी: इसने मेरी सभी फ़ाइलों को हटा दिया। यदि आप नहीं जानते कि आप क्या कर रहे हैं तो सावधान रहें!
साल्वी पास्कल

2
यह सभी लंबित परिवर्तनों को हटा देगा!
ओरस्टिस पी।

1

मैं वर्षों से रिबेट का उपयोग कर रहा हूं और मुझे कभी इस तरह की समस्या का सामना नहीं करना पड़ा। हालाँकि, आपकी पहली समस्या यह है कि आप इसे दूरस्थ शाखा पर सीधे developmentदूरस्थ रिपॉजिटरी से करने की कोशिश करते हैं , जिसे कहा जाता है origin। यह शाब्दिक रूप से गलत है क्योंकि रिबेस एक खतरनाक कमांड है, जो गिट इतिहास को पुनर्गठित करता है। यह कहने के बाद, आपको पहले अपने स्थानीय भंडार पर प्रयास करना चाहिए और केवल इसे धकेलना चाहिए, अगर यह आपके लिए अपेक्षित है।

तो, मेरा सामान्य रिबेट वर्कफ़्लो निम्नलिखित लगता है (लेकिन कृपया ध्यान रखें, कि आपको शाखाओं पर रिबास का उपयोग नहीं करना चाहिए, जो आप केवल एक ही समिति नहीं हैं। ऐसी शाखाओं के लिए, बस लागू होने और संघर्ष को हल करने के लिए उपयोग करें, यदि लागू हो):

  1. सुनिश्चित करें कि आपके पास एक साफ-सुथरा काम करने वाला पेड़ है (कोई असहज परिवर्तन नहीं)
  2. उस शाखा को चेकआउट करें जिस पर आप रिबास करना चाहते हैं (उदाहरण के लिए, मान लें कि यह masterएक पंक्ति के रूप में है):git checkout master && git pull origin master && git checkout development
  3. वास्तविक प्रतिपूर्ति करें: git rebase master
  4. यदि यह पूरा हो गया है और सब कुछ उम्मीद के मुताबिक काम करता है, तो इसे अपने रिमोट पर धकेल दें। ऐसा करने के लिए, आपको इसे मजबूर करने की आवश्यकता है, क्योंकि रिमोट होस्ट में पहले से ही एक और क्रम में इतिहास है, रिमोट पुश करने के लिए कुछ भी नहीं के साथ जवाब देगा। इसलिए, हमें यह कहना होगा "इतिहास का मेरा स्थानीय संस्करण सही है, इतिहास के मेरे स्थानीय संस्करण का उपयोग करके उस दूरस्थ शाखा पर सब कुछ अधिलेखित करें:"git push -f origin development

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

हम सुविधा शाखा रणनीति का उपयोग करते हैं। इसमें, मैं आमतौर पर अन्य डेवलपर्स से "अपडेट" प्राप्त करने के लिए रिबेस का उपयोग करता हूं, जो कि इस बीच मास्टर शाखा पर हुआ था। ऐसा करने से, यह उन पुट के आकार को कम कर देता है जो एक पुल अनुरोध में दिखाई देते हैं। इसलिए, कोड समीक्षक के लिए इस सुविधा शाखा में किए गए मेरे परिवर्तनों को देखना आसान हो जाता है।


इस मामले में, मैं वास्तव में रिबेस के साथ जारी रखना चाहता था और इसका जवाब यह नहीं है। मुझे पता है कि मुझे रिबासिंग के जोखिमों का पता होना चाहिए और जब मुझे गिट-रिबेस का उपयोग करना चाहिए और नहीं करना चाहिए। यह git वर्कफ़्लो के लिए एक सामान्य (राय) दिशानिर्देश है और सीधे प्रश्न का उत्तर नहीं देता है। जहां तक ​​वर्षों के लिए रिबास का उपयोग करने की बात है, इस विशेष त्रुटि को g2 के v2.9.0 में जोड़ा गया था और प्रवाह उस रिलीज से पहले ठीक काम करता था। आपने यहाँ इस उत्तर में जो पोस्ट किया है वह पहले से ही पुराने प्रश्नों जैसे stackoverflow.com/a/11566503/2670370 और git-scm.com/book/en/v2/Git-Branching-Rebasing
शुभम चौधरी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.