जाँच करें कि क्या Git में ज़रुरत है


622

मैं यह कैसे जांच सकता हूं कि दूरस्थ रिपॉजिटरी बदल गई है या मुझे खींचने की आवश्यकता है?

अब मैं इस सरल स्क्रिप्ट का उपयोग करता हूं:

git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1

लेकिन यह भारी है।

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


14
कृपया ध्यान दें: "git pull --dry-run" वैसा काम नहीं करता जैसा कि उम्मीद की जाती है। ऐसा लगता है, कि गिट पुल अनजाने विकल्पों को सीधे जीआईटी लाने के लिए पारित करता है। नतीजा यह है कि एक सामान्य गिट पुल है।

27
"पुल" एक ही समय में "लाने" और "मर्ज" करने का एक छोटा तरीका है, यदि आपको दूरस्थ रेपो स्थिति की जांच करने की आवश्यकता है तो आप वास्तव में "लाने" का अनुकरण कर रहे हैं। तो git fetch -v --dry-runजो आपकी जरूरत है।
क्लाउडियो फ्लोरिनी

जवाबों:


857

पहली बार उपयोग करें git remote update, अपने दूरस्थ रीफ़्स को अद्यतित करने के लिए फिर आप कई काम कर सकते हैं, जैसे:

  1. git status -unoआपको बताएगा कि आप जिस शाखा पर नज़र रख रहे हैं, वह आगे है, पीछे है या नहीं। यदि यह कुछ नहीं कहता है, तो स्थानीय और दूरस्थ समान हैं।

  2. git show-branch *masterआपको उन सभी शाखाओं में दिखाई देगा जिनके नाम 'मास्टर' (जैसे मास्टर और मूल / मास्टर ) में समाप्त होते हैं ।

यदि आप ( ) के -vसाथ उपयोग करते हैं, तो आप देख सकते हैं कि कौन सी शाखाएँ अद्यतन हो गई हैं, इसलिए आपको वास्तव में किसी और आदेश की आवश्यकता नहीं है।git remote updategit remote -v update

हालाँकि, ऐसा लगता है कि आप एक स्क्रिप्ट या प्रोग्राम में ऐसा करना चाहते हैं और एक सच्चे / झूठे मूल्य के साथ समाप्त करना चाहते हैं। यदि ऐसा है, तो आपके वर्तमान HEAD प्रतिबद्ध और शाखा के प्रमुख के बीच संबंध की जाँच करने के तरीके हैं, हालाँकि जब से चार संभावित परिणाम हैं, आप इसे हाँ / नहीं उत्तर में कम नहीं कर सकते। हालाँकि, यदि आप ऐसा करने के लिए तैयार हैं, तो आप pull --rebase"स्थानीय पीछे हैं" का इलाज कर सकते हैं और "स्थानीय ने" को "खींचने की आवश्यकता" के रूप में बदल दिया है, और अन्य दो को "खींचने की आवश्यकता नहीं है"।

आप किसी भी रेफरी की प्रतिबद्ध आईडी प्राप्त कर सकते हैं git rev-parse <ref>, इसलिए आप इसे मास्टर और मूल / मास्टर के लिए कर सकते हैं और उनकी तुलना कर सकते हैं। यदि वे समान हैं, तो शाखाएं समान हैं। यदि वे असमान हैं, तो आप जानना चाहते हैं कि कौन दूसरे से आगे है। उपयोग करने git merge-base master origin/masterसे आपको दोनों शाखाओं के सामान्य पूर्वज मिल जाएंगे, और यदि उन्होंने नहीं निकाला है तो यह एक या दूसरे के समान होगा। यदि आपको तीन अलग-अलग आईडी मिलते हैं, तो शाखाओं को मोड़ दिया गया है।

इसे ठीक से करने के लिए, उदाहरण के लिए, एक स्क्रिप्ट में, आपको वर्तमान शाखा को संदर्भित करने में सक्षम होने की आवश्यकता है, और दूरस्थ शाखा जो इसे ट्रैक कर रही है। /etc/bash_completion.dशाखा नामों को प्राप्त करने के लिए बैश प्रॉम्प्ट-सेटिंग फ़ंक्शन में कुछ उपयोगी कोड होते हैं। हालाँकि, आपको वास्तव में नाम प्राप्त करने की आवश्यकता नहीं है। Git में शाखाओं और कमिट्स (जैसा कि दस्तावेज में है git rev-parse --help) के संदर्भ में कुछ साफ-सुथरे शॉर्टहैंड हैं । विशेष रूप से, आप @वर्तमान शाखा के लिए उपयोग कर सकते हैं (यह मानते हुए कि आप अलग-अलग स्थिति में नहीं हैं) और @{u}इसके अपस्ट्रीम शाखा (जैसे origin/master) के लिए। तो git merge-base @ @{u}(वर्तमान में) हैश (जिस पर) की वर्तमान शाखा और इसके ऊपर की ओर मोड़ देंगे git rev-parse @और git rev-parse @{u}आपको दो युक्तियों का हैश देगा। इसे निम्नलिखित लिपि में संक्षेपित किया जा सकता है:

