क्या मेरी सभी स्थानीय शाखाओं को "git pull --all" अपडेट कर सकते हैं?


473

मेरे पास अक्सर कम से कम 3 दूरस्थ शाखाएं हैं: मास्टर, मंचन और उत्पादन। मेरी 3 स्थानीय शाखाएँ हैं जो उन दूरस्थ शाखाओं को ट्रैक करती हैं।

मेरी सभी स्थानीय शाखाओं को अपडेट करना थकाऊ है:

git fetch --all
git rebase origin/master
git checkout staging
git rebase origin/staging
git checkout production
git rebase origin/production

मैं सिर्फ एक "पुल-पुल" करने में सक्षम होना पसंद करूंगा, लेकिन मैं इसे काम करने में सक्षम नहीं हूं। ऐसा लगता है कि एक "भ्रूण - लंबा" है, तो वर्तमान कार्य शाखा को अपडेट (तेजी से आगे या विलय) करता है, लेकिन अन्य स्थानीय शाखाएं नहीं।

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


8
क्या आप केवल फास्ट-फॉरवर्ड मामले में स्थानीय ट्रैकिंग शाखाओं का स्वचालित अपडेट चाहते हैं? Ypu चाहिए, becaue मर्ज का सामना करना पड़ सकता है जिसे आपको सुलझाना होगा ...
Jakub Narębski

34
परामर्श के समय में एक रूढ़िवादी $ 300 को इसके साथ गड़बड़ करने के लिए मानते हुए, इस एकल मुद्दे पर 77,476 की व्यू काउंट का उपयोग करके कंपनियों की लागत 23,242,800 डॉलर है। अब इस प्रश्न पर विचार करें stackoverflow.com/questions/179123/… और अन्य सभी। वाह।
ल्यूक पुप्लेट

16
@ ल्यूक आप पहले व्यक्ति हैं जिन्होंने मुझे सुना है कि कैसे समय बिताने की कोशिश कर रहा है जो हम चाहते हैं कि कंपनियों को पैसा चाहिए। ये सरल चीजें स्वचालित होनी चाहिए और इतनी सरल होनी चाहिए कि मुझे मंचों, आईएमओ को पढ़ने के लिए एक ब्राउज़र नहीं खोलना पड़े।
शमूएल

13
@LukePuplett मर्क्यूरियल की तुलना में SO पर git के लगभग ~ 9 गुना अधिक सवाल हैं, और पूर्व के बहुमत से प्रतीत होता है कि "मैं git में <सरल ऑपरेशन कैसे करूं?"। यह इंगित करता है कि गिट या तो बुरी तरह से डिज़ाइन किया गया है, खराब रूप से प्रलेखित है, unintuitive, या तीनों।
इयान केम्प

26
@IanKemp मुझे यकीन नहीं है कि एसओ की जनसांख्यिकी को जाने बिना उस दावे को करना सुरक्षित है। यदि Mercurial आमतौर पर यहां उपयोग नहीं किया जाता है, या यदि इसके उपयोगकर्ता इसके बारे में पूछने के लिए अन्य मंचों का उपयोग करते हैं, तो मैं उसी परिणाम को देखने की उम्मीद करूंगा। :) असेंबली की तुलना में जावास्क्रिप्ट पर ~ 51 गुना अधिक प्रश्न हैं - इसलिए इस प्रकार के मेट्रिक्स द्वारा टूल को जज करना हमेशा सही नहीं हो सकता है।
डैनशूमवे

जवाबों:


188

आपके द्वारा वर्णित व्यवहार pull --allवैसा ही है जैसा अपेक्षित है, हालांकि जरूरी नहीं कि उपयोगी हो। विकल्प को भ्रूण लाने के लिए पारित किया जाता है, जो तब सभी रीमोट से सभी रीफ प्राप्त करता है, बजाय केवल एक की जरूरत के; pullतब विलय (या आपके मामले में, विद्रोह) उपयुक्त एकल शाखा।

यदि आप अन्य शाखाओं की जाँच करना चाहते हैं, तो आपको उनकी जाँच करनी होगी। और हां, विलय (और रिबासिंग) के लिए पूरी तरह से एक काम के पेड़ की आवश्यकता होती है, इसलिए उन्हें अन्य शाखाओं की जांच के बिना नहीं किया जा सकता है। यदि आप चाहें, तो आप अपने वर्णित चरणों को एक स्क्रिप्ट / उपनाम में लपेट सकते हैं, हालांकि मैं कमांड के साथ जुड़ने का सुझाव &&दूंगा ताकि उनमें से एक विफल हो जाए, यह हल करने की कोशिश नहीं करेगा।


2
यदि आप एक उदाहरण कमांड लाइन देते हैं, तो मैं मतदान करूंगा। मुझे जीथब पर यह समस्या है। मैंने UI पर एक शाखा बनाई। अब मुझे शाखा दिखाने के लिए अपने स्थानीय की आवश्यकता है। गिट पुल --all; git ब्रांच ... argh ... कमांड: git ब्रांच -a
मारीओटी

@mariotti निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं, और यह आपकी टिप्पणी से वास्तव में स्पष्ट नहीं है। आप एक नया प्रश्न पूछ सकते हैं।
कास्केबेल

1
या @ जेफ्रोमी .. एक उदाहरण दें। मैं वास्तव में आपसे सहमत था।
मारीओटी

3
@ मारीओटी इस उत्तर की बात यह है कि अंतर्निहित कमांड वास्तव में ओपी के लिए क्या नहीं करते हैं, इसलिए उनके पास चरणों का अनुक्रम आवश्यक है। उन चरणों को स्वचालित करना संभव है (उदाहरण के लिए जॉन के उत्तर देखें) लेकिन उन्हें करना होगा। इसलिए यदि आप जो करने की कोशिश कर रहे हैं, वह बिल्कुल ओपी के समान है, तो वास्तव में देने के लिए एक उदाहरण नहीं है, और यदि आप कुछ अलग करने की कोशिश कर रहे हैं, तो आपको एक नया प्रश्न पूछना चाहिए - यह है कि स्टैकऑवरफ्लो कैसे काम करता है! (और आपकी टिप्पणी अस्पष्ट है, लेकिन मेरा सबसे अच्छा अनुमान है कि आप यहाँ ओपी से कुछ अलग चाहते हैं, इसलिए हाँ, नया प्रश्न।)
कास्केबेल

हां, कुछ अलग। लेकिन आपका जवाब सिर्फ संदर्भ के लिए एकदम सही था। और मुझे आपके उत्तर के कारण अब और पूछने की आवश्यकता नहीं है। बस: स्वीकृत उत्तर git-up का उपयोग करता है, जो कि कमांड लाइन को git करने के लिए एक इंटरफ़ेस है (मुझे लगता है)। मैं उम्मीद कर रहा था कि आप इसे git कमांड की कुछ लाइनों में स्पष्ट कर सकते हैं। वर्तमान उत्तर git नहीं है।
मरियोटी

