गिट क्लोन के बाद स्वचालित रूप से सीडी कैसे करें?


37

मैं कुछ करने के बाद कमांड cdद्वारा बनाई गई निर्देशिका के लिए स्वचालित रूप से करना चाहता cloneहूं git clone

महत्वपूर्ण: मैं कमांड के लिए सिंटैक्स को बदलना नहीं चाहता (जैसे कि एक उपनाम / फ़ंक्शन का उपयोग करें) क्योंकि यह Pretzoप्रोजेक्ट से स्वचालित रूप से प्राप्त होने वाले zsh- पूर्णता को तोड़ देगा ।

संपादित करें : मैंने किसी भी उत्तर को सही मानने का कारण नहीं बताया, क्योंकि कोई भी उत्तर ऐसा नहीं दिया गया था जो ऊपर दी गई शर्त का अनुपालन करता हो।

मैं ZSH का उपयोग करता हूं, लेकिन किसी अन्य शेल में एक उत्तर भी स्वीकार्य है।


मुझे उत्तर unix.stackexchange.com/questions/97920/… पसंद है, लेकिन इसे ~/.bashrcफ़ाइल पर उस फ़ंक्शन को लिखने के लिए उल्लेख करना होगा (उदाहरण के लिए) और मेरे लिए कम से कम यह काम नहीं किया, मुझे इसे बदलने के साथ ठीक करने की आवश्यकता है पंक्ति:/usr/bin/git "$@" 2>&1 | tee $tmp
लँतारी

जवाबों:


19

एक समारोह बनाएँ:

gclonecd() {
  git clone "$1" && cd "$(basename "$1" .git)"
}

(".गित" के साथ और बिना लिंक के काम करता है)


2
git cloneअगर मैं उपयोग नहीं कर रहा हूं तो मुझे उन सभी साधनों का उपयोग करना होगा जिन्हें मुझे बदलना होगा gitहब को गिट के रूप में अलियास किया गया है, ओह-माय-ज़श ऑटो-पूर्णता प्रदान करता है, आदि ...
डैनियल के।

3
@Wildeyes gitआपके शेल की कार्यशील निर्देशिका को बदल नहीं सकता है, इसलिए किसी भी तरह से आपको इसे अन्य उपनाम / फ़ंक्शन में लपेटना होगा जो आपको चाहिए और इसे बिलिन के साथ अनुसरण करता है cd। यदि आप hubइसके बजाय कॉल करना चाहते हैं git, तो फ़ंक्शन में ऐसा करें। यदि आप चाहते हैं कि यह केवल cloneकमांड को प्रभावित करे , तो फ़ंक्शन में कार्रवाई के लिए जांचें। आदि
फ्रॉस्ट्सचुट्ज़

मैंने देखा है कि basename git@github.com:pckujawa/pattern-rec.gitपैटर्न-रिजल्ट में परिणाम होता है। क्या आप क्लोन करते समय सिर्फ .गित एक्सटेंशन को छोड़ देते हैं?
पाट

8
@Pat basenameएक प्रत्यय तर्क भी लेता है, इसलिए आप ऐसा कर सकते हैं:git clone $1 && cd $(basename $1 .git)
हेनरिक एन

17

git cloneएक अतिरिक्त तर्क लेता है: निर्देशिका का उपयोग करने के लिए। आप इसे git clone URL . तब के साथ वर्तमान कार्य निर्देशिका में क्लोन कर सकते हैं , कार्यशील निर्देशिका को बदलने की कोई आवश्यकता नहीं है; आप पहले से ही वहां हैं।

यदि आप वास्तव में gitकमांड को वास्तव में वर्किंग डायरेक्टरी में बदलना चाहते हैं , तो आप इसे एक फंक्शन में बदल सकते हैं, जो gitआवश्यक होने पर वास्तविक कॉल करता है:

git()
{
   local tmp=$(mktemp)
   local repo_name

   if [ "$1" = clone ] ; then
     /usr/bin/git "$@" | tee $tmp
     repo_name=$(awk -F\' '/Cloning into/ {print $2}' $tmp)
     rm $tmp
     printf "changing to directory %s\n" "$repo_name"
     cd "$repo_name"
   else
     /usr/bin/git "$@"
   fi
}

मुझे इसी की तो तलाश थी। मुझे एहसास हुआ कि कोई आंतरिक हुक या ऐसा कुछ नहीं है, मैंने लगभग एक सटीक कार्य लिखा :) :)
डैनियल के।

2
@Wildeyes हाँ: एक /tmpवॉल्यूम है जो RAM में है, जैसे कोई भी आधुनिक लिनक्स tmpfs के माध्यम से करता है। वैसे भी, आप डिस्क पर लिखने के बारे में क्यों परवाह करेंगे, जब आपने अभी-अभी गिट क्लोन किया है, जो निर्देशिका बनाता है और डिस्क पर शायद सैकड़ों फाइलें लिखता है ...
कज़िन

1
आप शायद पूरे "एनवीएम के बारे में सही हैं अगर यह डिस्क पर लिखता है" बात, मैं बस अतिरिक्त संचालन को बचाने के लिए देख रहा था। बहुत बहुत धन्यवाद कज़।
डेनियल के।

3
सावधान रहे। यह है git [flags] command [arguments], इसलिए आँख बंद करके cloneनिश्चित स्थिति में मांगना विफल हो जाएगा।
वॉनब्रांड

