गिट निर्देशिका में नहीं है, जबकि गिट पुल


308

मान लीजिए कि मेरे पास एक निर्देशिका है /X/Y, जो एक गिट रिपॉजिटरी है। क्या किसी भी तरह git pullसे अंदर से एक कमांड को कॉल करना संभव है /X, लेकिन /X/Yनिर्देशिका को लक्षित करना ?

संपादित करें: मुझे लगता है कि मैं विशेष रूप से सोच रहा था: क्या यह एक git कमांड का उपयोग करके संभव है, लेकिन निर्देशिकाओं को बदलने के बिना?

नोट: मैंने VonC के उत्तर को स्वीकार कर लिया है क्योंकि यह पिछले विकल्पों की तुलना में बहुत अधिक सुरुचिपूर्ण है। 1.8.5 वर्ष से अधिक पुराने Git चलाने वाले लोगों के लिए, कृपया नीचे दिए गए bstpierre का उत्तर देखें


2
जब तक आप GIT_DIR को अनसेट नहीं करते हैं, तब तक हुक के भीतर गिट-पुल का उपयोग करने से मैं इसे जोड़ना चाहूंगा। से मिलता जुलता।
zpmorgan

1.8.5 git (Q4 2013) से शुरू होकर, आप "git कमांड का उपयोग कर पाएंगे, लेकिन निर्देशिकाओं को बदले बिना"। देखें नीचे मेरा उत्तर
VonC

जवाबों:


453

1.8.5 git (Q4 2013) से शुरू होकर , आप "Git कमांड का उपयोग कर पाएंगे, लेकिन निर्देशिकाओं को बदले बिना"।

ठीक वैसे ही जैसे " make -C <directory>", " git -C <directory> ..." गित को कुछ और करने से पहले वहां जाने के लिए कहता है

देखें नाज़री रामली द्वारा प्रतिबद्ध 44e1e4 :

वर्तमान निर्देशिका को छोड़े बिना एक अलग निर्देशिका में Git कमांड को लागू करने के लिए अधिक कुंजीवृत्त लेता है:

  1. (cd ~/foo && git status)
    git --git-dir=~/foo/.git --work-tree=~/foo status
    GIT_DIR=~/foo/.git GIT_WORK_TREE=~/foo git status
  2. (cd ../..; git grep foo)
  3. for d in d1 d2 d3; do (cd $d && git svn rebase); done

ऊपर दिखाए गए तरीके स्क्रिप्टिंग के लिए स्वीकार्य हैं लेकिन त्वरित कमांड लाइन चालान के लिए बहुत बोझिल हैं।

इस नए विकल्प के साथ, उपरोक्त कुछ कीस्ट्रोक्स के साथ किया जा सकता है:

  1. git -C ~/foo status
  2. git -C ../.. grep foo
  3. for d in d1 d2 d3; do git -C $d svn rebase; done

Git 2.3.4 (मार्च 2015), और के बाद से 6a536e2 प्रतिबद्ध द्वारा कार्तिक नायक ( KarthikNayak) , gitव्यवहार करेगा " git -C '<path>'एक के रूप में" नो-सेशन जब <path>खाली है।

" git -C """ अनजाने में त्रुटि के साथ " Cannot change to ''" मर जाता है , जबकि शेल सीडी "" को नो-ऑप मानता है।
शेल के व्यवहार को एक मिसाल के रूप में लेते हुए, git-C "" को नो-ऑप के रूप में भी सिखाएं ।


4 साल बाद, Git 2.23 (Q3 2019) दस्तावेज़ जो ' git -C ""' काम करता है और निर्देशिका नहीं बदलता है

6a536e2 के बाद से यह व्यवहार कर रहा है git: ( "व्यवहार करें" git -C '<path>'जब कोई <path>खाली न हो, तो 2015-03-06, Git v2.3.4)।

इसका मतलब है कि प्रलेखन अब (अंत में) शामिल हैं:

यदि ' <path>' मौजूद है, लेकिन खाली है, उदाहरण के लिए -C "", तो वर्तमान कार्य निर्देशिका को अपरिवर्तित छोड़ दिया गया है।


आप git -Cउदाहरण के रूप में Git 2.26 (Q1 2020) के साथ उपयोग कर सकते हैं ।

देखें b441717 प्रतिबद्ध , प्रतिबद्ध 9291e63 , प्रतिबद्ध 5236fce , प्रतिबद्ध 10812c2 , प्रतिबद्ध 62d58cd , b87b02c प्रतिबद्ध , प्रतिबद्ध 9b92070 , प्रतिबद्ध 3595d10 , f511bc0 प्रतिबद्ध , प्रतिबद्ध f6041ab , प्रतिबद्ध f46c243 , 99c049b प्रतिबद्ध , प्रतिबद्ध 3,738,439 , 7,717,242 प्रतिबद्ध , b8afb90 प्रतिबद्ध (20 दिसंबर 2019) डेंटन लियूDenton-L द्वारा ( )
(द्वारा विलय Junio सी Hamano - gitster- में प्रतिबद्ध 381e8e9 , 05 फरवरी 2020)