206

मैं इसे स्वचालित करने के लिए हब के syncउपकमांड का उपयोग करता हूं । मेरे पास है , इसलिए मैं जो कमांड टाइप करता हूं वह है:alias git=hub.bash_profile

git sync

यह उन सभी स्थानीय शाखाओं को अपडेट करता है जिनकी मिलान अपस्ट्रीम शाखा है। आदमी पृष्ठ से:

  • यदि स्थानीय शाखा पुरानी है, तो इसे तेज़ी से अग्रेषित करें;
  • यदि स्थानीय शाखा में अप्रकाशित कार्य होता है, तो इसके बारे में चेतावनी दें;
  • यदि शाखा विलीन हो गई है और इसकी अपस्ट्रीम शाखा हटा दी गई है, तो इसे हटा दें।

यह वर्तमान शाखा पर अनचाहे बदलावों को रोकने / अस्थिर करने का काम भी करता है।

मैं एक समान टूल का उपयोग करता था जिसे git-up कहा जाता है , लेकिन अब इसे बनाए नहीं रखा जाता है, और git syncलगभग एक ही चीज़ करता है।


14
विंडोज के बारे में क्या?
वायलेट जिराफ

6
@ TrentonD.Adams की तारीखें और लेखक की तारीखें अलग-अलग अवधारणाएं हैं। एक रिबेस कमिट डेट बदल देगा लेकिन ऑथर डेट नहीं (सिवाय संघर्षों के, जहां ऑथर डेट भी बदल जाती है)। लेखक की तारीख यह दर्शाती है कि जब प्रतिबद्ध पेड़ लेखक थे और एक अप्रकाशित विद्रोह के दौरान नहीं बदलना चाहिए। कमिट डेट बदल जाती है क्योंकि रिबेट हमेशा एक नई प्रतिबद्धता बनाता है। इसलिए प्रतिबद्ध तारीखें हमेशा सही क्रम में होंगी।
देव

16
गिट-अप के स्वत: रिबासिंग व्यवहार को बंद करने के लिए, दौड़ें git config --global git-up.rebase.auto false
डैन लोवेनहेर्ज़

17
@MaxYankov साझा इतिहास को आम तौर पर टाला जाना चाहिए, एक खींचतान के दौरान स्थानीय कमानों को पुन: पेश करने में कुछ भी गलत नहीं है।
देव

23
स्थानीय कमिट्स को रीबास करना इतिहास को फिर से लिखना है और इसे वास्तव में जितना आसान है उससे अधिक सरल बना दिया है। रिबेस के साथ, आप अपने आप को कोड के साथ पा सकते हैं जो स्वचालित रूप से विलय हो जाता है लेकिन संकलन नहीं करता है, या बदतर नहीं है, संकलन करता है लेकिन काम नहीं करता है। विलय करना आपके काम करने के तरीके को स्वीकार करता है: आपने परिवर्तनों को लागू किया और अन्य लोगों के बदलावों को शामिल करने से पहले उनका परीक्षण किया और मर्ज कमिट एक बहुत ही उपयोगी बिंदु है: यह वह जगह है जहाँ आप यह सुनिश्चित करते हैं कि विभिन्न चैज़ेट्स एक साथ अच्छी तरह से खेलते हैं। रीबेसिंग ऐसा लगता है कि यह प्रक्रिया कभी घटित नहीं होती है, जो कि वास्तव में सही नहीं है और एक बहुत ही खतरनाक अभ्यास है।
मैक्स यांकोव

39

मुझे पता है कि यह सवाल लगभग 3 साल पुराना है, लेकिन मैंने खुद से एक ही सवाल पूछा और कोई भी तैयार समाधान नहीं मिला। इसलिए, मैंने एक कस्टम git कमांड शेल स्क्रिप्ट तैयार की है।

यहाँ यह जाता है, git-ffwd-updateस्क्रिप्ट निम्नलिखित करता है ...

  1. यह git remote updateलेट रिवीज लाने के लिए ए जारी करता है
  2. फिर git remote showएक दूरस्थ शाखा को ट्रैक करने वाली स्थानीय शाखाओं की सूची प्राप्त करने के लिए उपयोग करता है (जैसे शाखाएँ जिनका उपयोग किया जा सकता है git pull)
  3. तब यह जाँच करता है git rev-list --count <REMOTE_BRANCH>..<LOCAL_BRANCH>कि रिमोट के पीछे स्थानीय शाखा कितनी प्रतिबद्ध है (और इसके विपरीत)
  4. यदि स्थानीय शाखा 1 या अधिक है, तो यह तेजी से अग्रेषित नहीं किया जा सकता है और इसे हाथ से मर्ज या रिबाउंड करने की आवश्यकता है
  5. यदि स्थानीय शाखा 0 से आगे है और 1 या उससे अधिक पीछे है, तो इसे तेजी से आगे बढ़ाया जा सकता है git branch -f <LOCAL_BRANCH> -t <REMOTE_BRANCH>

स्क्रिप्ट को इस तरह कहा जा सकता है:

$ git ffwd-update
Fetching origin
 branch bigcouch was 10 commit(s) behind of origin/bigcouch. resetting local branch to remote
 branch develop was 3 commit(s) behind of origin/develop. resetting local branch to remote
 branch master is 6 commit(s) behind and 1 commit(s) ahead of origin/master. could not be fast-forwarded

पूर्ण स्क्रिप्ट, के रूप में सहेजा जाना चाहिए git-ffwd-updateऔर पर होना चाहिए PATH

#!/bin/bash

main() {
  REMOTES="$@";
  if [ -z "$REMOTES" ]; then
    REMOTES=$(git remote);
  fi
  REMOTES=$(echo "$REMOTES" | xargs -n1 echo)
  CLB=$(git rev-parse --abbrev-ref HEAD);
  echo "$REMOTES" | while read REMOTE; do
    git remote update $REMOTE
    git remote show $REMOTE -n \
    | awk '/merges with remote/{print $5" "$1}' \
    | while read RB LB; do
      ARB="refs/remotes/$REMOTE/$RB";
      ALB="refs/heads/$LB";
      NBEHIND=$(( $(git rev-list --count $ALB..$ARB 2>/dev/null) +0));
      NAHEAD=$(( $(git rev-list --count $ARB..$ALB 2>/dev/null) +0));
      if [ "$NBEHIND" -gt 0 ]; then
        if [ "$NAHEAD" -gt 0 ]; then
          echo " branch $LB is $NBEHIND commit(s) behind and $NAHEAD commit(s) ahead of $REMOTE/$RB. could not be fast-forwarded";
        elif [ "$LB" = "$CLB" ]; then
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. fast-forward merge";
          git merge -q $ARB;
        else
          echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. resetting local branch to remote";
          git branch -f $LB -t $ARB >/dev/null;
        fi
      fi
    done
  done
}