#!/bin/sh

UPSTREAM=${1:-'@{u}'}
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "$UPSTREAM")
BASE=$(git merge-base @ "$UPSTREAM")

if [ $LOCAL = $REMOTE ]; then
    echo "Up-to-date"
elif [ $LOCAL = $BASE ]; then
    echo "Need to pull"
elif [ $REMOTE = $BASE ]; then
    echo "Need to push"
else
    echo "Diverged"
fi

नोट: git के पुराने संस्करणों ने @अपने दम पर अनुमति नहीं दी , इसलिए आपको @{0}इसके बजाय उपयोग करना पड़ सकता है ।

लाइन UPSTREAM=${1:-'@{u}'}आपको वैकल्पिक रूप से एक अपस्ट्रीम शाखा को पारित करने की अनुमति देती है, यदि आप वर्तमान शाखा के लिए कॉन्फ़िगर किए गए एक से अलग दूरस्थ शाखा के खिलाफ जांच करना चाहते हैं। यह आमतौर पर रीमोटेनम / ब्रांचनाम के रूप का होगा । यदि कोई पैरामीटर नहीं दिया गया है, तो मान चूक जाता है @{u}

स्क्रिप्ट मानती है कि आपने ट्रैकिंग शाखाओं को अद्यतित करने के लिए git fetchया git remote updateपहले किया है । मैंने इसे स्क्रिप्ट में नहीं बनाया है क्योंकि यह अधिक लचीला होना है जिससे आप अलग-अलग ऑपरेशन कर सकते हैं और अलग-अलग ऑपरेशन के रूप में तुलना कर सकते हैं, उदाहरण के लिए यदि आप बिना लेट हुए तुलना करना चाहते हैं क्योंकि आपने हाल ही में प्राप्त किया है।


4
@ ताकेशिन मुझे लगता है कि आप git ls- रिमोट ओरिजिनल -h refs / heads / master को जोड़ सकते हैं जैसा कि @brool ने git Rev-list --max-count = 1 ओरिजिन / मास्टर के साथ सुझाया था। यदि वे उसी हैश को लौटाते हैं, तो दूरस्थ शाखा तब तक नहीं बदली जाती है जब तक कि आपने अंतिम बार अपने रिमोट रिफ्स (पुल, फ़िंच, रिमोट अपडेट आदि के साथ) अपडेट नहीं कर दिए हों। इससे यह फायदा होगा कि आपको कंटेंट को खींचना नहीं पड़ेगा। सभी सही दूर है, लेकिन एक और अधिक सुविधाजनक समय के लिए छोड़ सकता है। हालाँकि, चूंकि दूरस्थ अद्यतन गैर-विनाशकारी है, इसलिए आप इसे वैसे भी कर सकते हैं।
नील मैय्यूज

2
आप कोशिश भी कर सकते हैं git status -s -u no, जो इससे कम आउटपुट देता है git status -u no
फिलिप क्लाउड

2
@mhulse, git remote -v updategit remote --helpफुलर स्पष्टीकरण के लिए आउटपुट देखें ।
नील मेवेज़

1
@ क्रिसमिस गुड पॉइंट। पुराने संस्करणों के साथ अधिक स्पष्ट वाक्यविन्यास की आवश्यकता है। मैंने विभिन्न प्रणालियों के साथ प्रयोग किया है और पाया है कि @{u}git 1.8.3.2 के साथ काम करता है, लेकिन @ऐसा नहीं करता है। हालाँकि @साथ काम करता है 1.8.5.4। Moral of the story: git में सुधार होता रहता है और यह सबसे हाल का संस्करण है जो आप कर सकते हैं।
नील मैय्यूज़

1
अब एक विनिर्देशक @ के लिए आवश्यक है। आप @ के बजाय @ {0} का उपयोग कर सकते हैं।
बेन डेविस

132

अगर आपके पास अपस्ट्रीम ब्रांच है

git fetch <remote>
git status

अगर आपके पास अपस्ट्रीम ब्रांच नहीं है

दो शाखाओं की तुलना करें:

git fetch <remote>
git log <local_branch_name>..<remote_branch_name> --oneline

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