t1507: पंक्ति में full_name()

साइन-ऑफ-बाय: डेंटन लियू

इससे पहले, हम चल रहे थे test_must_fail full_name। हालाँकि, test_must_failइसका उपयोग केवल git कमांड पर किया जाना चाहिए।
इनलाइन full_name()ताकि हम सीधे कमांड test_must_failपर उपयोग कर gitसकें।

जब full_name()में पेश किया गया था 28fb84382b ( "परिचय <branch>@{upstream}अंकन", 2009-09-10, Git v1.7.0-RC0 - मर्ज ), git -Cविकल्प उपलब्ध नहीं है अभी तक था (क्योंकि यह में पेश किया गया था 44e1e4d67d ( " git: दिए गए एक निर्देशिका में चलाने -C विकल्प के साथ ", 2013-09-09, Git v1.8.5-rc0 - बैच # 5 में सूचीबद्ध मर्ज ))। नतीजतन, सहायक फ़ंक्शन ने प्रत्येक बार मैन्युअल रूप से आवश्यकता को हटा दिया । हालाँकि, अब उपलब्ध होने के बाद , हम इसके बजाय और इनलाइन का उपयोग कर सकते हैं ।
cdgit -Cfull_name()


6
वाह, बहुत अच्छा! यह अधिक सुंदर तरीका है, इसलिए मैं इसे भविष्य के दर्शकों के लिए स्वीकार करूंगा।
गाविन एंडेरेग

1
मेरे लिए काम नहीं करता है: # git --version और& git -C ~ / .m2 / चेकआउट मास्टर git संस्करण 1.8.3.4 (Apple Git-47) अज्ञात विकल्प: -C उपयोग: git [--version] [bhelp] ] [-c name = value] [--exec-path [= <path>] [- html-path] [--man-path] [--info-path] [-p | - paginate -नो-पेजर] [-नो-प्रतिस्थापन-वस्तुएं] [--bare] [--गीत-दिर = <पथ>] [- कार्य-वृक्ष = <पथ>] [- namespace = <name> ] <कमांड> [<args>]
Jan Galinski

7
@JanGalinski लेकिन मैंने "शुरुआती 1.8.5 git" का उल्लेख किया। तो 1.8.3.x git उस विकल्प के बारे में अभी तक नहीं जानता है।
वॉनसी

2
उबंटू 12.04 पर मुझे एक नया गिट संस्करण स्थापित करना था। मैंने इसे इस तरह किया: apt-get install software-properties-common python-software-propertiesफिर git रेपो जोड़ें add-apt-repository ppa:git-core/ppa। अंतिम चरण git को अपडेट करना है apt-get update && apt-get upgrade:।
ph3nx


54

संपादित करें :

या तो एक बग के साथ है git pull, या आप वह नहीं कर सकते जो आप उस कमांड के साथ करने की कोशिश कर रहे हैं। आप इसे प्राप्त कर सकते हैं और प्राप्त कर सकते हैं:

cd /X
git --git-dir=/X/Y/.git fetch
git --git-dir=/X/Y/.git --work-tree=/X/Y merge origin/master

मूल उत्तर :

मान लें कि आप बैश या समान चला रहे हैं, तो आप कर सकते हैं (cd /X/Y; git pull)

Git आदमी पेज निर्दिष्ट करता है कुछ चर (देखें "Git भंडार") है कि लगता है जैसे वे मदद करनी चाहिए, लेकिन मैं उन्हें सही (मेरे भंडार में / tmp / ggg2 के साथ) काम नहीं कर सकते हैं:

GIT_WORK_TREE=/tmp/ggg2 GIT_DIR=/tmp/ggg2/.git git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.

मेरे cwd / tmp को उस रेपो अपडेट करने के दौरान नीचे कमांड चलाना, लेकिन अपडेट की गई फाइल वर्किंग ट्री / tmp / ggg2 के बजाय / tmp में दिखाई देती है:

GIT_DIR=/tmp/ggg2/.git git pull

एक ऐसे ही प्रश्न का उत्तर भी देखें , जो कि --git-dirऔर --work-treeझंडे को प्रदर्शित करता है ।


क्या आपने केवल GIT_WORK_TREE का उपयोग करने का प्रयास किया?
तीरंदाज़ी

@ एरोमास्टर: हां, यदि आप ऐसा करते हैं, तो .gitडायरेक्ट्री नहीं मिल सकती ।
bstpierre

ठीक है, मैन पेज कहता है कि अगर GIT_DIR सेट नहीं है, तो GIT_WORK_TREE का उपयोग नहीं किया जाता है। यह अजीब लगता है कि इसका काम नहीं कर रहा है, जब दोनों का उपयोग किया जाता है।
तीरंदाज़ी

@ एरोमास्टर: मुझे आश्चर्य होगा कि क्या यहाँ कहीं बग है। यदि मैं करता हूं git --git-dir=/tmp/ggg2/.git --work-tree=/tmp/ggg2 pull, तो मुझे एक त्रुटि संदेश मिलता है। लेकिन अगर मैं git --git-dir=/tmp/ggg2/.git --work-tree=. pull/ tmp में हूँ, तो यह अद्यतन की गई फ़ाइलों को / tmp में रखता है जैसा कि इसे करना चाहिए।
bstpierre

@bstpierre: मैं अभी स्थापित Git के साथ एक सिस्टम के लिए उपयोग नहीं है, लेकिन अगर मैं मैं के साथ अन्य विकल्पों की कोशिश कर रहा हो जाएगा --work-treeकी तरह अभी --work-tree=/tmp/ggg2/और --work-tree=/tmp/ggg2/.के बाद से यह कैसे अपने रास्ते पार्स करने में कोई समस्या हो सकती है।
तीरंदाज़ी

32

आप इसे बैश स्क्रिप्ट या गिट उपनाम में लपेट सकते हैं:

cd /X/Y && git pull && cd -

1
यह निश्चित रूप से चाल है, लेकिन मुझे आश्चर्य है कि अगर निर्देशिका बदलने के बिना git कमांड का उपयोग करने का कोई तरीका है। मुझे लगता है कि वहाँ नहीं है शुरू कर रहा हूँ।
गैविन एंडरग

1
और pushd/popdइसके बजाय जोड़ी का उपयोग करेंcd/cd-
axd

या आप सीडी को वापस आने से रोकने के लिए एक उपधारा का उपयोग कर सकते हैं:(cd xyz && git pull)
कर्मोदय

30

यह पोस्ट थोड़ी पुरानी है इसलिए इसमें बग हो सकता है और इसे ठीक कर दिया गया था, लेकिन मैंने अभी ऐसा किया है:

git --work-tree=/X/Y --git-dir=/X/Y/.git pull origin branch

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


मुझे यह समाधान पसंद है क्योंकि यह निर्देशिकाओं के साथ काम करता है जैसे \\ रीमोटेमाचिन \ सी $ \ फ़ोल्डर \ आदि
ट्वैसब्रिलिग

7

जैसा कि मेरे कुछ सर्वर पुराने उबंटू एलटीएस संस्करणों पर हैं, मैं आसानी से नवीनतम संस्करण के लिए गिट को अपग्रेड नहीं कर सकता (जो कुछ उत्तरों में वर्णित -C विकल्प का समर्थन करता है)।

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

pushd /X/Y
git pull
popd

या, यह एक लाइनर के रूप में कर रहा है:

pushd /X/Y; git pull; popd

लिनक्स और विंडोज दोनों में पुशड और पॉपड कमांड हैं।


5

संयोजन का उपयोग करना pushd, git pullऔर popd, हम इस कार्यक्षमता को प्राप्त कर सकते हैं:

pushd <path-to-git-repo> && git pull && popd

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

pushd "E:\Fake Directory\gitrepo" && git pull && popd

ये अद्भुत है। पूरी तरह से काम करता है
खिंचाव

4

आप इस तरह से एक स्क्रिप्ट लिख सकते हैं:

cd /X/Y
git pull

आप इसे कुछ इस तरह नाम दे सकते हैं gitpull
यदि आप इसके बजाय इसके बजाय मनमानी निर्देशिका करना चाहते हैं /X/Y:

cd $1
git pull

फिर आप इसे अंतिम रूप से कॉल कर सकते हैं gitpull /X/Z
, आप रिपॉजिटरी ढूंढने का प्रयास कर सकते हैं। मेरे पास एक ~/gitफ़ोल्डर है जिसमें रिपॉजिटरी हैं, और आप इसका उपयोग उन सभी पर एक पुल बनाने के लिए कर सकते हैं।

g=`find /X -name .git`
for repo in ${g[@]}
do
    cd ${repo}
    cd ..
    git pull
done

2
यदि आप इसे कमांड लाइन से करना चाहते हैं, तो बस इसे सबस्क्रिप्शन में करें (cd /X/Y && git pull):।
कैस्केबेल

2

मेरे जैसे किसी के लिए जो एक रिमोट सर्वर पर ड्रश (ड्रुपल शेल) कमांड के जरिए ऐसा करने की कोशिश कर रहा था, आप उस समाधान का उपयोग नहीं कर पाएंगे जिसके लिए आपको वर्किंग डायरेक्टरी में सीडी की आवश्यकता होती है:

इसके बजाय आपको समाधान का उपयोग करने की आवश्यकता है जो एक पुल और एक मर्ज में टूट जाता है:

drush @remote exec git --git-dir=/REPO/PATH --work-tree=/REPO/WORKDIR-PATH fetch origin
drush @remote exec git --git-dir=/REPO/PATH --work-tree=/REPO/WORKDIR-PATH merge origin/branch

1

यह एक समान समस्या हो सकती है, लेकिन आप केवल आपके आदेशों की श्रृंखला भी कर सकते हैं। जैसे

एक लाइन पर

cd ~/Sites/yourdir/web;git pull origin master

या एसएसएच के माध्यम से।

ssh username@atyourserver.com -t "cd ~/Sites/thedir/web;git pull origin master"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.