main $@

1
इस स्क्रिप्ट के लिए धन्यवाद। क्या यह संभव है कि कोई उस स्क्रिप्ट को विंडोज़ बैच में बदल सके?
सारिको

@Sariko आप एक सामान्य विंडोज़ शेल पर गिट का उपयोग क्यों नहीं करेंगे? यदि आप
साइबरविन

@RyanWilcox धन्यवाद, मैं इसे हर (काम-) दिन की तरह उपयोग कर रहा हूं ... ;-) आप अधिक git से संबंधित स्क्रिप्ट और उपनामों के लिए मेरी डॉट-फाइल्स पर एक नज़र डालना चाहते हैं: github.com/muhqu/dotfiles
muhqu

@ muhqu मैं आपकी स्क्रिप्ट का उपयोग करने की कोशिश कर रहा हूं और मुझे नहीं पता कि इसने पहली बार काम क्यों किया, लेकिन यह अभी "अपेक्षित" काम नहीं कर रहा है। उदाहरण के लिए, इस पर एक नज़र डालें । आपकी स्क्रिप्ट चलाने के बाद भी मास्टर comm२ पीछे क्यों है?
बीपीएल

1
@ muhqu नए git संस्करणों में, -t और -l को एक git branchकॉल के भीतर एक साथ उपयोग नहीं किया जाना चाहिए । मैंने कॉल को बदलने के लिए -l हटा दिया git branch -f $LB -t $ARB >/dev/null;और अब स्क्रिप्ट वैसी ही काम करती है जैसी उसे करनी चाहिए।
राडेक लिस्का

24

इसे स्वचालित करना इतना कठिन नहीं है:

#!/bin/sh
# Usage: fetchall.sh branch ...

set -x
git fetch --all
for branch in "$@"; do
    git checkout "$branch"      || exit 1
    git rebase "origin/$branch" || exit 1
done

4
लिपियों में उपनामों का उपयोग नहीं करना शायद सबसे अच्छा है। यह भी वास्तव में कुछ भी प्राप्त नहीं करता है, बस पहले से ही प्राप्त सामग्री पर विद्रोह करता है। आप बदलना चाहिए git rebase origin/$branchकरने के लिए git pull, इतना है कि यह उचित ट्रैकिंग शाखा (संभवतः मूल पर) से लायेगा और या तो मर्ज या रिबेस config द्वारा निर्धारित किया जाता है।
Cascabel

@ जेफ्रोमी: मैं भूल गया था fetch। संपादित किया है; अतिरिक्त सुविधाएँ / सुधार जो कुछ भी ओपी तक हैं।
फ्रेड फू

8
मुझे अभी भी लगता है कि आप pull(या जांच branch.<branch>.rebase) का उपयोग कर सकते हैं , ताकि आप गलती से एक शाखा को पुन: स्थापित न करें जो सामान्य रूप से खींचने के लिए स्थापित है (मर्ज)।
कैसबेल 22

1
पहली त्रुटि पर दुभाषिया से बाहर निकलने के set -eबजाय उपयोग करने पर विचार करें || exit 1
क्रिशोज

18

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

git fetch origin
git update-ref refs/heads/other-branch origin/other-branch

अपनी स्थानीय शाखा की स्थिति को अपडेट किए बिना उसे अपडेट करने के लिए।

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


1
यह ठीक वही उपाय है जिसकी मुझे तलाश थी। मैं आमतौर पर कई शाखाओं पर परिवर्तन नहीं करता, और बस रिमोट से मिलान करने के लिए अपनी विभिन्न स्थानीय शाखाओं को अपडेट करना चाहता हूं। यह समाधान मेरे सामान्य डिलीट / री-चेकआउट विधि की तुलना में बहुत अच्छा है!
डेव नाइट

1
एक कमांड में संयुक्त:git fetch origin other-branch:other-branch
फेब

12

यहां बहुत सारे उत्तर हैं, लेकिन कोई भी ऐसा नहीं है git-fetchजो सीधे स्थानीय रेफरी को अपडेट करने के लिए उपयोग करता है, जो कि शाखाओं की जांच करने की तुलना में बहुत आसान है, और इससे अधिक सुरक्षित है git-update-ref

यहां हम git-fetchगैर-वर्तमान शाखाओं और git pull --ff-onlyवर्तमान शाखा के लिए अपडेट करने के लिए उपयोग करते हैं । यह:

  • शाखाओं की जाँच की आवश्यकता नहीं है
  • शाखाओं को केवल तभी अपडेट किया जाता है जब वे तेजी से अग्रेषित की जा सकें
  • रिपोर्ट करेगा जब यह तेजी से आगे नहीं बढ़ सकता

और यहाँ यह है:

#!/bin/bash
currentbranchref="$(git symbolic-ref HEAD 2>&-)"
git branch -r | grep -v ' -> ' | while read remotebranch
do
    # Split <remote>/<branch> into remote and branchref parts
    remote="${remotebranch%%/*}"
    branchref="refs/heads/${remotebranch#*/}"

    if [ "$branchref" == "$currentbranchref" ]
    then
        echo "Updating current branch $branchref from $remote..."
        git pull --ff-only
    else
        echo "Updating non-current ref $branchref from $remote..."
        git fetch "$remote" "$branchref:$branchref"
    fi
done

इसके लिए मैनपेज से git-fetch:

   <refspec>
       The format of a <refspec> parameter is an optional plus +, followed by the source ref <src>,
       followed by a colon :, followed by the destination ref <dst>.

       The remote ref that matches <src> is fetched, and if <dst> is not empty string, the local ref
       that matches it is fast-forwarded using <src>. If the optional plus + is used, the local ref is
       updated even if it does not result in a fast-forward update.

निर्दिष्ट करके git fetch <remote> <ref>:<ref>(बिना किसी के +) हमें एक भ्रूण मिलता है जो स्थानीय रेफरी को केवल तभी अपडेट करता है जब इसे तेजी से अग्रेषित किया जा सकता है।

नोट : यह मानता है कि स्थानीय और दूरस्थ शाखाओं को एक ही नाम दिया गया है (और आप सभी शाखाओं को ट्रैक करना चाहते हैं), यह वास्तव में जानकारी होनी चाहिए कि आपके पास कौन सी स्थानीय शाखाएँ हैं और उन्हें ट्रैक करने के लिए क्या सेट किया गया है।