git fetch origin

# See if there are any incoming changes
git log HEAD..origin/master --oneline

(मैं मान रहा हूं कि origin/masterआपकी रिमोट ट्रैकिंग शाखा है)

यदि कोई भी उपर्युक्त आउटपुट में सूचीबद्ध है, तो आपके पास आने वाले परिवर्तन हैं - आपको विलय करने की आवश्यकता है। यदि कोई कमिट सूचीबद्ध नहीं है, git logतो विलय करने के लिए कुछ भी नहीं है।

ध्यान दें कि यह तब भी काम करेगा जब आप एक सुविधा शाखा पर हों - जिसके पास ट्रैकिंग रिमोट नहीं है, क्योंकि यदि गिट द्वारा याद किए origin/masterगए अपस्ट्रीम शाखा का उपयोग करने के बजाय स्पष्ट रूप से संदर्भित करता है ।


2
git fetch; git log HEAD.. --onelineयदि स्थानीय के लिए एक डिफ़ॉल्ट दूरस्थ शाखा है तो भी एक छोटी संकेतन का उपयोग किया जा सकता है।
फिल पिरोज्कोव

@philpirozhkov यदि आपके पास एक डिफ़ॉल्ट दूरस्थ शाखा है, तो मुझे लगता है कि एक साधारण "गिट स्थिति" चाहिए। मेरा जवाब किसी भी दो शाखाओं के लिए एक सामान्य था, जहां एक दूसरे पर नज़र रख सकता है या नहीं।
प्लेगहैमर

55
git rev-list HEAD...origin/master --countआपको दोनों के बीच "अलग" कमिट की कुल संख्या देगा।
जेक बर्गर

1
छोटा और सरल। मेरा पसंदीदा समाधान जो सिर्फ नए कमिट (दो बार अंगूठे)
दिखाता है

मैं इसे (उबंटू) बैच फ़ाइल में कैसे उपयोग कर सकता हूं, ताकि मैं अन्य कमांड चला सकता हूं, जब यह कमांड दिखाता है कि पुल की जरूरत है?
यूलिसिस ने Alves

69

यदि यह एक स्क्रिप्ट के लिए है, तो आप इसका उपयोग कर सकते हैं:

git fetch
$(git rev-parse HEAD) == $(git rev-parse @{u})

