गिट में, एक भंडार से असंबंधित शाखा को शुरू करने का एक सरल तरीका है?


328

आज एक समस्या के साथ एक दोस्त की मदद करते हुए, मुझे एक शाखा शुरू करनी थी जो शाखा से पूरी तरह से अलग होने की आवश्यकता थी master। इस शाखा की सामग्री का वास्तव में एक अलग मूल था master, जिसे शाखा में विकसित किया गया था , लेकिन masterबाद में उन्हें शाखा में विलय कर दिया गया था।

मुझे याद आया कि जॉन विएग्ली की गिट्टी को नीचे से पढ़ने से याद आता है कि कैसे शाखाएं अनिवार्य रूप से एक प्रतिबद्ध के लिए एक लेबल है जो एक निश्चित सम्मेलन का अनुसरण करता है और कैसे एक प्रतिबद्ध फाइल फाइलों के पेड़ से बंधा होता है और वैकल्पिक रूप से माता-पिता के लिए होता है। हम गिट्स प्लंबिंग का उपयोग करके मौजूदा रिपॉजिटरी के लिए एक पेरेंटलेस कमिट बनाने के लिए गए:

इसलिए हमने इंडेक्स की सभी फाइलों से छुटकारा पा लिया ...

$ git rm -rf .

... टारबॉल से निकाले गए निर्देशिका और फाइलें, उन लोगों को सूचकांक में जोड़ा ...

$ git add .

... और एक ट्री ऑब्जेक्ट बनाया ...

$ git write-tree

( git-write-treeहमें बनाई गई ट्री ऑब्जेक्ट का sha1sum बताया।)

फिर, हमने पेड़ को प्रतिबद्ध किया, बिना माता-पिता के काम को निर्दिष्ट किए ...

$ echo "Imported project foo" | git commit-tree $TREE

( git-commit-treeहमें बनाई गई प्रतिबद्ध वस्तु का sha1sum बताया।)

... और एक नई शाखा बनाई जो हमारे नए बनाए गए कमिट की ओर इशारा करती है।

$ git update-ref refs/heads/other-branch $COMMIT

अंत में, हम masterवहां काम जारी रखने के लिए शाखा में लौट आए ।

$ git checkout -f master

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

जवाबों:


510

एक नई सुविधा है (V1.7.2 के बाद से) जो इस कार्य को अन्य उत्तरों में से किसी से भी अधिक उच्च स्तर का बनाती है।

git checkoutअब --orphanविकल्प का समर्थन करता है। से आदमी पेज :

git checkout [-q] [-f] [-m] --orphan <new_branch> [<start_point>]

<New_branch> नाम से एक नई अनाथ शाखा बनाएं , <start_point> से शुरू होकर उस पर स्विच करें। इस नई शाखा पर किए गए पहले कमिट में कोई माता-पिता नहीं होंगे और यह अन्य सभी शाखाओं से पूरी तरह से डिस्कनेक्ट और कमिट होने पर एक नए इतिहास की जड़ होगी।

यह वही नहीं करता है जो पूछने वाला चाहता था, क्योंकि यह सूचकांक और काम करने वाले पेड़ को पॉपुलेट करता है <start_point>(क्योंकि यह सब, एक चेकआउट कमांड है)। कार्यशील पेड़ और सूचकांक से किसी भी अवांछित वस्तुओं को हटाने के लिए केवल अन्य कार्रवाई आवश्यक है। दुर्भाग्य से, git reset --hardकाम नहीं करता है, लेकिन git rm -rf .इसके बजाय इस्तेमाल किया जा सकता है (मेरा मानना ​​है कि यह rm .git/index; git clean -fdxअन्य उत्तरों में दिए गए समकक्ष है)।


संक्षेप में:

git checkout --orphan newbranch
git rm -rf .
<do work>
git add your files
git commit -m 'Initial commit'

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


क्या आप जानते हैं कि यदि आप किसी अन्य शाखा "पेड़" से किसी शाखा की जांच करते हैं तो एक अनाथ शाखा का निर्माण संभव है?
JJD

1
@JJD: मुझे लगता है कि आप जो चाहते हैं, वह मर्ज मर्ज है। ( git checkout master && git merge --no-commit "orphan-branch" ) कुछ इसी तरह के ट्रिक git-reset या इंडेक्स के साथ खेलते हुए काम करेंगे। लेकिन यह आपके वांछित वर्कफ़्लो पर निर्भर करता है।
फोर्ड

@ मैथ्यू यहाँ git 1.7.2 के लिए चैंज है
JJD

@ मैं कम या ज्यादा के अनाथ के बारे में सोचा था कि इस परियोजना के स्रोत कोड से अलग इकाई परीक्षण या प्रलेखन जैसी चीजें शामिल हैं।
JJD