1
"शाखाओं को केवल तभी अपडेट किया जाता है जब वे तेजी से अग्रेषित की जा सकें" - तेजी से आगे बढ़ने का क्या महत्व है? यदि मुझे अपनी सभी शाखाओं में नवीनतम स्रोत चाहिए, तो मुझे तेजी से अग्रेषण की परवाह क्यों करनी चाहिए या नहीं? इस तरह की चीजें जो मुझे गित और उसके फैनबोई पर हंसाती हैं। आप इसे केवल एक कमांड में नहीं कर सकते। इसके बजाय आपको c*nचरणों को करने की आवश्यकता है (1 के बजाय), जहां cकुछ क्रमबद्ध आदेशों nकी संख्या है और शाखाओं की संख्या है।
jww

@jww यह "Git पर हंसने में मदद नहीं करता है और इसके फैनबोइ के" [sic] जब यह VCS है जो दुनिया के अधिकांश उपयोग करता है। लेकिन मैं बताता हूं ... मुझे लगता है कि इस तरह के "ग्लोबल पुल" की पटकथा के संदर्भ में गैर-वर्तमान शाखाओं में परिवर्तन करने का प्रयास न करने के लिए विवेकपूर्ण है यदि उनके पास संघर्ष है।
विले

यह सहायक था, धन्यवाद। केवल एक चीज जो मुझे पसंद नहीं थी, वह यह थी कि हर रिमोट शाखा के लिए स्थानीय रूप से एक शाखा बनाई जाए (जिसमें मैं दिलचस्पी नहीं रखता हूं), इसलिए मैंने इसे उन शाखाओं तक सीमित git branch -r | grep -v ' -> ' | while read remotebranchकरने के git branch -r | grep -v ' -> ' | grep -f <(git branch | cut -c 3- | awk '{print "\\S*/"$0"$"}') | while read remotebranchलिए बदल दिया जो मेरे पास पहले से ही हैं। इसके अलावा मैंने git fetch --pruneकुछ भी करने से पहले दूरस्थ शाखाओं की सूची को अपडेट करने के लिए शुरुआत में जोड़ा , जो कुछ चेतावनियों से बचा जाता है।
नैट कुक

11

यह समस्या हल नहीं हुई है (अभी तक), कम से कम आसानी से / बिना स्क्रिप्टिंग के नहीं: जूनियो सी हमानो द्वारा git मेलिंग सूची पर इस पोस्ट को देखें स्थिति की व्याख्या करते हुए और एक सरल समाधान के लिए कॉल प्रदान करें।

प्रमुख तर्क यह है कि आपको इसकी आवश्यकता नहीं होनी चाहिए:

गिट के साथ जो प्राचीन नहीं है (यानी v1.5.0 या नया), स्थानीय "देव" होने का कोई कारण नहीं है जो विशुद्ध रूप से रिमोट को ट्रैक करते हैं। यदि आप केवल देखने और देखने के लिए जाना चाहते हैं, तो आप दूरस्थ ट्रैकिंग शाखा को सीधे " git checkout origin/dev" के साथ अलग किए गए एचएएडी पर देख सकते हैं ।

जिसका अर्थ है कि उपयोगकर्ताओं के लिए इसे सुविधाजनक बनाने के लिए केवल वही मामले हैं जो इन स्थानीय शाखाओं को संभालने के लिए होते हैं जो आपके पास स्थानीय परिवर्तन होने पर "ट्रैक" करते हैं, या जब आप कुछ करने की योजना बनाते हैं।

यदि आपके पास "देव" पर स्थानीय परिवर्तन हैं जो हटाने "देव" को ट्रैक करने के लिए चिह्नित है, और यदि आप "देव" से अलग एक शाखा पर हैं, तो हमें git fetch"ट्रैकिंग" देव "को अपडेट करने के बाद कुछ भी नहीं करना चाहिए " । यह वैसे भी तेजी से आगे नहीं बढ़ेगा

एक समाधान के लिए कॉल स्थानीय शाखाओं को चुभाने के लिए एक विकल्प या बाहरी स्क्रिप्ट के लिए था जो अब मूल-ट्रैकिंग अनुरोधों की तरह तेजी से अग्रेषण द्वारा अप-टू-डेट रखने के बजाय, दूरस्थ-ट्रैकिंग शाखाओं का पालन करता है।

तो कैसे " git branch --prune --remote=<upstream>" के बारे में है कि स्थानीय शाखाओं पर iterates, और अगर

(1) यह वर्तमान शाखा नहीं है; और
(2) यह <upstream> से ली गई कुछ शाखा को ट्रैक करने के लिए चिह्नित है; और
(3) इसका अपना कोई कमिट नहीं है;

फिर उस शाखा को हटा दें? " git remote --prune-local-forks <upstream>" भी ठीक है; मुझे इस बात की कोई परवाह नहीं है कि कौन सी कमांड उस फीचर को लागू करती है।

नोट: git 2.10 के रूप में ऐसा कोई समाधान मौजूद नहीं है। ध्यान दें किgit remote pruneउप-कंप्यूटर, औरgit fetch --pruneशाखा के लिए रिमोट-ट्रैकिंग शाखा को हटाने के बारे में है जो अब रिमोट पर मौजूद नहीं है, रिमोट-ट्रैकिंग शाखा (जिसके लिए रिमोट-ट्रैकिंग शाखा अपस्ट्रीम शाखा है) को ट्रैक करने वाली स्थानीय शाखा को हटाने के बारे में नहीं है।


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

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

@michael_n: विस्तारित ... हम्म, अब मैं देख रहा हूं कि पोस्ट अनुरोधित समाधान के बारे में बिल्कुल नहीं था, लेकिन यह समस्या के बारे में था (XY समस्या का मामला मानकर)।
जकुब नारबस्की

हम्म, अलग किए गए सिर के साथ झांकना आसान बनाया जाना चाहिए, विशेष रूप से इसे उपयोगी जानकारी दिखाना चाहिए। स्थिति और एलालो को कुछ प्रतिक्रिया के साथ तेजी से आगे बढ़ाने के लिए (जैसे खींचा हुआ कमिट्स)। तब यह आसानी से स्थानीय शाखाओं के लिए एक प्रतिस्थापन होगा।
Eckes

9

यहां बहुत सारे स्वीकार्य उत्तर हैं, लेकिन कुछ प्लंबिंग असिंचित के लिए थोड़े अपारदर्शी हो सकते हैं। यहाँ एक बहुत सरल उदाहरण है जिसे आसानी से अनुकूलित किया जा सकता है:

$ cat ~/bin/git/git-update-all
#!/bin/bash
# Update all local branches, checking out each branch in succession.
# Eventually returns to the original branch. Use "-n" for dry-run.
git_update_all() {
  local run br
  br=$(git name-rev --name-only HEAD 2>/dev/null)
  [ "$1" = "-n" ] && shift && run=echo

  for x in $( git branch | cut -c3- ) ; do
     $run git checkout $x && $run git pull --ff-only || return 2
  done

  [ ${#br} -gt 0 ] && $run git checkout "$br"
}

git_update_all "$@"

अगर आप जोड़ते हैं ~/bin/git अपने कोPATH (फ़ाइल मानकर ~/bin/git/git-update-all), तो आप बस चला सकते हैं:

$ git update-all

धन्यवाद! आपने मुझे बैश के साथ खेलने का एक घंटा बचाया ...
8ctopus

5

इस स्क्रिप्ट को .profileMac OS X पर जोड़ें :

# Usage:
#   `git-pull-all` to pull all your local branches from origin
#   `git-pull-all remote` to pull all your local branches from a named remote

function git-pull-all() {
    START=$(git symbolic-ref --short -q HEAD);
    for branch in $(git branch | sed 's/^.//'); do
        git checkout $branch;
        git pull ${1:-origin} $branch || break;
    done;
    git checkout $START;
};

function git-push-all() {
    git push --all ${1:-origin};
};

1
क्या यह सभी परिवर्तनों को पहले नहीं रोकना चाहिए, और फिर उन्हें पुनर्स्थापित करना चाहिए?
मेल

5

यहाँ एक अच्छा जवाब है: सभी गिट शाखाओं को कैसे लाया जाए

for remote in `git branch -r`; do git branch --track $remote; done
git pull --all

आप सिर्फ करने के बजाय git fetchऔर करने का सुझाव क्यों दे रहे हैं ? git pullgit pull
सिंटगमा

धन्यवाद। ऐसा लगता है कि पुल सभी शाखाओं को सभी रिमोट से प्राप्त करता है। इसे बदल दिया
दूधोवस्की

8
यह सभी रीमेक लाएगा, लेकिन यह केवल वर्तमान शाखा को मर्ज करेगा। यदि आपके पास 10 रीमोट हैं, तो आपको प्रत्येक को मैन्युअल रूप से जांचना और मर्ज करना होगा।

ऐसा करने से origin/उपसर्ग के साथ स्थानीय रूप से सभी दूरस्थ शाखाएं
बन जाएंगी

3

एक स्क्रिप्ट जो मैंने अपने GitBash के लिए लिखी थी । निम्नलिखित को पूरा करता है:

  • डिफ़ॉल्ट रूप से सभी ट्रैक कि उत्पत्ति को ट्रैक करने के लिए सेटअप से मूल के लिए खींचती है, अगर आप वांछित एक अलग रिमोट निर्दिष्ट करने के लिए अनुमति देता है।
  • यदि आपकी वर्तमान शाखा गंदी स्थिति में है तो यह आपके परिवर्तनों को रोक देती है और अंत में इन परिवर्तनों को पुनर्स्थापित करने का प्रयास करेगी।
  • दूरस्थ शाखा को ट्रैक करने के लिए स्थापित की गई प्रत्येक स्थानीय शाखा के लिए:
    • git checkout branch
    • git pull origin
  • अंत में, आपको अपनी मूल शाखा में लौटा देगा और राज्य को बहाल करेगा।

** मैं इसका उपयोग करता हूं, लेकिन पूरी तरह से परीक्षण नहीं किया है, अपने जोखिम पर उपयोग करें। यहाँ .bash_alias फ़ाइल में इस स्क्रिप्ट का एक उदाहरण देखें ।

    # Do a pull on all branches that are tracking a remote branches, will from origin by default.
    # If current branch is dirty, will stash changes and reply after pull.
    # Usage: pullall [remoteName]
    alias pullall=pullAll
    function pullAll (){
     # if -h then show help
     if [[ $1 == '-h' ]]
    then
      echo "Description: Pulls new changes from upstream on all branches that are tracking remotes."
      echo 
      echo "Usage: "
      echo "- Default: pullall"
      echo "- Specify upstream to pull from: pullall [upstreamName]"
      echo "- Help: pull-all -h"
    else

     # default remote to origin
     remote="origin"
     if [ $1 != "" ]
     then
       remote=$1
     fi

     # list all branches that are tracking remote
     # git branch -vv : list branches with their upstreams
     # grep origin : keep only items that have upstream of origin
     # sed "s/^.."... : remove leading *
     # sed "s/^"..... : remove leading white spaces
     # cut -d" "..... : cut on spaces, take first item
     # cut -d splits on space, -f1 grabs first item
     branches=($(git branch -vv | grep $remote | sed "s/^[ *]*//" | sed "s/^[ /t]*//" | cut -d" " -f1))

     # get starting branch name
     startingBranch=$(git rev-parse --abbrev-ref HEAD)

     # get starting stash size
     startingStashSize=$(git stash list | wc -l)

     echo "Saving starting branch state: $startingBranch"
     git stash

     # get the new stash size
     newStashSize=$(git stash list | wc -l)

     # for each branch in the array of remote tracking branches
     for branch in ${branches[*]}
     do
       echo "Switching to $branch"
       git checkout $branch

       echo "Pulling $remote"
       git pull $remote

     done

     echo "Switching back to $startingBranch"
     git checkout $startingBranch

     # compare before and after stash size to see if anything was stashed
     if [ "$startingStashSize" -lt "$newStashSize" ]
     then
       echo "Restoring branch state"
       git stash pop
     fi
    fi
    }

क्या आप समकक्ष विंडोज बैट फ़ाइल प्रदान कर सकते हैं?
जाफी

1
@ जफी मुझे यकीन नहीं है कि मेरे हाथों में कितना समय है और मैं बैच में सुपर धाराप्रवाह नहीं हूं, लेकिन मैं इसे दे सकता हूं। मैं अपनी प्रगति यहाँ पोस्ट करूँगा , शायद अन्य लोग इसमें कदम रख सकें और मदद कर सकें?
फिलासॉफ़ल

3

यदि आप विंडोज पर हैं तो आप PyGitUp का उपयोग कर सकते हैं जो git-upपायथन के लिए एक क्लोन है । आप स्कूप के साथ या इसके माध्यम से पाइप का उपयोग करके इसे स्थापित कर सकते हैंpip install --user git-up का उपयोग करscoop install git-up

[4]


3

बस एक अद्यतन जवाब पोस्ट कर रहा हूँ। git-upअब रखरखाव नहीं किया जाता है और यदि आप प्रलेखन पढ़ते हैं, तो वे उल्लेख करते हैं कि कार्यक्षमता अब गिट में उपलब्ध है

Git 2.9 के रूप में, git pull --rebase --autostash मूल रूप से एक ही काम करता है।

तदनुसार, यदि आप Git 2.9 या बाद में अपडेट करते हैं, तो आप git-up को स्थापित करने के बजाय इस उपनाम का उपयोग कर सकते हैं:

git config --global alias.up 'pull --rebase --autostash'

आप इसे git pullGit 2.9 के रूप में भी हर किसी के लिए सेट कर सकते हैं (धन्यवाद @VonC कृपया उसका उत्तर यहां देखें )

git config --global pull.rebase true
git config --global rebase.autoStash true

1
आप एक उपनाम की जरूरत नहीं है। एक साधारण गिट पुल सही विन्यास के साथ पर्याप्त है: stackoverflow.com/a/40067353/6309
VONC

ग्रेट कॉल आउट थैंक्स @VonC मैंने अपना उत्तर अपडेट किया :) किसी git-upदस्तावेज को PR भी सबमिट कर सकता है क्योंकि वे इस बात का उल्लेख नहीं करते हैं कि
aug

यह एक बार में सभी स्थानीय शाखाओं को अपडेट नहीं करता है, यही वजह है कि मैं मुख्य रूप से उपयोग किया जाता है git-up
किरण

प्रलेखन अद्यतन git-up:)
अगस्त