(नोट: इस बनाम पिछले उत्तरों का लाभ यह है कि आपको वर्तमान शाखा का नाम पाने के लिए एक अलग कमांड की आवश्यकता नहीं है। "HEAD" और "@ {u}" (वर्तमान शाखा के अपस्ट्रीम) इसका ध्यान रखें। अधिक जानकारी के लिए "git Rev-parse --help"।


मैंने @ {u} को स्वतंत्र रूप से खोजा था और मैंने आपके देखे जाने से पहले अपना उत्तर अपडेट कर दिया था।
नील मैय्यू

1
विल git rev-parse @{u}वास्तव में नवीनतम एक के बिना प्रतिबद्ध दिखाने git fetch?
काइल स्ट्रैंड

3
यह था टिकट! हालाँकि, आपके तर्क का ==अर्थ है कि "यदि ऊपर की ओर से कोई परिवर्तन नहीं हैं"। मैं !=अपने आवेदन के लिए "अगर ऊपर की ओर से परिवर्तन होते हैं" के लिए जाँच करता था। पहले मत भूलना git fetch!
क्रिसप्रेम

1
मैंने गिट लाने को जोड़ा, क्योंकि मूल प्रश्न का उत्तर देना वास्तव में आवश्यक है। btw के @लिए कम है HEAD
user1338062

विंडोज यूजर्स को @{u}git rev-parse '@{u}'
5-21 बजे

36

आदेश

git ls-remote origin -h refs/heads/master

रिमोट पर वर्तमान सिर को सूचीबद्ध करेगा - आप इसे पिछले मूल्य से तुलना कर सकते हैं या देख सकते हैं कि आपके स्थानीय रेपो में SHA है या नहीं।


1
इन मूल्यों की तुलना करने के लिए कोई नमूना स्क्रिप्ट?
ताकेशिन

18
git rev-list HEAD...origin/master --countआपको दोनों के बीच "अलग" कमिट की कुल संख्या देगा।
जेक बर्गर

3
स्पष्ट करने के लिए @jberger, जो केवल आपके पीछे (आगे और पीछे नहीं) कमिट की संख्या दिखाएगा और यह केवल तभी काम करेगा जब आप git fetchया git remote updateपहले। git statusएक गिनती, btw भी दिखाता है।
डेनिस

1
@ डेनिस ने सोचा ..कि "मूल / स्वामी में काम करता है, HEAD को घटाता है" (यानी पीछे कमिट्स की संख्या)। जबकि, ...है सममित अंतर (यानी आगे और पीछे)
जेक बर्गर

3
अति उत्कृष्ट। जहां तक ​​मैं बता सकता हूं, यह एकमात्र समाधान है जो वास्तव में अद्यतनों के लिए मूल की जांच करता है, लेकिन संक्षेप में ए नहीं करता है fetch
काइल स्ट्रैंड

35

यहाँ एक बैश वन-लाइनर है जो वर्तमान शाखा की HEAD कमिट हैश की तुलना उसकी रिमोट अपस्ट्रीम शाखा से करता है, इसमें कोई भारी git fetchया git pull --dry-runपरिचालन आवश्यक नहीं है:

[ $(git rev-parse HEAD) = $(git ls-remote $(git rev-parse --abbrev-ref @{u} | \
sed 's/\// /g') | cut -f1) ] && echo up to date || echo not up to date

यहाँ बताया गया है कि यह कुछ हद तक घनीभूत रेखा है:

  • कमांड को $(x)बैश कमांड-प्रतिस्थापन सिंटैक्स का उपयोग करके समूहीकृत और नेस्ट किया जाता है ।
  • git rev-parse --abbrev-ref @{u}एक संक्षिप्त अपस्ट्रीम रेफरी (उदा origin/master) देता है, जिसे तब पाइप- sedकमांड द्वारा अंतरिक्ष-पृथक क्षेत्रों में परिवर्तित किया जाता है , जैसे origin master
  • इस स्ट्रिंग को खिलाया जाता है, git ls-remoteजो रिमोट शाखा के प्रमुख को लौटाता है। यह कमांड रिमोट रिपॉजिटरी के साथ संवाद करेगा। cutटैब-अलग किए गए संदर्भ स्ट्रिंग को हटाते हुए पाइप्ड कमांड सिर्फ पहला फ़ील्ड (कमिट हैश) निकालता है।
  • git rev-parse HEAD स्थानीय प्रतिबद्ध हैश लौटाता है।
  • बैश सिंटैक्स [ a = b ] && x || yएक-लाइनर को पूरा करता है: यह एक टेस्ट कंस्ट्रक्शन के बाद बैश स्ट्रिंग-तुलना = है [ test ], जिसके बाद और-लिस्ट और या-लिस्ट का निर्माण होता है && true || false

2
यदि आप शाखा नामों में स्लैश का उपयोग करते हैं तो मैं sed पर / g का उपयोग नहीं करूंगा । वह "sed 's / \ / /" ही है।
मार्टिन डेविस

@wjordan आपका समाधान तब विफल हो जाता है जब रिमोट रिपॉजिटरी उपलब्ध नहीं होती (या रखरखाव के तहत) और "अप टू डेट" ट्रिगर होगा
फ्रेम

20

मेरा सुझाव है कि आप स्क्रिप्ट https://github.com/badele/gitcheck देखें । मैंने इस स्क्रिप्ट को आपके सभी Git रिपॉजिटरी में से एक में चेक के लिए कोडित किया है, और यह दिखाता है कि किसने प्रतिबद्ध नहीं किया है और किसने धक्का नहीं दिया है।

यहाँ एक नमूना परिणाम:

यहां छवि विवरण दर्ज करें


6
साफ-सुथरा, इसे शुद्ध खोल में फिर से लिखने के बारे में सोचना
ओलिवियर रिफलो

1
अब, आप सीधे एक डॉकटर कंटेनर (अपने होस्ट में आपकी फ़ाइलों के साथ) से gitcheck का उपयोग कर सकते हैं। अधिक जानकारी के लिए gitcheck github प्रोजेक्ट देखें
ब्रूनो एडेल

बैश गिट-मल्टी-रेपो-टूलिंग में एक समान उपकरण । git mrepo -cयह सभी लंबित कामों को प्रदर्शित करेगा।
ग्रेग

11

मैंने इस समाधान को @jberger की टिप्पणियों पर आधारित किया।

if git checkout master &&
    git fetch origin master &&
    [ `git rev-list HEAD...origin/master --count` != 0 ] &&
    git merge origin/master
then
    echo 'Updated!'
else
    echo 'Not updated.'
fi

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

1
धन्यवाद। यह साफ था।
शोभित पुरी

10

कई बहुत अमीर और सरल जवाब पहले से ही हैं। कुछ विपरीत प्रदान करने के लिए, मैं एक बहुत ही सरल रेखा के साथ कर सकता था।

# Check return value to see if there are incoming updates.
if ! git diff --quiet remotes/origin/HEAD; then
 # pull or whatever you want to do
fi

2
मूल उत्तर की कमी थी '!' अगर में। परिवर्तन नहीं होने पर git diff से वापसी मान शून्य है।
थूविला

IMO वहाँ से बाहर सबसे अच्छा समाधान, बिल्कुल मैं "मूल / मास्टर" या अन्य संशोधन के साथ "remotes / मूल / HEAD" स्थानापन्न करने की आवश्यकता है
Matthias Michael Engh

9

मुझे लगता है कि ऐसा करने का सबसे अच्छा तरीका होगा:

git diff remotes/origin/HEAD

यह मानते हुए कि आपके पास यह refspec पंजीकृत है। यदि आपको रिपॉजिटरी को क्लोन करना है, तो आपको करना चाहिए, अन्यथा (यदि रेपो को स्थानीय रूप से डी नोवो बनाया गया था, और रिमोट में धकेल दिया गया है), तो आपको स्पष्ट रूप से रिफस्पेक को जोड़ना होगा।


9

नीचे की स्क्रिप्ट पूरी तरह से काम करती है।

changed=0
git remote update && git status -uno | grep -q 'Your branch is behind' && changed=1
if [ $changed = 1 ]; then
    git pull
    echo "Updated successfully";
else
    echo "Up-to-date"
fi

6

मैं ब्रूल द्वारा सुझाए गए तरीके से करूंगा। निम्न एक-पंक्ति स्क्रिप्ट आपके अंतिम कमिटेड संस्करण के SHA1 को लेती है और इसकी तुलना दूरस्थ मूल में से एक से करती है, और केवल भिन्न होने पर परिवर्तन को खींचती है। और यह समाधान के आधार पर git pullया उससे भी अधिक हल्के वजन का है git fetch

[ `git log --pretty=%H ...refs/heads/master^` != `git ls-remote origin
-h refs/heads/master |cut -f1` ] && git pull

यह आदेश विफल हो जाता है, अगर git रिपॉजिटरी को "--depth 1" (डाउनलोड आकार को सीमित करने के लिए) के साथ क्लोन किया गया है। क्या आप जानते हैं, अगर इसे ठीक करने का कोई तरीका है?
एडम रिक्ज़ोस्की

गिट लॉग यह कई पंक्तियों को वापस कर रहा है, और एक त्रुटि दे रहा है "बैश: [: बहुत सारे तर्क" मैं स्विच करूंगाgit rev-parse --verify HEAD
ड्रयू पियर्स

1
यह बैश द्वारा की जाने वाली एक साधारण स्ट्रिंग तुलना है। अगर कुछ विफल होता है, तो मैं आपको अपना सिंटैक्स जांचने का सुझाव दूंगा (यानी आप इसे गलत टाइप कर रहे हैं)। पहले git log --pretty=%H ...refs/heads/master^ अपने अंतिम आरंभ किए गए संस्करण git ls-remote origin -h refs/heads/master |cut -f1 का SHA1 पाने के लिए दौड़ें, और फिर दूरस्थ मूल के SHA1 को पाने के लिए दौड़ें । ये दोनों git कमांड हैं और इनका बैश से कोई लेना-देना नहीं है। वर्ग कोष्ठक के अंदर बैश क्या होता है, पहले कमांड से आउटपुट की दूसरे के साथ तुलना करना, और यदि वे समान हैं तो यह सच है और चलता है git pull
क्लाउडियो फ्लोरिनी

"और यदि वे समान हैं तो यह सच है और चलता है git pull"। मुझे पता है कि मैं नाइटपिक हो रहा हूं, लेकिन किसी को भ्रम से बचाने के लिए, यह होना चाहिए "और यदि वे बराबर नहीं हैं "। इसके अलावा, जो भी कारण हो, मेरे लिए पहला git कमांड काम नहीं करता है। (मैं जीआईटी पर हूं 2.4.1।) इसलिए मैं git log --pretty=%H master | head -n1इसके बजाय सिर्फ उपयोग कर रहा हूं । लेकिन मुझे यकीन नहीं है कि अगर यह बिल्कुल वैसा ही है।
xd1le

6

यदि आप इस स्क्रिप्ट को चलाते हैं, तो यह परीक्षण करेगा कि क्या वर्तमान शाखा को निम्नलिखित की आवश्यकता है git pull:

#!/bin/bash

git fetch -v --dry-run 2>&1 |
    grep -qE "\[up\s+to\s+date\]\s+$(
        git branch 2>/dev/null |
           sed -n '/^\*/s/^\* //p' |
                sed -r 's:(\+|\*|\$):\\\1:g'
    )\s+" || {
        echo >&2 "Current branch need a 'git pull' before commit"
        exit 1
}

