मर्क्यूरियल में रूट डाइरेक्टरी (जिसमें .hg होता है) को प्रिंट करने का एक तरीका है
hg root
क्या निर्देशिका को पाने के लिए गिट में कुछ समान है।
bzr root
का उपयोग बाज़ार में बहुत किया गया था
मर्क्यूरियल में रूट डाइरेक्टरी (जिसमें .hg होता है) को प्रिंट करने का एक तरीका है
hg root
क्या निर्देशिका को पाने के लिए गिट में कुछ समान है।
bzr root
का उपयोग बाज़ार में बहुत किया गया था
जवाबों:
हाँ:
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 इससे पुराना है, तो यह अन्य उत्तर देखें।
git config --global alias.exec '!exec '
हूं इसलिए मैं जैसी चीजें कर सकता हूं git exec make
। यह काम करता है क्योंकि शेल उपनाम हमेशा शीर्ष-स्तरीय निर्देशिका में निष्पादित होते हैं।
hg root
करता है यह आपके चेक आउट किए गए भंडार के शीर्ष-स्तरीय निर्देशिका को प्रिंट करता है। यह आपको इसके लिए स्विच नहीं करता है (और यह वास्तव में ऐसा नहीं कर सकता है, क्योंकि वर्तमान निर्देशिका की पूरी अवधारणा और आपके शेल इंटरैक्ट कैसे हैं)।
~/my.proj/foo/bar
, और आपके साथ ~/my.proj
सहानुभूति है ~/src/my.proj
, तो उपरोक्त कमांड आपको ले जाएगा ~/src/my.proj
। एक समस्या हो सकती है, अगर आप उसके बाद जो करना चाहते हैं वह पेड़ अज्ञेय नहीं है।
.git
निर्देशिका के अंदर हों ।
के लिए man
पृष्ठ git-config
( उपनाम के तहत ) कहते हैं:
यदि उर्फ विस्तार को विस्मयादिबोधक बिंदु के साथ उपसर्ग किया जाता है, तो इसे शेल कमांड के रूप में माना जाएगा। [...] ध्यान दें कि शेल कमांडों को रिपॉजिटरी के शीर्ष-स्तरीय निर्देशिका से निष्पादित किया जाएगा, जो वर्तमान में आवश्यक नहीं हो सकता है।
तो, UNIX पर आप यह कर सकते हैं:
git config --global --add alias.root '!pwd'
.zshrc
डालूं, और मैं `उर्फ cg =" cd $ (git root) "को परिभाषित करता हूं, तो $ () भाग का मूल्यांकन स्रोत-समय पर किया जाता है, और हमेशा ~ / dotfiles को इंगित करता है, जैसा कि मेरा zzrc है ।
क्या --show-toplevel
हाल ही में इसे जोड़ा गया है git rev-parse
या कोई इसका उल्लेख क्यों नहीं कर रहा है?
से git rev-parse
आदमी पेज:
--show-toplevel
Show the absolute path of the top-level directory.
git-rev-parse
- क्योंकि इसके नाम के बारे में सुझाव है कि यह संशोधन विनिर्देशों के बारे में है। BTW, मुझे git --work-tree
काम के समान देखकर खुशी होगी git --exec-path[=<path>]
: "यदि कोई रास्ता नहीं दिया गया है, तो git वर्तमान सेटिंग को प्रिंट करेगा"; कम से कम, IMO, इस तरह की सुविधा के लिए एक तार्किक स्थान होगा।
root = rev-parse --show-toplevel
अपने gitconfig में उपनाम कर सकते हैं ।
git config --global alias.root "rev-parse --show-toplevel"
और उसके बाद git root
काम करने के लिए सक्षम हो जाएगा
git rev-parse --show-toplevel
तब काम करता है जब मैंने इसे सबमॉडल में आज़माया था । यह गिट उपमॉडल के रूट डायर को प्रिंट करता है। यह आपके लिए क्या छापता है?
--show-cdup
करने के लिए --show-top-level
फ़र, 2011 में (के बाद इस जवाब प्रस्तुत किया गया था)।
" 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) के साथ है ।
.git
यदि आप पहले से ही रूट डायरेक्टरी में हैं , तो यह कमांड एक सापेक्ष रास्ता देता है । (कम से कम, यह msysgit पर करता है।)
यहां एक सरल उत्तर लिखने के लिए, ताकि हम उपयोग कर सकें
git root
काम करने के लिए, बस अपने git का उपयोग करके कॉन्फ़िगर करें
git config --global alias.root "rev-parse --show-toplevel"
और फिर आप निम्नलिखित को अपने साथ जोड़ना चाहेंगे ~/.bashrc
:
alias cdroot='cd $(git root)'
ताकि आप cdroot
अपने रेपो के शीर्ष पर जाने के लिए उपयोग कर सकें ।
यदि आप पहले से ही शीर्ष-स्तर पर हैं या एक गिट रिपॉजिटरी में नहीं cd $(git rev-parse --show-cdup)
हैं तो आपको घर ले जाएगा (बस सीडी)। cd ./$(git rev-parse --show-cdup)
इसे ठीक करने का एक तरीका है।
cd "$(git rev-parse --show-cdup)"
:। यह काम करता है क्योंकि cd ""
आपको वापस लेने के बजाय कहीं नहीं ले जाता है $HOME
। और वैसे भी $ () इनवोकेशन को उद्धृत करना सबसे अच्छा अभ्यास है, अगर वे रिक्त स्थान के साथ कुछ आउटपुट करते हैं (ऐसा नहीं है कि यह कमांड इस मामले में होगा, हालांकि)।
$PWD
। इस उदाहरण के $PWD
बजाय git की जड़ को हल करेगा realpath $PWD
।
वर्तमान गिट रूट निर्देशिका के निरपेक्ष पथ की गणना करने के लिए, शेल स्क्रिप्ट में उपयोग के लिए कहें, रीडलिंक और गिट रेव-पार्स के इस संयोजन का उपयोग करें:
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
अपने वर्तमान पेड़ की जड़ पाने के लिए दौड़ने में सक्षम होंगे । ध्यान दें कि शेल स्क्रिप्ट में, "-ई" का उपयोग करके शेल से बाहर निकलने का कारण बन सकता है यदि रेव-पार्स विफल हो जाता है ताकि आप सही तरीके से निकास की स्थिति और त्रुटि संदेश प्राप्त कर सकें यदि आप गिट डायरेक्टरी में नहीं हैं।
"$(git rev-parse ...)"
हैक की तरह उपयोग करें ./$(git rev-parse ...)
।
जैसा कि दूसरों ने नोट किया है, समाधान का मूल उपयोग करना है git rev-parse --show-cdup
। हालाँकि, पता करने के लिए कुछ किनारे मामले हैं:
जब cwd पहले से ही काम करने वाले पेड़ की जड़ है, तो कमांड एक खाली स्ट्रिंग देता है।
दरअसल यह एक खाली लाइन का निर्माण करता है, लेकिन पीछे की लाइन को तोड़ने के लिए कमांड प्रतिस्थापन पट्टी को तोड़ देता है। अंतिम परिणाम एक खाली स्ट्रिंग है।
अधिकांश उत्तर आउटपुट को पूर्व-निर्धारित करने का सुझाव देते हैं, ./
ताकि "./"
इसे खिलाए जाने से पहले एक खाली आउटपुट बन जाए cd
।
जब GIT_WORK_TREE को किसी ऐसे स्थान पर सेट किया जाता है जो cwd का जनक नहीं है, तो आउटपुट निरपेक्ष नामनाम हो सकता है।
./
इस स्थिति में Prepending गलत है। यदि ./
कोई निरपेक्ष मार्ग से जुड़ा हुआ है, तो यह एक सापेक्ष पथ बन जाता है (और वे केवल उसी स्थान को संदर्भित करते हैं यदि cwd सिस्टम का रूट डायरेक्टरी है)।
आउटपुट में व्हॉट्सएप हो सकता है।
यह वास्तव में केवल दूसरे मामले में लागू होता है, लेकिन इसका एक आसान निर्धारण है: कमांड प्रतिस्थापन (और मूल्य के किसी भी बाद के उपयोग) के आसपास दोहरे उद्धरण चिह्नों का उपयोग करें।
जैसा कि अन्य उत्तरों ने उल्लेख किया है, हम कर सकते हैं 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 root
' का उपयोग क्यों नहीं करते हैं जो आपके ऊपर दिए गए उत्तर का उपयोग करता है?
बस अगर आप इस रास्ते को 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)
लघु समाधान जो सबमॉड्यूल के साथ, हुक में और .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
)
(root=$(git rev-parse --git-dir)/ && cd ${root%%/.git/*} && git rev-parse && pwd)
लेकिन यह बाहरी $GIT_DIR
एस को कवर नहीं करता है जो कि अन्य के नाम पर रखा गया है.git
यदि आप ऐसा करने के लिए एक अच्छे उपनाम की तलाश कर रहे हैं, cd
तो यदि आप एक गीदड़ में नहीं हैं, तो इसे न उड़ाएं:
alias ..g='git rev-parse && cd "$(git rev-parse --show-cdup)"'
git-extras
जोड़ता $ git root
देख https://github.com/tj/git-extras/blob/master/Commands.md#git-root
$ pwd
.../very-deep-from-root-directory
$ cd `git root`
$ git add . && git commit
$ brew install git-extras
$ apt-get install git-extras
यह शेल उर्फ काम करता है चाहे आप एक गिट सबडिर में हों, या शीर्ष स्तर पर:
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)'
alias git-root='cd \`git rev-parse --git-dir\`; cd ..'
बाकी सब कुछ कुछ बिंदु पर विफल रहता है या तो होम डायरेक्टरी में जा रहा है या बस बुरी तरह से विफल हो रहा है। यह GIT_DIR पर वापस जाने का सबसे तेज़ और सबसे छोटा तरीका है।
$GIT_DIR
वर्कट्री का उपयोग करके अलग किया जाता है .git
-फाइल्स और gitdir: SOMEPATH
। नतीजतन यह सबमॉड्यूल्स के लिए विफल रहता है, भी, जहां $GIT_DIR
शामिल है .git/modules/SUBMODULEPATH
।
यहां एक स्क्रिप्ट है जो मैंने लिखा है कि दोनों मामलों को संभालती है: 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
)
उम्मीद है कि यह उपयोगी है।
git exec
विचार गैर-नशीले पदार्थों के भंडार में अधिक सहायक है। हालांकि, मेरे जवाब में यह स्क्रिप्ट नंगे बनाम गैर-नंगे मामले को सही ढंग से संभालती है, जो किसी के लिए उपयोगी हो सकती है, इसलिए मैं इस उत्तर को यहां छोड़ रहा हूं।
git submodule
एस के भीतर विफल रहता है जहां $GIT_DIR
कुछ ऐसा होता है /.git/modules/SUBMODULE
। इसके अलावा, आप मानते हैं कि .git
निर्देशिका गैर-नंगे मामले में कार्यस्थल का हिस्सा है।
$ git config alias.root '!pwd'
# then you have:
$ git root
[alias] findroot = "!f () { [[ -d ".git" ]] && echo "Found git in [
pwd ]" && exit 0; cd .. && echo "IN
pwd" && f;}; f"
git config --global alias.root '!pwd'
काम करता है। मैं ऐसे किसी भी मामले में हाजिर नहीं हो पा रहा था जहाँ यह गैर-वैश्विक संस्करण के लिए अलग तरह से काम करता हो। (यूनिक्स, जीआईटी 1.7.10.4) बीटीडब्ल्यू: आपकी findroot
आवश्यकता एक /.git
अंतहीन पुनरावृत्ति से बचने के लिए है।
2.13.0 Git के बाद से , यह रूट प्रोजेक्ट का रास्ता दिखाने के लिए एक नए विकल्प का समर्थन करता है, जो सबमॉड्यूल के अंदर से उपयोग किए जाने पर भी काम करता है:
git rev-parse --show-superproject-working-tree
यदि आप एक शेल फ्रेमवर्क का उपयोग करते हैं, तो पहले से ही शेल उपनाम उपलब्ध हो सकता है:
$ grt
में ओह-मेरी-zsh (68k) ( cd $(git rev-parse --show-toplevel || echo ".")
)$ git-root
में prezto (8.8k) (प्रदर्शित करता है काम कर पेड़ जड़ के लिए पथ)$ g..
zimfw (1k) (वर्किंग ट्री के शीर्ष स्तर पर वर्तमान निर्देशिका को बदलता है।)मैं डेनियल ब्रॉकमैन की उत्कृष्ट टिप्पणी पर विस्तार करना चाहता था।
परिभाषित 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
यदि किसी को git
निष्पादन योग्य आवश्यकता के बिना, ऐसा करने के लिए POSIX आज्ञाकारी तरीके की आवश्यकता होती है :
#$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)
}
if
स्टेटमेंट में यह जाँचना था कि क्या आपने निर्देशिका बदल दी है। यदि यह उसी निर्देशिका में रहता है, तो यह मानता है कि आप कहीं अटक गए हैं (जैसे /
), और ब्रेक पुनरावर्तन। बग तय हो गया है, और अब उम्मीद के मुताबिक काम करना चाहिए। इस पर ध्यान दिलाने के लिए धन्यवाद।
आज खुद ही इसका हल निकालना था। इसे 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;
}