3

मुझे इस सवाल का एक ही मुद्दा आया ...

इसके बारे में खुद को आश्चर्यचकित करते हुए, मैंने अपनी .bashrcफ़ाइल के अंदर एक छोटा उर्फ ​​कार्य किया :

gitPullAll() {
    for branch in `git branch | sed -E 's/^\*/ /' | awk '{print $1}'`; do
        git checkout $branch
        git pull -p
        printf "\n"
    done
    echo "Done"
}

मेरे लिए काम किया:


2

यदि refs / हेड / मास्टर को refs / remotes / foo / मास्टर , के आउटपुट के लिए तेजी से अग्रेषित किया जा सकता है

git merge-base refs/heads/master refs/remotes/foo/master

SHA1 आईडी को वापस करना चाहिए जो कि रिफ / हेड / मास्टर पॉइंट को दर्शाता है। इसके साथ, आप एक स्क्रिप्ट डाल सकते हैं जो स्वचालित रूप से उन सभी स्थानीय शाखाओं को अपडेट करती है जिनके पास कोई डायवर्टिंग कमिट नहीं है जो उन पर लागू होता है।

यह छोटा शेल स्क्रिप्ट (मैंने इसे गिट-कैन-एफएफ कहा है ) दिखाता है कि यह कैसे किया जा सकता है।

#!/bin/sh

set -x

usage() {
    echo "usage: $(basename $0) <from-ref> <to-ref>" >&2
    exit 2
}