इससे बचने के लिए इसे Git हुक प्री-कमिट के रूप में रखना बहुत सुविधाजनक है

Merge branch 'foobar' of url:/path/to/git/foobar into foobar

जब आप commitसे पहले pulling

इस कोड को हुक के रूप में उपयोग करने के लिए, बस स्क्रिप्ट को कॉपी / पेस्ट करें

.git/hooks/pre-commit

तथा

chmod +x .git/hooks/pre-commit

6

मैं इसे एक वास्तविक पोस्ट के रूप में पोस्ट करना चाहता हूं क्योंकि टिप्पणियों में यह याद रखना आसान है।

इस सवाल का सही और सबसे अच्छा जवाब @ जेक बर्जर ने दिया, आपका बहुत बहुत धन्यवाद, सभी को इसकी जरूरत है और सभी को यह टिप्पणी में याद आती है। तो यहाँ से जूझ रहे सभी लोगों के लिए यह सही उत्तर है, बस इस कमांड के आउटपुट का उपयोग यह जानने के लिए करें कि क्या आपको गिट पुलिंग करने की आवश्यकता है। यदि आउटपुट 0 है, तो जाहिर है कि अपडेट करने के लिए कुछ भी नहीं है।

@stackoverflow, इस आदमी को एक घंटी दें। धन्यवाद @ जेक बर्गर