1
"वास्तविक" पथ जोड़ने में मदद करेगा? जैसे: git_real_home = which git git () {... $ git_real_home "$ @" | टी $
टैम्प

7

यदि आप रेपो का स्थानीय नाम प्रदान करते हैं, तो $ _ का उपयोग करना वास्तव में आसान है :

git clone git@github.com:npm/npm.git npm-local-dir && cd $_

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

git clone git@github.com:pckujawa/pattern-rec.git && 
cd `echo $_ | sed -n -e 's/^.*\/\([^.]*\)\(.git\)*/\1/p'`

संपादित करें: ठीक है, मैं मनव (नीचे टिप्पणी) को धन्यवाद देने जा रहा था

git clone foo/bar && cd !$:t

लेकिन यह zsh में काम नहीं करता है (कुछ के बारे में zsh विस्तार कैसे करता है, यह इनपुट के रूप में पहले कमांड का इलाज नहीं करने का कारण बनता है !$)। मुझे यह देखना था कि क्या !$:tकिया ( बैश शैल में अग्रिम | $ {me: -whatever} )। !$पिछली कमांड के अंतिम भाग को पकड़ लेता है और :t"पूंछ छोड़कर सभी अग्रणी फ़ाइल नाम घटकों को हटा देगा।" अच्छी जानकारी, लेकिन मेरी इच्छा है कि मैं इसे zsh के साथ काम करने के लिए प्राप्त कर सकूं (मैंने noglobकोई सफलता नहीं मिलने की कोशिश की )।

EDIT: उपयोग करने के बजाय ( sedया !$:tजो मेरे लिए काम नहीं करता है, वैसे भी), मुझे दो अन्य विकल्प (एक आदत https://unix.stackexchange.com/users/5685/frederik-deweerdtt ) https के साथ उत्तर मिला। : //unix.stackexchange.com/users/129926/henrik-n की टिप्पणी):

git clone git@github.com:npm/npm.git && cd $(basename $_ .git)

या

git clone git@github.com:npm/npm.git && cd ${${_%%.git*}##*/}

git clone foo/bar && cd !$:t
मानव

यदि आप में आपका रेपो url समाप्त हो जाता है, .gitतो आप !$:t:rफ़ोल्डर का नाम प्राप्त करने के लिए उपयोग कर सकते हैं ।
माइकल स्ट्रैमेल

2

किसी भी POSIX शेल के लिए एक सरल समाधान निर्देशिका को स्पष्ट रूप से क्लोन करने के लिए निर्दिष्ट करना है (किसी भी फाइल सिस्टम पथ) और इसका पुन: उपयोग करें:

git clone <repository> <directory> &&
cd "$_"

तथा

cd -

जब आपका हो जाए।


2

आप कुछ ऐसा कर सकते हैं:

clone_check() {
  (($? != 0)) && return
  local cmd=$history[$((HISTCMD-1))]
  cmd=("${(@Q)${(z)cmd}}")
  if [[ $cmd = "git clone "* ]]; then
    local dir
    if (($#cmd == 3)); then
      dir=${cmd[3]:t}
      dir=${dir%.git}
      dir=${dir#*:}
    elif (($#cmd > 3)); then
      dir=$cmd[-1]
    else
      return
    fi
    print -r CDing into $dir > /dev/tty
    cd -- $dir
  fi
}
precmd_functions+=(clone_check)

यह काफी सरल है। यह एक precmdहुक है (प्रत्येक प्रॉम्प्ट से पहले निष्पादित), यह जांचता है कि अंतिम कमांड लाइन कैसी दिखती है git clone .../somethingया git clone .../something dir, उस से निर्देशिका का अनुमान लगाएं और इसमें सीडी।

यदि आपके द्वारा दर्ज यह काम नहीं करता है git clone foo; whateverया whatever; git clone fooया git clone --option repo...


+1 कोड के लिए आपका बहुत-बहुत धन्यवाद; मैं कुछ दिनों से इसका उपयोग कर रहा हूं। मैंने सिर्फ एक मुद्दे पर ध्यान दिया है; यदि आप किसी प्रोजेक्ट को क्लोन करने के बाद टर्मिनल को बंद करते हैं, तो अगली बार जब आप टर्मिनल खोलते हैं, तो zsh दो त्रुटि संदेशों के साथ शिकायत करता है: CDing into <project>और clone_check:cd:17: no such file or directory: <project>। टर्मिनल को बंद करने से पहले आपके द्वारा चलाए गए अंतिम कमांड जैसे ही त्रुटि गायब हो जाती है $ git clone
user938271

2

यहाँ के लिए उपरोक्त उत्तर का एक अनुकूलन है OSX

  • mktemp अतिरिक्त पैरामीटर की आवश्यकता है
  • git cloneकरने के लिए लिखते हैं STDERRडिफ़ॉल्ट रूप से (देखें इस )

समारोह:

function git {
   local tmp=$(mktemp -t git)
   local repo_name

   if [ "$1" = clone ] ; then
     command git "$@" --progress 2>&1 | tee $tmp
     repo_name=$(awk -F\' '/Cloning into/ {print $2}' $tmp)
     rm $tmp
     printf "changing to directory %s\n" "$repo_name"
     cd "$repo_name"
   else
     command git "$@"
   fi
}

1
7 उत्तर हैं जो आपके "ऊपर" प्रदर्शित करते हैं। लेकिन समय के साथ इसमें बदलाव हो सकता है। इस तरह के संदर्भ एसई पर कोई मतलब नहीं रखते हैं, कृपया अपना उत्तर संपादित करें और उस उत्तर के लिए एक लिंक शामिल करें जिसका आप उल्लेख कर रहे थे।
टेकफ़र

0

मैं इसकी अनुशंसा नहीं करूंगा, लेकिन आप इस एक-लाइनर का उपयोग कर सकते हैं:

echo 'project' | xargs -I % sh -c 'git clone https://github.com/username/%.git && cd %'


0

इसे अपने शेल में शामिल करें:

git(){
  case "$1" in clone) git-clone "${@:2}";; *) command git "$@";; esac
}
git-clone(){ 
   local tgt 
   tgt=$(command git clone "$@" 2> >(tee /dev/stderr |head -n1 | cut -d \' -f2)) ||
      return $?
   cd "$tgt"
}

यह git की मानक त्रुटि से क्लोनिंग लक्ष्य को सरसरी तौर पर चमकाने का काम करता है और cd'यदि (और केवल यदि) तो क्लोनिंग एक सफलता थी।

यह सभी तर्कों और विकल्पों को स्वीकार करता है जो नियमित git cloneकरता है।

या तो आप git आवरण का उपयोग कर सकते हैं और अपने पूर्णताओं के बारे में चिंता करने की ज़रूरत नहीं है, या आप git आवरण से छुटकारा पा सकते हैं और अपनी git cloneपूर्णताओं को पुनः प्राप्त कर सकते हैं git-clone

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