[ $# -ne 2 ] && usage

FROM_REF=$1
TO_REF=$2

FROM_HASH=$(git show-ref --hash $FROM_REF)
TO_HASH=$(git show-ref --hash $TO_REF)
BASE_HASH=$(git merge-base $FROM_REF $TO_REF)

if [ "$BASE_HASH" = "$FROM_HASH" -o \
     "$BASE_HASH" = "$FROM_REF" ]; then
    exit 0
else
    exit 1
fi

उस टिप्पणी से आपका क्या तात्पर्य है?
पहाड़ी

मैं खुद स्क्रिप्ट पहाड़ी को लिखने में सक्षम नहीं हूं, और मुझे अपने ज्ञान ज्ञान के बारे में आश्वस्त नहीं है कि मैं गिट-मर्ज-बेस का उपयोग कर सकता हूं।
नॉर्मन राम्से

2
मुझे डर है कि इतनी अच्छी तरह से प्रदान की गई स्क्रिप्ट का फायदा उठाने के लिए मुझे मॉडल की समझ नहीं है। यह एक व्यक्ति को भाड़े के लिए स्विच करने के लिए पर्याप्त बनाने के लिए पर्याप्त है।
नॉर्मन राम्से

मुझे व्यक्तिगत रूप से टॉमी पुण्येनन का लेख "गीट फॉर कंप्यूटर वैज्ञानिकों" में गिट के मॉडल और शब्दावली से परिचित होने में काफी मदद मिली।
पहाड़ी 13

2

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

git fetch

head="$(git symbolic-ref HEAD)"
git for-each-ref --format="%(refname) %(upstream)" refs/heads | while read ref up; do
    if [ -n "$up" -a "$ref" != "$head" ]; then
        mine="$(git rev-parse "$ref")"
        theirs="$(git rev-parse "$up")"
        base="$(git merge-base "$ref" "$up")"
        if [ "$mine" != "$theirs" -a "$mine" == "$base" ]; then
            git update-ref "$ref" "$theirs"
        fi
    fi
done

2

थोड़ी अलग लिपि जो केवल तेजी से आगे की शाखाओं की है जिनके नाम उनकी अपस्ट्रीम शाखा से मेल खाते हैं। यदि तेजी से आगे संभव है, तो यह वर्तमान शाखा को भी अपडेट करता है।

सुनिश्चित करें कि आपकी सभी शाखाओं की अपस्ट्रीम शाखाएँ सही ढंग से चल रही हैं git branch -vv। के साथ अपस्ट्रीम शाखा सेट करेंgit branch -u origin/yourbanchname

फाइल में कॉपी-पेस्ट करें और paste५५ पर काटा:

#!/bin/sh

curbranch=$(git rev-parse --abbrev-ref HEAD)

for branch in $(git for-each-ref refs/heads --format="%(refname:short)"); do
        upbranch=$(git config --get branch.$branch.merge | sed 's:refs/heads/::');
        if [ "$branch" = "$upbranch" ]; then
                if [ "$branch" = "$curbranch" ]; then
                        echo Fast forwarding current branch $curbranch
                        git merge --ff-only origin/$upbranch
                else
                        echo Fast forwarding $branch with origin/$upbranch
                        git fetch . origin/$upbranch:$branch
                fi
        fi
done;

2

निम्नलिखित एक-लाइनर फास्ट-फॉरवर्ड सभी शाखाएं जिनके ऊपर एक शाखा है यदि संभव हो, और अन्यथा एक त्रुटि प्रिंट करता है:

git branch \
  --format "%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)" |
  sh

यह कैसे काम करता है?

यह git branchकमांड के साथ एक कस्टम प्रारूप का उपयोग करता है । प्रत्येक शाखा के लिए एक अपस्ट्रीम शाखा है, यह निम्नलिखित पैटर्न के साथ एक रेखा प्रिंट करती है:

git push . <remote-ref>:<branch>

इसे सीधे पाइप किया जा सकता है sh(यह मानते हुए कि शाखा के नाम सुव्यवस्थित हैं)। ओमित| shयह क्या कर रहा है यह देखने लिए ।

चेतावनियां

वन-लाइनर आपके रिमोट से संपर्क नहीं करेगा। इसे चलाने से पहले git fetchया जारी करें git fetch --all

वर्तमान में चेक-आउट की गई शाखा जैसे संदेश के साथ अपडेट नहीं की जाएगी

! [remote rejected] origin/master -> master (branch is currently checked out)

इसके लिए आप रेगुलर का सहारा ले सकते हैं git pull --ff-only

उपनाम

आपके लिए निम्न जोड़ें .gitconfigताकि git fftप्रदर्शन इस आदेश:

[alias]
        fft = !sh -c 'git branch --format \"%(if)%(upstream:short)%(then)git push . %(upstream:short):%(refname:short)%(end)\" | sh' -

मेरी भी देख लो .gitconfig। उपनाम "फास्ट-फॉरवर्ड ट्रैकिंग (ब्रांच)" का शॉर्टहैंड है।


यह एक अच्छा समाधान है, हालांकि मुझे लगता है कि मैं का उपयोग किया जाएगा soluction @ जॉन द्वारा propsed यह बेहतर उत्पादन के लिए। hub
डिडिएर एल

यह तेज, सरल और वास्तव में काम करता है! मैं चकित हूँ, हालांकि git pushयह पूरी तरह से विपरीत है कि आप क्या उम्मीद करेंगे। क्या राज हे?
ब्रैंडलोनाइट

@BrandonLWhite: मैं सवाल नहीं समझता। आप क्या उम्मीद करते हैं git push?
krlmlr

git pushके पास अपलोड शब्दार्थ है - मेरे पास स्थानीय स्तर पर कुछ संदेश हैं जो मैं ऊपर भेजना चाहता हूं। git pullडाउनलोड शब्दार्थ है - मैं अपनी स्थानीय शाखा में कुछ अपस्ट्रीम रिमोट कमिट्स प्राप्त करना चाहता हूं। चूंकि हम रिमोट से लोकल में नए कमिट डाउनलोड करने की बात कर रहे हैं, git pullयह स्पष्ट पसंद है। लेकिन नहीं, यह ट्रिक उपयोग करता है git pushgit pushमेरी स्थानीय शाखा में दूरस्थ परिवर्तनों को खींचने का परिणाम क्या है ?!
ब्रैंडलोनाइट

git pushस्थानीय शाखाओं को अपडेट करने के लिए भी इस्तेमाल किया जा सकता है, जब तक कि यह एक फास्ट-फॉरवर्ड अपडेट है।
krlmlr

1

@Larsmans से स्क्रिप्ट, थोड़ा सुधार हुआ:

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git rebase "origin/$branch" || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git rebase "origin/$CURRENT" || exit 1

यह खत्म होने के बाद, एक ही शाखा से काम कर रहे कॉपी को छोड़ देता है जो स्क्रिप्ट के आने से पहले थी।

git pullसंस्करण:

#!/bin/sh

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
for branch in "$@"; do
  if ["$branch" -ne "$CURRENT"]; then
    git checkout "$branch" || exit 1
    git pull || exit 1
  fi
done
git checkout "$CURRENT" || exit 1
git pull || exit 1

1

ऐसा लगता है कि कई अन्य लोगों ने भी इसी तरह के समाधानों में योगदान दिया है, लेकिन मुझे लगा कि मैं अपने साथ आए लोगों को योगदान देने के लिए आमंत्रित करूंगा। इस समाधान में एक अच्छा रंगीन आउटपुट है, इनायत से आपकी वर्तमान कार्यशील निर्देशिका को संभालता है, और तेज़ है क्योंकि यह कोई चेकआउट नहीं करता है, और आपके कार्यशील निर्देशिका को छोड़ देता है। इसके अलावा, यह सिर्फ एक शेल स्क्रिप्ट है जिसमें गिट के अलावा कोई निर्भरता नहीं है। (केवल अब तक OSX पर परीक्षण किया गया है)

#!/usr/bin/env bash

gitup(){    
RED='\033[33;31m'
YELLO='\033[33;33m'
GREEN='\033[33;32m'
NC='\033[0m' # No Color

HEAD=$(git rev-parse HEAD)
CHANGED=$(git status --porcelain | wc -l)

echo "Fetching..."
git fetch --all --prune &>/dev/null
for branch in `git for-each-ref --format='%(refname:short)' refs/heads`; do

    LOCAL=$(git rev-parse --quiet --verify $branch)
    if [ "$HEAD" = "$LOCAL" ] && [ $CHANGED -gt 0 ]; then
        echo -e "${YELLO}WORKING${NC}\t\t$branch"
    elif git rev-parse --verify --quiet $branch@{u}&>/dev/null; then
        REMOTE=$(git rev-parse --quiet --verify $branch@{u})
        BASE=$(git merge-base $branch $branch@{u})

        if [ "$LOCAL" = "$REMOTE" ]; then
           echo -e "${GREEN}OK${NC}\t\t$branch" 
        elif [ "$LOCAL" = "$BASE" ]; then
            if [ "$HEAD" = "$LOCAL" ]; then
                git merge $REMOTE&>/dev/null
            else
                git branch -f $branch $REMOTE
            fi
            echo -e "${GREEN}UPDATED${NC}\t\t$branch"
        elif [ "$REMOTE" = "$BASE" ]; then
            echo -e "${RED}AHEAD${NC}\t\t$branch"
        else
            echo -e "${RED}DIVERGED${NC}\t\t$branch"
        fi
    else
        echo -e "${RED}NO REMOTE${NC}\t$branch"
    fi
done
}

https://github.com/davestimpert/gitup

क्षमा करें, मुझे यह भी लगता है कि मैं ऊपर दिए गए अन्य उपकरण के समान नाम के साथ आया हूं।


2
क्या तुम वही हो जिसने यह लिखा है? यदि हां, तो कृपया अपनी संबद्धता का खुलासा करें अर्थात हमें बताएं कि आप इससे कैसे संबंधित हैं। अधिक जानकारी के लिए कृपया इस पर अधिक पढ़ें । विशेष रूप से मत बताओ - शो! ; हमें बताएं कि आपकी स्क्रिप्ट के कौन से भाग हैं और यह समस्या का हल कैसे / क्यों करता है।
केएल

1
हां मैंने इसे लिखा था। मैंने आपके .bashrc या .zshrc में त्वरित कॉपी-पेस्ट के लिए ऊपर दिए गए स्रोत को शामिल किया है।
स्टंप

यह एक अच्छा समाधान है और अच्छी तरह से काम करता है। किसी ने नोटिस नहीं लिया था?
विले

1

यह स्क्रिप्ट के नीचे का उपयोग करके किया जा सकता है ... यह पहले सभी शाखाओं को प्राप्त करेगा और एक-एक करके चेकआउट करेगा और अपने आप से अपडेट करेगा।

#!/bin/bash
git branch -r | grep -v '\->' | while read remote; do git branch --track 
"${remote#origin/}" "$remote"; done

set -x
CURRENT=`git rev-parse --abbrev-ref HEAD`
git fetch --all
branch_name=$(git branch | awk '{print $1" "}' | grep -v '*' | xargs)
for branch in $branch_name; do
   git checkout "$branch" || exit 1
   git rebase "origin/$branch" || exit 1
   git pull origin $branch|| exit 1
done
git checkout "$CURRENT" || exit 1
git pull || exit 1

अपना जवाब देने के लिए कुछ स्पष्टीकरण जोड़ें
मूर्ख-देव

1

आप इसे केवल एक git कमांड के साथ नहीं कर सकते, लेकिन आप इसे एक bash लाइन के साथ स्वचालित कर सकते हैं।

एक पंक्ति के साथ सभी शाखाओं को सुरक्षित रूप से अपडेट करने के लिए, यहाँ मैं क्या करूँ:

git fetch --all && for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*') ; do git checkout $branch && git merge --ff-only || break ; done
  • यदि यह एक शाखा को तेजी से अग्रेषित नहीं कर सकता है या किसी त्रुटि का सामना कर सकता है, तो यह आपको रोक देगा और आपको उस शाखा में छोड़ देगा ताकि आप वापस नियंत्रण ले सकें और मैन्युअल रूप से विलय कर सकें।

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

स्पष्टीकरण:

बेहतर पठनीयता के लिए, इसे कई लाइनों में विभाजित किया जा सकता है:

git fetch --all && \
for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*')
    do git checkout $branch && \
    git merge --ff-only || break
done
  1. git fetch --all && ... => सभी रीमेक से फ़ॉर्म्स प्राप्त होते हैं और यदि कोई त्रुटि नहीं हुई है, तो अगले कमांड के साथ जारी रखें।

  2. git branch | sed '/*/{$q;h;d};$G' | tr -d '*'=> के आउटपुट से git branch, sedलाइन को ए के साथ *ले जाएं और इसे अंत तक ले जाएं (ताकि वर्तमान शाखा अंतिम रूप से अपडेट हो जाए)। फिर trबस हटा दें *

  3. for branch in $(...) ; do git checkout $branch && git merge --ff-only || break ; done=> पिछली कमांड से प्राप्त प्रत्येक शाखा के नाम के लिए, इस शाखा की जाँच करें और तेजी से आगे बढ़ने के साथ विलय करने का प्रयास करें। यदि यह विफल हो जाता है, breakतो कॉल किया जाता है और कमांड यहां बंद हो जाती है।

बेशक, आप बदल सकते हैं git merge --ff-onlyके साथ git rebaseअगर यह होता है कि आप क्या चाहते।

अंत में, आप इसे अपने bashrc में एक उपनाम के रूप में रख सकते हैं :

alias git-pull-all='git fetch --all && for branch in $(git branch | sed '\''/*/{$q;h;d};$G'\'' | tr -d "*") ; do git checkout $branch && git merge --ff-only || break ; done'

या यदि आप 'और' के साथ खिलवाड़ करने से डरते हैं, या आप अपने संपादक में सिंटैक्टिक पठनीयता रखना पसंद करते हैं, तो आप इसे एक समारोह के रूप में घोषित कर सकते हैं:

git-pull-all()
{
    git fetch --all && for branch in $(git branch | sed '/*/{$q;h;d};$G' | tr -d '*') ; do git checkout $branch && git merge --ff-only || break ; done
}