git rev-list HEAD...origin/master --count will give you the total number of "different" commits between the two.  Jake Berger Feb 5 '13 at 19:23

4

git fetch (remote)अपने रिमोट रेफ को अपडेट करने के लिए चलाएं , यह आपको दिखाएगा कि नया क्या है। फिर, जब आप अपनी स्थानीय शाखा की जांच करते हैं, तो यह आपको दिखाएगा कि क्या यह ऊपर की तरफ है।


मुझे लगता है कि उसके पास पहले से ही स्थानीय शाखा है जो चेक आउट कर चुकी है, इसलिए उसे यह दिखाने के लिए कुछ और चाहिए कि क्या वह पीछे है आदि वह इस स्थिति के साथ कर सकता है।
नील मैय्यू

यह सच है, कि आपके द्वारा रीमेक किए जाने के बाद, git statusयह भी दिखाया जाएगा।
चे

1
यह मूड में कुछ git pull --dry-runहै, लेकिन मुझे लगता है कि यह एक क्रोन स्क्रिप्ट के लिए भारी है जो प्रत्येक मिनट चलता है।
ताकेशिन

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

@ टाकेशिन: यदि आप हर मिनट रिमोट रेपो की जांच करना चाहते हैं, तो मुझे लगता है कि आप डीवीसीएस के बिंदु से चूक गए हैं। पूरे विचार को थोड़ी देर के लिए स्वतंत्र रूप से विकसित करने में सक्षम होना है, और फिर बाद में सभी को एक साथ सुचारू रूप से रखना है। यह cvs, svn, p4 आदि की तरह नहीं है, जहाँ आपको हमेशा रिपॉजिटरी में जो भी नवीनतम है, उसके शीर्ष पर काम करना होगा। अगर आपको वास्तव में किसी ऐसी चीज़ की ज़रूरत है जो किसी और पर काम कर रही है, तो आपको एक अलग संचार तंत्र का उपयोग करना चाहिए, जैसे कि ईमेल, आपको यह बताने के लिए कि यह खींचने के लिए कब तैयार है।
नील मैय्यूज जूल 20'10

4

इस तरह के सभी जटिल संकटों का समाधान इतना छोटा और आसान है:

#!/bin/bash

BRANCH="<your branch name>"
LAST_UPDATE=`git show --no-notes --format=format:"%H" $BRANCH | head -n 1`
LAST_COMMIT=`git show --no-notes --format=format:"%H" origin/$BRANCH | head -n 1`

git remote update
if [ $LAST_COMMIT != $LAST_UPDATE ]; then
        echo "Updating your branch $BRANCH"
        git pull --no-edit
else
        echo "No updates available"
fi

LAST_COMMIT और LAST_UPDATE हमेशा परिवर्तन होने पर भी बराबर होते हैं
canbax

यह समाधान अच्छा और सरल है, git remote updateअपने कोड से पहले निष्पादित करने की आवश्यकता है , नवीनतम मूल जानकारी प्राप्त करने के लिए
ak93

आदेशों git remote updateसे पहले नहीं जोड़ना चाहिए git show?
सेटटॉप