2
@JJD: मैंने जो स्क्रिप्ट दी है, आपको वही देना चाहिए, जब तक आप मुझे गलत न समझें। जब आपने कहा कि "दृश्यमान रहता है", तो क्या आपका मतलब है कि फाइलें एक अलग शाखा की जाँच के बावजूद कार्यशील निर्देशिका में बनी रहेंगी? का उपयोग करते हुए --no-commitपर git mergeइस लक्ष्य को हासिल होगा। आपको git reset origin/masterअपनी अगली कमेटी के साथ पालन करने की आवश्यकता हो सकती है , जहाँ आप चाहते हैं, लेकिन तब आपकी अनाथ-शाखा की फाइलें "अनट्रेक्टेड फ़ाइल्स" के रूप में दिखाई देंगी, जब तक कि आप उन्हें अपनी .gitignore फ़ाइल में शामिल नहीं करते।
फॉर्ड

32

से Git समुदाय बुक :

git symbolic-ref HEAD refs/heads/newbranch 
rm .git/index 
git clean -fdx 
<do work> 
git add your files 
git commit -m 'Initial commit'

1
अगला उत्तर git के आधुनिक संस्करणों के लिए बेहतर है।
किकिटो

14
@kikito: पुन: "अगला उत्तर बेहतर है" ... एसओ पर यहाँ आदेश स्थिर नहीं है। क्या आप एक लिंक जोड़ सकते हैं जो आपको लगता है कि एक बेहतर उत्तर है।
डेविड जे।

2
मैं stackoverflow.com/a/4288660/312586 का जिक्र कर रहा था । आप सही हैं, मुझे "अगला" नहीं कहना चाहिए था। जब मैंने टिप्पणी की, तो इस उत्तर से इसका स्कोर कम था।
किकिटो

1
rm .git/indexबदसूरत है :-)
Ciro Santilli ly C C C

यह एक मामले के लिए बेहतर काम करता है "मैं शाखा के लिए प्रतिबद्ध करना चाहता हूं, इसे बनाने अगर यह पहले मौजूद नहीं था"
अधिकतम

22

यद्यपि git symbolic-refसूचकांक कार्यों के साथ और हटाने का समाधान , नए भंडार को बनाने के लिए वैचारिक रूप से क्लीनर हो सकता है

$ cd /path/to/unrelated
$ git init
[edit and add files]
$ git add .
$ git commit -m "Initial commit of unrelated"
[master (root-commit) 2a665f6] Initial commit of unrelated
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 foo

फिर इससे प्राप्त करें

$ cd /path/to/repo
$ git fetch /path/to/unrelated master:unrelated-branch
warning: no common commits
remote: Counting objects: 3, done.
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
From /path/to/unrelated
 * [new branch]      master     -> unrelated-branch

अब आप हटा सकते हैं / पथ / / से असंबंधित


मेरी राय में, एक स्वच्छ अवधारणा में git branchया के लिए एक विकल्प शामिल होगा git checkout। मुझे खुशी है कि git इस तरह की चीजें संभव बनाता है, लेकिन यह आसान क्यों नहीं होना चाहिए?
पहाड़ी

3
क्योंकि यह है, और एक दुर्लभ चीज होनी चाहिए। यदि आपके पास असंबंधित चीजें शाखा हैं, तो यह आम तौर पर असंबंधित भंडार से संबंधित है, बजाय इसे मौजूदा एक में भराई करने के (हालांकि अपवाद हैं)।
जकुब नारबस्की

1
+1। साथी git newbies के लिए, आप जाहिरा तौर पर उसके माध्यम से शाखाओं की सूची बना सकते हैं git branchऔर उनके बीच स्विच कर सकते हैं git checkout BRANCH_NAME
14:11 बजे आकावल

इसके लिए धन्यवाद, मैंने अपने बारे में नहीं सोचा होगा। यह अतिरिक्त सहायक है क्योंकि यह अन्य रेपो के लिए इतिहास (यदि कोई है) को बनाए रखता है।
BM5k

13

Github में प्रोजेक्ट पेज नाम की एक सुविधा है जहाँ आप अपनी परियोजना में एक विशेष नाम की शाखा बना सकते हैं, जिसमें Github द्वारा सेवा की जाएगी। उनके निर्देश निम्नानुसार हैं:

$ cd /path/to/fancypants
$ git symbolic-ref HEAD refs/heads/gh-pages
$ rm .git/index
$ git clean -fdx

वहां से आपके पास एक खाली भंडार है जिसे आप फिर अपनी नई सामग्री जोड़ सकते हैं।


10