बक्शीश:

उन लोगों के लिए जो इस sed '/*/{$q;h;d};$G'भाग पर स्पष्टीकरण चाहते हैं :

  • /*/=> एक के साथ लाइन के लिए खोजें *

  • {$q => यदि यह अंतिम पंक्ति में है, तो पद छोड़ें (हमें कुछ भी करने की आवश्यकता नहीं है क्योंकि वर्तमान शाखा पहले से ही सूची में अंतिम है)।

  • ;h;d} => अन्यथा, होल्ड बफर में लाइन को स्टोर करें और इसे वर्तमान सूची स्थिति में हटा दें।

  • ;$G => जब यह अंतिम पंक्ति तक पहुंचता है, तो होल्ड बफर की सामग्री को जोड़ दें।


आप अंतहीन लाइनों के सभी पागलपन से बचने और स्क्रिप्ट के शीर्ष में &&स्थापित कर सकते हैं set -e
मार्स

0

क्या मेरी सभी स्थानीय शाखाओं को "git pull --all" अपडेट कर सकते हैं?

नहीं ये नहीं हो सकता। फास्ट-फ़ॉरवर्डिंग के लिए, मैंने ऐसा करने के लिए एक छोटा उपकरण लिखा। https://github.com/changyuheng/git-fast-forward-all

इस उपकरण के लाभ:

  1. एक रिपॉजिटरी में कई रीमोट का समर्थन करता है। (hub sync फिलहाल कई रीमेक का समर्थन नहीं करता है)
  2. स्थानीय शाखा और संबंधित दूरस्थ ट्रैकिंग शाखा पर अलग-अलग नाम रखने का समर्थन करता है।
  3. हर एक शाखा के लिए रिमोट लाने वाली अन्य लिपियों की तुलना में बहुत तेज़।
  4. कोई त्रुटि-प्रवण रेगेक्स पार्सिंग / संपादन नहीं।

-1

Git 2.9 के अनुसार:

git pull --rebase --autostash

Https://git-scm.com/docs/git-rebase देखें

ऑपरेशन शुरू होने से पहले एक अस्थायी स्लैश बनाएं और ऑपरेशन समाप्त होने के बाद इसे लागू करें। इसका मतलब है कि आप एक गंदे वर्कट्री पर रिबास चला सकते हैं। हालांकि, देखभाल के साथ उपयोग करें: एक सफल रिबास के बाद अंतिम स्लैश आवेदन गैर-तुच्छ संघर्ष हो सकता है।


-1

वास्तव में, गिट के साथ version 1.8.3.1, यह काम करता है:

[root@test test]# git br
* master
  release/0.1
  update
[root@test test]# git pull --rebase
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 9 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
From http://xxx/scm/csdx/test-git
   d32ca6d..2caa393  release/0.1 -> origin/release/0.1
Current branch master is up to date.
[root@test test]# git --version
git version 1.8.3.1

मास्टर शाखा में, आप अन्य सभी शाखाओं को अपडेट कर सकते हैं। @Cascabel

मुझे नहीं पता कि 2.17 में कौन सा संस्करण इसे तोड़ता / ठीक करता है, (जो मैं उपयोग करता हूं), यह काम कर सकता है।

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