2

यहाँ एक Bash स्क्रिप्ट का मेरा संस्करण है जो पूर्वनिर्धारित फ़ोल्डर में सभी रिपॉजिटरी की जाँच करता है:

https://gist.github.com/henryiii/5841984

यह आम स्थितियों के बीच अंतर कर सकता है, जैसे कि पुल की जरूरत और पुश की आवश्यकता होती है, और यह बहुआयामी होता है, इसलिए भ्रूण एक ही बार में होता है। इसमें कई कमांड होते हैं, जैसे पुल और स्टेटस।

अपने पथ में एक फ़ोल्डर में एक सिमलिंक (या स्क्रिप्ट) रखो, फिर यह git all status(, आदि) के रूप में काम करता है । यह केवल मूल / मास्टर का समर्थन करता है, लेकिन इसे संपादित या किसी अन्य विधि के साथ जोड़ा जा सकता है।


1
git ls-remote | cut -f1 | git cat-file --batch-check >&-

किसी भी ऐसे रिमोट में संदर्भित सब कुछ सूचीबद्ध करेगा जो आपके रेपो में नहीं है। आपके पास पहले से मौजूद चीजों के लिए दूरस्थ रेफरी परिवर्तन को पकड़ने के लिए (जैसे पिछले कमिट के लिए रीसेट) थोड़ा अधिक लगता है:

git pack-refs --all
mine=`mktemp`
sed '/^#/d;/^^/{G;s/.\(.*\)\n.* \(.*\)/\1 \2^{}/;};h' .git/packed-refs | sort -k2 >$mine
for r in `git remote`; do 
    echo Checking $r ...
    git ls-remote $r | sort -k2 | diff -b - $mine | grep ^\<
done

1

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

#!/bin/bash
dir="/path/to/root"
lock=/tmp/update.lock
msglog="/var/log/update.log"

log()
{
        echo "$(date) ${1:-missing}" >> $msglog
}

if [ -f $lock ]; then
        log "Already run, exiting..."
else
        > $lock
        git -C ~/$dir remote update &> /dev/null
        checkgit=`git -C ~/$dir status`
        if [[ ! "$checkgit" =~ "Your branch is up-to-date" ]]; then
                log "-------------- Update ---------------"
                git -C ~/$dir pull &>> $msglog
                log "-------------------------------------"
        fi
        rm $lock

fi
exit 0

1

सरल regexp का उपयोग करना:

str=$(git status) 
if [[ $str =~ .*Your\ branch\ is\ behind.*by.*commits,\ and\ can\ be\ fast-forwarded ]]; then
    echo `date "+%Y-%m-%d %H:%M:%S"` "Needs pull"
else
    echo "Code is up to date"
fi

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

0

मैं स्टीफन हैबरमैन के उत्तर पर आधारित स्क्रिप्ट के एक संस्करण का उपयोग करता हूं:

if [ -n "$1" ]; then
    gitbin="git -C $1"
else
    gitbin="git"
fi

# Fetches from all the remotes, although --all can be replaced with origin
$gitbin fetch --all
if [ $($gitbin rev-parse HEAD) != $($gitbin rev-parse @{u}) ]; then
    $gitbin rebase @{u} --preserve-merges
fi

इस स्क्रिप्ट को कहा जाता है git-fetch-and-rebase, इसे directory nameऑपरेशन करने के लिए स्थानीय गिट रिपॉजिटरी के एक वैकल्पिक तर्क के साथ लागू किया जा सकता है । यदि स्क्रिप्ट को बिना किसी तर्क के कहा जाता है, तो यह वर्तमान निर्देशिका को गिट रिपॉजिटरी का हिस्सा मान लेती है।

उदाहरण:

# Operates on /abc/def/my-git-repo-dir
git-fetch-and-rebase /abc/def/my-git-repo-dir

# Operates on the Git repository which the current working directory is part of
git-fetch-and-rebase

यह यहाँ भी उपलब्ध है


0

कई उत्तर और कई पोस्ट पढ़ने के बाद, और विभिन्न क्रमपरिवर्तन की कोशिश में आधा दिन बिताते हुए, यह वही है जो मैं लेकर आया हूं।

यदि आप विंडोज पर हैं, तो आप इस स्क्रिप्ट को विंडोज में Git Bash द्वारा विंडोज (इंस्टॉलेशन या पोर्टेबल) के लिए प्रदान कर सकते हैं।

इस स्क्रिप्ट में तर्कों की आवश्यकता है

- स्थानीय पथ जैसे / डी / स्रोत / प्रोजेक्ट 1
- Git URL उदा https: //username@bitbucket.org/username/project1.git
- कुंजिका