वर्तमान में चयनित उत्तर सही है, मैं सिर्फ उस संयोग को जोड़ूंगा ...

यह वास्तव में है कि कैसे github.com उपयोगकर्ताओं को उनके पुनर्खरीद के लिए Github पेज बनाने देता है, जिसे एक अनाथ शाखा कहा जाता है gh-pages। सुंदर चरण दिए गए हैं और यहां बताया गया है:

https://help.github.com/articles/creating-project-pages-manually

मूल रूप से इसे सेट करने के लिए git कमांड इस प्रकार हैं:

  1. git checkout --orphan gh-pages (अपने रेपो पर gh-pages नामक पेरेंटलेस शाखा बनाएं)
  2. git rm -rf . (ब्रांच वर्किंग ट्री से किसी भी फाइल को हटाता है)
  3. rm '.gitignore' (यहां तक ​​कि gitignore)
  4. अब वेबसाइट कंटेंट जोड़ें (index.html आदि) और कमिट करें और पुश करें।
  5. फायदा।

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

उम्मीद है की यह मदद करेगा!


3

कभी-कभी मैं बस तुरंत परियोजना में खाली शाखा बनाना चाहता हूं, फिर काम करना शुरू करूंगा, मैं सिर्फ कमांड का पालन करूंगा:

git checkout --orphan unrelated.branch.name
git rm --cached -r .
echo "init unrelated branch" > README.md
git add README.md
git commit -m "init unrelated branch"

1

यदि आपकी मौजूदा सामग्री पहले से ही प्रतिबद्ध थी, तो अब आप (Git 2.18 Q2 2018) इसे अपनी नई अनाथ शाखा में निकाल सकते हैं, "के कार्यान्वयन के बाद सेgit rebase -i --root " सीक्वेंसर मशीनरी का अधिक उपयोग करने के लिए अद्यतन किया गया है।

वह सीक्वेंसर वह है जो अब प्रतिबद्ध ग्राफ के पूरे टोपोलॉजी को कहीं और ट्रांसप्लांट करने की अनुमति देता है

देखें 8fa6eea प्रतिबद्ध , 9c85a1c प्रतिबद्ध , ebddf39 प्रतिबद्ध , 21d0764 प्रतिबद्ध , d87d48b प्रतिबद्ध , ba97aea प्रतिबद्ध द्वारा (03 मई 2018) जोहानिस Schindelin ( dscho)
(द्वारा विलय Junio सी Hamano - gitster- में c5aa4bc प्रतिबद्ध , 30 मई 2018)

सीक्वेंसर: नए रूट शुरू करने की अनुमति देता है

नए --rebase-mergesमोड के संदर्भ में , जिसे विशेष रूप से मौजूदा शाखा टोपोलॉजी को उदारतापूर्वक बदलने की अनुमति देने के लिए डिज़ाइन किया गया था, एक उपयोगकर्ता पूरी तरह से नए सिरे से शाखा में कमिट निकालना चाह सकता है जो एक नव-निर्मित रूट कमिट के साथ शुरू होता है

रूट कमिट बनने के लिए प्रतिबद्ध कमिट करने reset [new root]से पहले कमांड को सम्मिलित करना अब संभव है pick। उदाहरण:

reset [new root]
pick 012345 a commit that is about to become a root commit
pick 234567 this commit will have the previous one as parent

यह resetकमांड के अन्य उपयोगों के साथ संघर्ष नहीं करता है क्योंकि [new root]मान्य रेफरी नाम का (भाग) नहीं है: दोनों ओपनिंग ब्रैकेट और साथ ही रिफ़ नामों में स्थान अवैध है।


0

Http://wingolog.org/archives/2008/10/14/merging-in-unrelated-git-branches पर यह स्क्रिप्ट मिली और यह बहुत ही बढ़िया काम करती है!

#!/bin/bash

set -e

if test -z "$2" -o -n "$3"; then
    echo "usage: $0 REPO BRANCHNAME" >&2
    exit 1
fi

repo=$1
branch=$2

git fetch "$repo" "$branch"

head=$(git rev-parse HEAD)
fetched=$(git rev-parse FETCH_HEAD)
headref=$(git rev-parse --symbolic-full-name HEAD)

git checkout $fetched .

tree=$(git write-tree)

newhead=$(echo "merged in branch '$branch' from $repo" | git commit-tree $tree -p $head -p $fetched)
git update-ref $headref $newhead $head
git reset --hard $headref

1
मुझे विश्वास है कि उसी प्रभाव का उपयोग करके प्राप्त किया जा सकता है git fetch $REMOTE $REMOTE_BRANCH:$LOCAL_BRANCH। क्या मैं कुछ भूल रहा हूँ?
पहाड़ी ५
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.