क्या एक कमांड में git रूट डायरेक्टरी पाने का कोई तरीका है?


669

मर्क्यूरियल में रूट डाइरेक्टरी (जिसमें .hg होता है) को प्रिंट करने का एक तरीका है

hg root

क्या निर्देशिका को पाने के लिए गिट में कुछ समान है।


अच्छी स्क्रिप्ट एमिल। मैं स्क्रिप्ट ऑनलाइन उपलब्ध कराता हूं, और तर्क के रूप में फ़ाइल / निर्देशिका को जोड़ने की संभावना को अनुमति देता हूं। github.com/Dieterbe/git-scripts/commit/…
Dieter_be

इसके अलावा किसी के लिए उत्सुक या खोज bzr rootका उपयोग बाज़ार में बहुत किया गया था
क्रिस्टोफर इव्स

कृपया ध्यान दें कि 'gcd': git-Aware 'cd' Relative to Repository Root with Auto-Completion के साथ jeetworks.org/node/52 पर है
मीका विडेनमैन


1
@MichaWiedenmann: लिंक मृत है।
15:33 बजे d33tah

जवाबों:


1111

हाँ:

git rev-parse --show-toplevel

यदि आप Git कमांड को अधिक सीधे दोहराना चाहते हैं, तो आप एक उपनाम बना सकते हैं :

git config --global alias.root 'rev-parse --show-toplevel'

और अब git rootबस के रूप में कार्य करेगा hg root


नोट : एक submodule में इस की मूल निर्देशिका प्रदर्शित करेगा submodule और नहीं माता पिता भंडार। यदि आप Git> = 2.13 या इसके बाद के संस्करण का उपयोग कर रहे हैं, तो एक तरीका है कि सबमॉड्यूल्स सुपरप्रोजेक्ट की रूट डायरेक्टरी दिखा सकता है। यदि आपका git इससे पुराना है, तो यह अन्य उत्तर देखें।


148
मैं हमेशा परिभाषित करता git config --global alias.exec '!exec 'हूं इसलिए मैं जैसी चीजें कर सकता हूं git exec make। यह काम करता है क्योंकि शेल उपनाम हमेशा शीर्ष-स्तरीय निर्देशिका में निष्पादित होते हैं।
डैनियल ब्रोकमैन

8
ये क्या hg rootकरता है यह आपके चेक आउट किए गए भंडार के शीर्ष-स्तरीय निर्देशिका को प्रिंट करता है। यह आपको इसके लिए स्विच नहीं करता है (और यह वास्तव में ऐसा नहीं कर सकता है, क्योंकि वर्तमान निर्देशिका की पूरी अवधारणा और आपके शेल इंटरैक्ट कैसे हैं)।
सर्वव्यापी

14
इस समाधान के साथ स्मैल कैविट - यह किसी भी प्रतीकात्मक लिंक का अनुसरण करेगा। इसलिए, यदि आप अंदर हैं ~/my.proj/foo/bar, और आपके साथ ~/my.projसहानुभूति है ~/src/my.proj, तो उपरोक्त कमांड आपको ले जाएगा ~/src/my.proj। एक समस्या हो सकती है, अगर आप उसके बाद जो करना चाहते हैं वह पेड़ अज्ञेय नहीं है।
फ्रेंकी पेनोव जूल

3
मैं इसे git हुक के भीतर से कैसे उपयोग कर सकता हूं? विशेष रूप से, मैं पोस्ट-मर्ज हुक कर रहा हूं और मुझे स्थानीय git रेपो की वास्तविक रूट निर्देशिका प्राप्त करने की आवश्यकता है।
डेरेक

12
यह समाधान (और इस पृष्ठ पर कई अन्य जो मैंने कोशिश की है) एक गिट हुक के अंदर काम नहीं करते हैं। अधिक सटीक होने के लिए, यह तब काम नहीं करता जब आप परियोजना की .gitनिर्देशिका के अंदर हों ।
डेनिस

97

के लिए manपृष्ठ git-config( उपनाम के तहत ) कहते हैं:

यदि उर्फ ​​विस्तार को विस्मयादिबोधक बिंदु के साथ उपसर्ग किया जाता है, तो इसे शेल कमांड के रूप में माना जाएगा। [...] ध्यान दें कि शेल कमांडों को रिपॉजिटरी के शीर्ष-स्तरीय निर्देशिका से निष्पादित किया जाएगा, जो वर्तमान में आवश्यक नहीं हो सकता है।

तो, UNIX पर आप यह कर सकते हैं:

git config --global --add alias.root '!pwd'

2
इसलिए, यदि आपके पास "गिट रूट" कमांड है, तो आप इसे कैसे एक उपनाम में रख सकते हैं? अगर मैं इसे अपने में .zshrcडालूं, और मैं `उर्फ cg =" cd $ (git root) "को परिभाषित करता हूं, तो $ () भाग का मूल्यांकन स्रोत-समय पर किया जाता है, और हमेशा ~ / dotfiles को इंगित करता है, जैसा कि मेरा zzrc है ।
zelk

2
@ cormacrelf आप इसे शेल उपनाम में नहीं रखते हैं। आप इसे शेल फ़ंक्शन या स्क्रिप्ट में रख सकते हैं।
कॉनरेड मेयर

4
@ cormacrelf इसे दोहरे उद्धरण चिह्नों के बजाय एकल उद्धरणों में रखें, फिर इसे परिभाषा के समय पर विस्तारित नहीं किया जाएगा, बल्कि रनटाइम पर।
क्लैक

3
@ मेकैनिकल वास्तव में? तो आप इसे रेपो के बाहर करने की क्या उम्मीद करेंगे?
अलोइस महदाल

1
@AloisMahdal वास्तव में मेरे लिए यह एक रेपो के बाहर विफल नहीं होता है, यह बस cwd की रिपोर्ट करता है।
जस्टिनपिट्स

90

क्या --show-toplevelहाल ही में इसे जोड़ा गया है git rev-parseया कोई इसका उल्लेख क्यों नहीं कर रहा है?

से git rev-parseआदमी पेज:

   --show-toplevel
       Show the absolute path of the top-level directory.

1
इस पर ध्यान दिलाने के लिए धन्यवाद; आपकी मदद के बिना, मेरे लिए यह देखना मुश्किल होगा git-rev-parse- क्योंकि इसके नाम के बारे में सुझाव है कि यह संशोधन विनिर्देशों के बारे में है। BTW, मुझे git --work-treeकाम के समान देखकर खुशी होगी git --exec-path[=<path>]: "यदि कोई रास्ता नहीं दिया गया है, तो git वर्तमान सेटिंग को प्रिंट करेगा"; कम से कम, IMO, इस तरह की सुविधा के लिए एक तार्किक स्थान होगा।
इम्ज़ - इवान ज़खरीशेव 12

4
विशेष रूप से, आप root = rev-parse --show-toplevelअपने gitconfig में उपनाम कर सकते हैं ।
मेकैनिकल घोंघा

2
दूसरे शब्दों में, आप कर सकते हैं git config --global alias.root "rev-parse --show-toplevel"और उसके बाद git rootकाम करने के लिए सक्षम हो जाएगा
nonopolarity

@RyanTheLeach git rev-parse --show-toplevelतब काम करता है जब मैंने इसे सबमॉडल में आज़माया था । यह गिट उपमॉडल के रूट डायर को प्रिंट करता है। यह आपके लिए क्या छापता है?
वारब्यूकी

2
मैं उलझन में था कि इस उत्तर ने शीर्ष उत्तर की नकल क्यों की। बारी-बारी से बाहर है कि शीर्ष जवाब से संपादित किया गया था --show-cdupकरने के लिए --show-top-levelफ़र, 2011 में (के बाद इस जवाब प्रस्तुत किया गया था)।
वारब्किस

54

" git rev-parse --git-dir" के बारे में कैसे ?

F:\prog\git\test\copyMerge\dirWithConflicts>git rev-parse --git-dir
F:/prog/git/test/copyMerge/.git

--git-dirविकल्प काम करने लगता है।

से Git रेव-पार्स मैनुअल पृष्ठ :

--git-dir

    Show $GIT_DIR if defined else show the path to the .git directory.

आप इसे इस git setup-shस्क्रिप्ट में एक्शन में देख सकते हैं ।

यदि आप Git> = 2.13 के साथ एक सबमॉड्यूल फ़ोल्डर में हैं , तो उपयोग करें :

git rev-parse --show-superproject-working-tree

यदि आप उपयोग कर रहे हैं git rev-parse --show-toplevel, तो सुनिश्चित करें कि यह Git 2.25+ (Q1 2020) के साथ है


3
ओह रुको, यह करीब था लेकिन इसे वास्तविक .गित डायर मिलता है, न कि गिट रेपो का आधार। इसके अलावा, .it निर्देशिका कहीं और हो सकती है, इसलिए यह वह नहीं है जो मैं बिल्कुल ढूंढ रहा था।
21

2
ठीक है, मैं अब देख रहा हूं कि आप वास्तव में क्या देख रहे थे। --show-cdup तब अधिक उपयुक्त होता है। मैं दो विकल्पों के बीच अंतर को दर्शाने के लिए अपना उत्तर छोड़ता हूं।
VonC

2
यह भी प्रतीत होता है कि .gitयदि आप पहले से ही रूट डायरेक्टरी में हैं , तो यह कमांड एक सापेक्ष रास्ता देता है । (कम से कम, यह msysgit पर करता है।)
ब्लेयर होलोवे

2
+1, यह एकमात्र ऐसा उत्तर है जो मूल प्रश्न का उत्तर देता है "। वह निर्देशिका प्राप्त करें जिसमें .IT निर्देशिका होती है?"
FabienAndre

1
यह एकमात्र समाधान है जो विंडोज़ पर काम करता है और git सबमॉड्यूल्स (जैसे c: \ repositories \ myrepo \ .git \ मॉड्यूल \ mysubmodule) का उपयोग करते समय पार्स करने योग्य परिणाम देता है। यह विशेष रूप से पुन: प्रयोज्य स्क्रिप्ट में सबसे मजबूत समाधान बनाता है।
क्रिस्पीली

36

यहां एक सरल उत्तर लिखने के लिए, ताकि हम उपयोग कर सकें

git root

काम करने के लिए, बस अपने git का उपयोग करके कॉन्फ़िगर करें

git config --global alias.root "rev-parse --show-toplevel"

और फिर आप निम्नलिखित को अपने साथ जोड़ना चाहेंगे ~/.bashrc:

alias cdroot='cd $(git root)'

ताकि आप cdrootअपने रेपो के शीर्ष पर जाने के लिए उपयोग कर सकें ।


बहुत अच्छा! अंत में सुविधाजनक!
1919

एक महान जवाब, धन्यवाद!
AVARF

26

यदि आप पहले से ही शीर्ष-स्तर पर हैं या एक गिट रिपॉजिटरी में नहीं cd $(git rev-parse --show-cdup)हैं तो आपको घर ले जाएगा (बस सीडी)। cd ./$(git rev-parse --show-cdup)इसे ठीक करने का एक तरीका है।


7
एक अन्य विकल्प यह उद्धृत करने के लिए है cd "$(git rev-parse --show-cdup)":। यह काम करता है क्योंकि cd ""आपको वापस लेने के बजाय कहीं नहीं ले जाता है $HOME। और वैसे भी $ () इनवोकेशन को उद्धृत करना सबसे अच्छा अभ्यास है, अगर वे रिक्त स्थान के साथ कुछ आउटपुट करते हैं (ऐसा नहीं है कि यह कमांड इस मामले में होगा, हालांकि)।
ctrueden

यह उत्तर तब भी अच्छी तरह से काम करता है, जब आपने निर्देशिका को सिमिट के माध्यम से अपने git रेपो में बदल दिया हो । अन्य उदाहरणों में से कुछ भी अपेक्षित नहीं है जब आपके git रेपो एक सिमलिंक के तहत होता है क्योंकि वे bash के सापेक्ष git के रूट डायरेक्टरी को हल नहीं करते हैं $PWD। इस उदाहरण के $PWDबजाय git की जड़ को हल करेगा realpath $PWD
डेमियन la सील्लाज

16

वर्तमान गिट रूट निर्देशिका के निरपेक्ष पथ की गणना करने के लिए, शेल स्क्रिप्ट में उपयोग के लिए कहें, रीडलिंक और गिट रेव-पार्स के इस संयोजन का उपयोग करें:

gitroot=$(readlink -f ./$(git rev-parse --show-cdup))

git-rev-parse --show-cdupयदि आप रूट पर हैं, तो आपको अपने cwd, या खाली स्ट्रिंग से रूट की सही संख्या प्राप्त होगी। फिर खाली स्ट्रिंग मामले से निपटने के लिए "./" और पूर्व readlink -fपथ पर अनुवाद करने के लिए उपयोग करें।

आप git-rootइस तकनीक को लागू करने के लिए एक शेल स्क्रिप्ट के रूप में अपने PATH में एक कमांड बना सकते हैं :

cat > ~/bin/git-root << EOF
#!/bin/sh -e
cdup=$(git rev-parse --show-cdup)
exec readlink -f ./$cdup
EOF
chmod 755 ~/bin/git-root

(ऊपर git-root बनाने के लिए और निष्पादित बिट्स सेट करने के लिए एक टर्मिनल में चिपकाया जा सकता है; वास्तविक स्क्रिप्ट 2, 3 और 4. लाइनों में है)

और फिर आप git rootअपने वर्तमान पेड़ की जड़ पाने के लिए दौड़ने में सक्षम होंगे । ध्यान दें कि शेल स्क्रिप्ट में, "-ई" का उपयोग करके शेल से बाहर निकलने का कारण बन सकता है यदि रेव-पार्स विफल हो जाता है ताकि आप सही तरीके से निकास की स्थिति और त्रुटि संदेश प्राप्त कर सकें यदि आप गिट डायरेक्टरी में नहीं हैं।


2
आपके उदाहरण टूट जाएंगे यदि गिट "रूट" निर्देशिका पथ में रिक्त स्थान हैं। हमेशा "$(git rev-parse ...)"हैक की तरह उपयोग करें ./$(git rev-parse ...)
मिको रानाल्टेन

readlink -fबीएसडी पर समान काम नहीं करता है। इस एसओ को वर्कअराउंड के लिए देखें । पायथन जवाब शायद कुछ भी स्थापित किए बिना काम करेगा python -c 'import os, sys; print(os.path.realpath(sys.argv[1]))' "$(git rev-parse --show-cdup)":।
Bluu

16

जैसा कि दूसरों ने नोट किया है, समाधान का मूल उपयोग करना है git rev-parse --show-cdup। हालाँकि, पता करने के लिए कुछ किनारे मामले हैं:

  1. जब cwd पहले से ही काम करने वाले पेड़ की जड़ है, तो कमांड एक खाली स्ट्रिंग देता है।
    दरअसल यह एक खाली लाइन का निर्माण करता है, लेकिन पीछे की लाइन को तोड़ने के लिए कमांड प्रतिस्थापन पट्टी को तोड़ देता है। अंतिम परिणाम एक खाली स्ट्रिंग है।

    अधिकांश उत्तर आउटपुट को पूर्व-निर्धारित करने का सुझाव देते हैं, ./ताकि "./"इसे खिलाए जाने से पहले एक खाली आउटपुट बन जाए cd

  2. जब GIT_WORK_TREE को किसी ऐसे स्थान पर सेट किया जाता है जो cwd का जनक नहीं है, तो आउटपुट निरपेक्ष नामनाम हो सकता है।

    ./इस स्थिति में Prepending गलत है। यदि ./कोई निरपेक्ष मार्ग से जुड़ा हुआ है, तो यह एक सापेक्ष पथ बन जाता है (और वे केवल उसी स्थान को संदर्भित करते हैं यदि cwd सिस्टम का रूट डायरेक्टरी है)।

  3. आउटपुट में व्हॉट्सएप हो सकता है।

    यह वास्तव में केवल दूसरे मामले में लागू होता है, लेकिन इसका एक आसान निर्धारण है: कमांड प्रतिस्थापन (और मूल्य के किसी भी बाद के उपयोग) के आसपास दोहरे उद्धरण चिह्नों का उपयोग करें।

जैसा कि अन्य उत्तरों ने उल्लेख किया है, हम कर सकते हैं cd "./$(git rev-parse --show-cdup)", लेकिन यह दूसरे किनारे के मामले में टूटता है (और तीसरे किनारे का मामला यदि हम दोहरे उद्धरण छोड़ते हैं)।

कई गोले cd ""एक नो-ऑप के रूप में व्यवहार करते हैं , इसलिए उन गोले के लिए हम कर सकते हैं cd "$(git rev-parse --show-cdup)"(दोहरे उद्धरण पहले किनारे के मामले में एक तर्क के रूप में खाली स्ट्रिंग की रक्षा करते हैं, और तीसरे किनारे के मामले में व्हाट्सएप को संरक्षित करते हैं)। POSIX का कहना है कि इसका परिणाम cd ""अनिर्दिष्ट है, इसलिए इस धारणा को बनाने से बचना सबसे अच्छा हो सकता है।

एक समाधान जो उपरोक्त सभी मामलों में काम करता है, उसे किसी प्रकार के परीक्षण की आवश्यकता होती है। जाहिर है, यह इस तरह लग सकता है:

cdup="$(git rev-parse --show-cdup)" && test -n "$cdup" && cd "$cdup"

cdपहले किनारे के मामले के लिए नहीं किया जाता है।

यदि यह cd .पहले किनारे के मामले में चलने के लिए स्वीकार्य है , तो पैरामीटर के विस्तार में सशर्त किया जा सकता है:

cdup="$(git rev-parse --show-cdup)" && cd "${cdup:-.}"

आप केवल "git config --global --add alias.root '? Pwd'" और शेल उर्फ ​​gitroot = 'cd git root' का उपयोग क्यों नहीं करते हैं जो आपके ऊपर दिए गए उत्तर का उपयोग करता है?
जेसन एक्सेलसन

1
एक उपनाम का उपयोग करना संभव नहीं हो सकता है, उदाहरण के लिए यदि आप इसे स्क्रिप्ट करना चाहते हैं और कस्टम उपनाम पर भरोसा नहीं कर सकते।
नीला

1
उप मॉड्यूल एक और कोने का मामला है।
रयान द लेच

14

बस अगर आप इस रास्ते को Git को खिला रहे हैं, तो उपयोग करें :/

# this adds the whole working tree from any directory in the repo
git add :/

# and is equal to
git add $(git rev-parse --show-toplevel)

12

लघु समाधान जो सबमॉड्यूल के साथ, हुक में और .gitनिर्देशिका के अंदर काम करते हैं

यहाँ संक्षिप्त उत्तर है जो सबसे अधिक चाहिए:

r=$(git rev-parse --git-dir) && r=$(cd "$r" && pwd)/ && echo "${r%%/.git/*}"

यह एक गिट वर्किंग ट्री ( .gitडायरेक्टरी के अंदर सहित ) में कहीं भी काम करेगा , लेकिन मानता है कि रिपॉजिटरी डायरेक्टरी (ओं) को कहा जाता है .git(जो कि डिफ़ॉल्ट है)। सबमॉड्यूल्स के साथ, यह सबसे बाहरी वाले रिपॉजिटरी की जड़ में जाएगा।

यदि आप वर्तमान सबमॉड्यूल उपयोग की जड़ में जाना चाहते हैं:

echo $(r=$(git rev-parse --show-toplevel) && ([[ -n $r ]] && echo "$r" || (cd $(git rev-parse --git-dir)/.. && pwd) ))

आसानी से अपने submodule जड़ में एक आदेश पर अमल करने के तहत [alias]अपने में .gitconfigऐड:

sh = "!f() { root=$(pwd)/ && cd ${root%%/.git/*} && git rev-parse && exec \"$@\"; }; f"

इससे आप चीजों को आसानी से कर सकते हैं git sh ag <string>

मजबूत समाधान जो अलग-अलग नाम या बाहरी .gitया $GIT_DIRनिर्देशिकाओं का समर्थन करता है ।

ध्यान दें कि $GIT_DIRकहीं बाहरी (और बुलाया नहीं जा सकता है .git), इसलिए आगे की जाँच की आवश्यकता है।

इसे अपने में रखें .bashrc:

# Print the name of the git working tree's root directory
function git_root() {
  local root first_commit
  # git displays its own error if not in a repository
  root=$(git rev-parse --show-toplevel) || return
  if [[ -n $root ]]; then
    echo $root
    return
  elif [[ $(git rev-parse --is-inside-git-dir) = true ]]; then
    # We're inside the .git directory
    # Store the commit id of the first commit to compare later
    # It's possible that $GIT_DIR points somewhere not inside the repo
    first_commit=$(git rev-list --parents HEAD | tail -1) ||
      echo "$0: Can't get initial commit" 2>&1 && false && return
    root=$(git rev-parse --git-dir)/.. &&
      # subshell so we don't change the user's working directory
    ( cd "$root" &&
      if [[ $(git rev-list --parents HEAD | tail -1) = $first_commit ]]; then
        pwd
      else
        echo "$FUNCNAME: git directory is not inside its repository" 2>&1
        false
      fi
    )
  else
    echo "$FUNCNAME: Can't determine repository root" 2>&1
    false
  fi
}

# Change working directory to git repository root
function cd_git_root() {
  local root
  root=$(git_root) || return 1  # git_root will print any errors
  cd "$root"
}

टाइपिंग द्वारा इसे निष्पादित git_root(अपने खोल पुनरारंभ करने के बाद: exec bash)


इस कोड को git रिपॉजिटरी की जड़ खोजने के लिए Robust bash फ़ंक्शन में कोड-समीक्षा की जा रही है । अपडेट के लिए वहाँ देखें।
टॉम हेल

अच्छा लगा। अधिक जटिल है कि मैंने 7 साल पहले क्या प्रस्ताव रखा था ( stackoverflow.com/a/958125/6309 ), लेकिन अभी भी +1
वॉन सी

1
उन पंक्तियों के साथ छोटा समाधान है: (root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)लेकिन यह बाहरी $GIT_DIRएस को कवर नहीं करता है जो कि अन्य के नाम पर रखा गया है.git
टॉम हेल

मुझे आश्चर्य है कि अगर यह कई वर्कट्रीज़ को ध्यान में रखता है जो अब git 2.5+ ( stackoverflow.com/a/30185564/6309 ) में संभव हैं
VonC

करने के लिए आपकी टिप्पणी लिंक "रूट को खोजने के लिए मजबूत बैश समारोह ..." अब एक 404. देता है
ErikE

8

"Git config" उत्तर को थोड़ा संशोधित करने के लिए:

git config --global --add alias.root '!pwd -P'

और रास्ता साफ हो जाओ। बहुत अच्छा।


7

यदि आप ऐसा करने के लिए एक अच्छे उपनाम की तलाश कर रहे हैं, cdतो यदि आप एक गीदड़ में नहीं हैं, तो इसे न उड़ाएं:

alias ..g='git rev-parse && cd "$(git rev-parse --show-cdup)"'


6

यह शेल उर्फ ​​काम करता है चाहे आप एक गिट सबडिर में हों, या शीर्ष स्तर पर:

alias gr='[ ! -z `git rev-parse --show-toplevel` ] && cd `git rev-parse --show-toplevel || pwd`'

बैकटिक्स के बजाय आधुनिक सिंटैक्स का उपयोग करने के लिए अपडेट किया गया:

alias gr='[ ! -z $(git rev-parse --show-toplevel) ] && cd $(git rev-parse --show-toplevel || pwd)'

5
alias git-root='cd \`git rev-parse --git-dir\`; cd ..'

बाकी सब कुछ कुछ बिंदु पर विफल रहता है या तो होम डायरेक्टरी में जा रहा है या बस बुरी तरह से विफल हो रहा है। यह GIT_DIR पर वापस जाने का सबसे तेज़ और सबसे छोटा तरीका है।


ऐसा लगता है जैसे 'git rev-parse --git-dir' सबसे साफ समाधान है।
अस्तबलोग

3
यह तब विफल होता है, जब $GIT_DIRवर्कट्री का उपयोग करके अलग किया जाता है .git-फाइल्स और gitdir: SOMEPATH। नतीजतन यह सबमॉड्यूल्स के लिए विफल रहता है, भी, जहां $GIT_DIRशामिल है .git/modules/SUBMODULEPATH
टीनो

5

यहां एक स्क्रिप्ट है जो मैंने लिखा है कि दोनों मामलों को संभालती है: 1) एक कार्यक्षेत्र के साथ भंडार, 2) नंगे भंडार।

https://gist.github.com/jdsumsion/6282953

git-root (अपने पथ में निष्पादन योग्य फ़ाइल):

#!/bin/bash
GIT_DIR=`git rev-parse --git-dir` &&
(
  if [ `basename $GIT_DIR` = ".git" ]; then
    # handle normal git repos (with a .git dir)
    cd $GIT_DIR/..
  else
    # handle bare git repos (the repo IS a xxx.git dir)
    cd $GIT_DIR
  fi
  pwd
)

उम्मीद है कि यह उपयोगी है।


1
कीथ, सुझाव के लिए धन्यवाद, मैंने स्क्रिप्ट शामिल की है।
१ .:

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

1
हालांकि यह git submoduleएस के भीतर विफल रहता है जहां $GIT_DIRकुछ ऐसा होता है /.git/modules/SUBMODULE। इसके अलावा, आप मानते हैं कि .gitनिर्देशिका गैर-नंगे मामले में कार्यस्थल का हिस्सा है।
टीनो

4
$ git config alias.root '!pwd'
# then you have:
$ git root

यह उर्फ ​​एक वैश्विक के रूप में विफल हो जाएगा। इसके बजाय इसका प्रयोग करें (~ / .gitconfig में): [alias] findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [pwd ]" && exit 0; cd .. && echo "IN pwd" && f;}; f"
FractalSpace

नीचे क्यों? कृपया किसी त्रुटि को उजागर करें या इसके बजाय सुधार का सुझाव दें।
फ्रैक्टलस्पेस

1
मेरे लिए git config --global alias.root '!pwd'काम करता है। मैं ऐसे किसी भी मामले में हाजिर नहीं हो पा रहा था जहाँ यह गैर-वैश्विक संस्करण के लिए अलग तरह से काम करता हो। (यूनिक्स, जीआईटी 1.7.10.4) बीटीडब्ल्यू: आपकी findrootआवश्यकता एक /.gitअंतहीन पुनरावृत्ति से बचने के लिए है।
टीनो

4

2.13.0 Git के बाद से , यह रूट प्रोजेक्ट का रास्ता दिखाने के लिए एक नए विकल्प का समर्थन करता है, जो सबमॉड्यूल के अंदर से उपयोग किए जाने पर भी काम करता है:

git rev-parse --show-superproject-working-tree

git-scm.com/docs/… । दिलचस्प। मुझे वह याद आ गई होगी। +1
वॉनसी

3
यद्यपि चेतावनी: "यदि वर्तमान भंडार को किसी भी परियोजना द्वारा सबमॉड्यूल के रूप में उपयोग नहीं किया जाता है, तो आउटपुट कुछ भी नहीं है।"
वॉन

टिप्पणी के लिए धन्यवाद! मैंने उस पर ध्यान नहीं दिया था।
जोर्डी विलालता प्रात

2

शेल फ्रेमवर्क में पूर्व-कॉन्फ़िगर शेल उपनाम

यदि आप एक शेल फ्रेमवर्क का उपयोग करते हैं, तो पहले से ही शेल उपनाम उपलब्ध हो सकता है:

  • $ grtमें ओह-मेरी-zsh (68k) ( cd $(git rev-parse --show-toplevel || echo "."))
  • $ git-rootमें prezto (8.8k) (प्रदर्शित करता है काम कर पेड़ जड़ के लिए पथ)
  • $ g.. zimfw (1k) (वर्किंग ट्री के शीर्ष स्तर पर वर्तमान निर्देशिका को बदलता है।)

1

मैं डेनियल ब्रॉकमैन की उत्कृष्ट टिप्पणी पर विस्तार करना चाहता था।

परिभाषित git config --global alias.exec '!exec 'करने से आप ऐसा कर सकते हैं git exec makeक्योंकि man git-configराज्य के रूप में :

यदि उर्फ ​​विस्तार को विस्मयादिबोधक बिंदु के साथ उपसर्ग किया जाता है, तो इसे शेल कमांड के रूप में माना जाएगा। [...] ध्यान दें कि शेल कमांडों को रिपॉजिटरी के शीर्ष-स्तरीय निर्देशिका से निष्पादित किया जाएगा, जो वर्तमान में आवश्यक नहीं हो सकता है।

यह जानना आसान है कि $GIT_PREFIXएक रिपॉजिटरी के शीर्ष-स्तरीय निर्देशिका के सापेक्ष वर्तमान निर्देशिका का मार्ग क्या होगा। लेकिन, यह जानना केवल आधी लड़ाई ™ है। शेल वैरिएबल विस्तार इसका उपयोग करने के बजाय कठिन बनाता है। इसलिए मैं सुझाव देता हूं कि मैं इस bash -cतरह का उपयोग करूं :

git exec bash -c 'ls -l $GIT_PREFIX'

अन्य आदेशों में शामिल हैं:

git exec pwd
git exec make

1

यदि किसी को gitनिष्पादन योग्य आवश्यकता के बिना, ऐसा करने के लिए POSIX आज्ञाकारी तरीके की आवश्यकता होती है :

git-root:

#$1: Path to child directory
git_root_recurse_parent() {
    # Check if cwd is a git root directory
    if [ -d .git/objects -a -d .git/refs -a -f .git/HEAD ] ; then
        pwd
        return 0
    fi

    # Check if recursion should end (typically if cwd is /)
    if [ "${1}" = "$(pwd)" ] ; then
        return 1
    fi

    # Check parent directory in the same way
    local cwd=$(pwd)
    cd ..
    git_root_recurse_parent "${cwd}"
}

git_root_recurse_parent

यदि आप किसी स्क्रिप्ट के हिस्से के रूप में कार्यक्षमता चाहते हैं, तो शेबंग को हटा दें, और अंतिम git_root_recurse_parentपंक्ति को इसके साथ बदलें :

git_root() {
    (git_root_recurse_parent)
}

कैविएट: यदि इसे गिट रेपो में नहीं कहा जाता है, तो पुनरावृत्ति बिल्कुल भी समाप्त नहीं होती है।
एएच

@AH ifस्टेटमेंट में यह जाँचना था कि क्या आपने निर्देशिका बदल दी है। यदि यह उसी निर्देशिका में रहता है, तो यह मानता है कि आप कहीं अटक गए हैं (जैसे /), और ब्रेक पुनरावर्तन। बग तय हो गया है, और अब उम्मीद के मुताबिक काम करना चाहिए। इस पर ध्यान दिलाने के लिए धन्यवाद।
स्वैग

0

आज खुद ही इसका हल निकालना था। इसे C # में हल किया, क्योंकि मुझे एक कार्यक्रम के लिए इसकी आवश्यकता थी, लेकिन मुझे लगता है कि इसे फिर से लिखा जा सकता है। इस सार्वजनिक डोमेन पर विचार करें।

public static string GetGitRoot (string file_path) {

    file_path = System.IO.Path.GetDirectoryName (file_path);

    while (file_path != null) {

        if (Directory.Exists (System.IO.Path.Combine (file_path, ".git")))
            return file_path;

        file_path = Directory.GetParent (file_path).FullName;

    }

    return null;

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