अगर सादा पाठ में कमांड लाइन पर एक पासवर्ड दर्ज नहीं किया जाना चाहिए,
फिर GITPASS खाली है या नहीं यह जांचने के लिए स्क्रिप्ट को संशोधित करें; ऐसा न करें
बदलें और Git को पासवर्ड के लिए संकेत दें

स्क्रिप्ट होगी

- Find the current branch
- Get the SHA1 of the remote on that branch
- Get the SHA1 of the local on that branch
- Compare them.

यदि स्क्रिप्ट द्वारा मुद्रित रूप में कोई परिवर्तन होता है, तो आप लाने या खींचने के लिए आगे बढ़ सकते हैं। स्क्रिप्ट कुशल नहीं हो सकती है, लेकिन यह मेरे लिए काम करती है।

अपडेट - 2015-10-30: कंसोल के लिए पासवर्ड के साथ यूआरएल को प्रिंट करने से रोकने के लिए देव null को stderr।

#!/bin/bash

# Shell script to check if a Git pull is required.

LOCALPATH=$1
GITURL=$2
GITPASS=$3

cd $LOCALPATH
BRANCH="$(git rev-parse --abbrev-ref HEAD)"

echo
echo git url = $GITURL
echo branch = $BRANCH

# Bash replace - replace @ with :password@ in the GIT URL
GITURL2="${GITURL/@/:$GITPASS@}"
FOO="$(git ls-remote $GITURL2 -h $BRANCH 2> /dev/null)"
if [ "$?" != "0" ]; then
  echo cannot get remote status
  exit 2
fi
FOO_ARRAY=($FOO)
BAR=${FOO_ARRAY[0]}
echo [$BAR]

LOCALBAR="$(git rev-parse HEAD)"
echo [$LOCALBAR]
echo

if [ "$BAR" == "$LOCALBAR" ]; then
  #read -t10 -n1 -r -p 'Press any key in the next ten seconds...' key
  echo No changes
  exit 0
else
  #read -t10 -n1 -r -p 'Press any key in the next ten seconds...' key
  #echo pressed $key
  echo There are changes between local and remote repositories.
  exit 1
fi

0

इस सवाल पर समाप्त होने वाले विंडोज उपयोगकर्ताओं के लिए, मैं इस सवाल का जवाब एक शब्दाडंबर स्क्रिप्ट में कुछ संशोधित किया है। आवश्यक के रूप में मोड़, एक .ps1फ़ाइल को बचाने के लिए और अगर आप की तरह मांग पर निर्धारित या चलाने के लिए।

cd C:\<path to repo>
git remote update                           #update remote
$msg = git remote show origin               #capture status
$update = $msg -like '*local out of date*'
if($update.length -gt 0){                   #if local needs update
    Write-Host ('needs update')
    git pull
    git reset --hard origin/master
    Write-Host ('local updated')
} else {
    Write-Host ('no update needed')
}

0

क्योंकि नील्स के उत्तर ने मेरी बहुत मदद की, यहाँ कोई निर्भरता के साथ पायथन अनुवाद है:

import os
import logging
import subprocess

def check_for_updates(directory:str) -> None:
    """Check git repo state in respect to remote"""
    git_cmd = lambda cmd: subprocess.run(
        ["git"] + cmd,
        cwd=directory,
        stdout=subprocess.PIPE,
        check=True,
        universal_newlines=True).stdout.rstrip("\n")

    origin = git_cmd(["config", "--get", "remote.origin.url"])
    logging.debug("Git repo origin: %r", origin)
    for line in git_cmd(["fetch"]):
        logging.debug(line)
    local_sha = git_cmd(["rev-parse", "@"])
    remote_sha = git_cmd(["rev-parse", "@{u}"])
    base_sha = git_cmd(["merge-base", "@", "@{u}"])
    if local_sha == remote_sha:
        logging.info("Repo is up to date")
    elif local_sha == base_sha:
        logging.info("You need to pull")
    elif remote_sha == base_sha:
        logging.info("You need to push")
    else:
        logging.info("Diverged")

check_for_updates(os.path.dirname(__file__))

hth


-5

आप एक Phing स्क्रिप्ट भी पा सकते हैं जो अब ऐसा करती है।

मुझे अपने उत्पादन वातावरण को स्वचालित रूप से अपडेट करने के लिए एक समाधान की आवश्यकता थी और हम इस स्क्रिप्ट के लिए बहुत खुश हैं जो मैं साझा कर रहा हूं।

स्क्रिप्ट XML में लिखी गई है और उसे Phing की आवश्यकता है ।


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