ऐसे स्थानीय टैग हटाएं जो अब दूरस्थ रिपॉजिटरी में नहीं हैं


468

हम अपनी तैनाती प्रक्रिया के भाग के रूप में टैग का उपयोग करते हैं। समय-समय पर, हम इन टैग्स को अपने रिमोट रिपॉजिटरी से हटाकर साफ करना चाहते हैं।

यह बहुत सीधा है। एक उपयोगकर्ता कमांड के एक सेट में स्थानीय टैग और रिमोट टैग को हटा देता है। हमारे पास थोड़ी सी शेल स्क्रिप्ट है जो दोनों चरणों को जोड़ती है।

2 वें (3, 4, ...) उपयोगकर्ता के पास अब स्थानीय टैग हैं जो अब रिमोट पर प्रतिबिंबित नहीं होते हैं।

मैं एक ऐसी कमांड की तलाश में हूं, git remote prune originजो स्थानीय रूप से ट्रैकिंग शाखाओं की सफाई करे, जिसके लिए दूरस्थ शाखा को हटा दिया गया है।

वैकल्पिक रूप से, रिमोट टैग को सूचीबद्ध करने के लिए एक साधारण कमांड का उपयोग स्थानीय टैग के माध्यम से तुलना करने के लिए किया जा सकता है git tag -l



1
नोट: Git २.१ ((Q2 २०१ 2.) के साथ, एक साधारण आपको git config fetch.pruneTags trueवह कर देगा git fetchजो आप चाहते हैं! इस अन्य प्रश्न के लिए मेरा उत्तर देखें ।
वॉनक

2
नीचे दिए गए उत्तरों में से एक टिप्पणी को दोहराते हुए: कम से कम git 2.18.0 के साथ कोई भी इस वाक्यविन्यास का उपयोग कर सकता है: git fetch --prune --prune-tags origin
zutnop

जवाबों:


71

अच्छा प्रश्न। :) मेरे पास पूरा उत्तर नहीं है ...

उस ने कहा, आप के माध्यम से दूरस्थ टैग की एक सूची प्राप्त कर सकते हैं git ls-remote। द्वारा संदर्भित रिपॉजिटरी में टैग सूचीबद्ध करने के लिए origin, आप दौड़ेंगे:

git ls-remote --tags origin

हैश और दोस्ताना टैग नामों की सूची देता है, जैसे:

94bf6de8315d9a7b22385e86e1f5add9183bcb3c        refs/tags/v0.1.3
cc047da6604bdd9a0e5ecbba3375ba6f09eed09d        refs/tags/v0.1.4
...
2f2e45bedf67dedb8d1dc0d02612345ee5c893f2        refs/tags/v0.5.4

आप निश्चित रूप से इस सूची के द्वारा उत्पन्न टैग की तुलना आपके द्वारा स्थानीय स्तर पर किए गए टैग से तुलना करने के लिए एक साथ कर सकते हैं। एक नज़र डालें git show-ref --tags, जो टैग नामों को उसी रूप में उत्पन्न करता है git ls-remote)।


एक तरफ के रूप में, git show-refएक विकल्प होता है जो आपके पसंद के विपरीत होता है। निम्न कमांड दूरस्थ शाखा पर उन सभी टैगों को सूचीबद्ध करेगी जो आपके पास स्थानीय रूप से नहीं हैं:

git ls-remote --tags origin | git show-ref --tags --exclude-existing

धन्यवाद माइक। मैं तुलना के लिए प्रत्येक सूची का उपयोग करके अपना स्वयं का बैश स्क्रिप्ट रोल करूंगा।
भेजें

11
यदि आप एक जटिल स्क्रिप्ट में रुचि नहीं रखते हैं, तो रिचर्ड डब्ल्यू का जवाब बहुत अधिक सुरुचिपूर्ण ढंग से करता है।
काइल हिरोनिमस

1
स्थानीय रूप से मौजूद टैग के बारे में साइड नोट को अधिक git remote | xargs -L 1 git ls-remote --tags | git show-ref --tags --exclude-existing
रीमोट की

एक सरल समाधान के लिए अगला उत्तर देखें
sfletche

git सपोर्ट करता है --prune-tags। पता लगाएं कि यह किस संस्करण में पेश किया गया था। git-scm.com/docs/git-fetch#git-fetch---prune-tags
John Kloian

1052

यह बहुत अच्छा सवाल है, मैं एक ही बात सोच रहा था।

मैं एक स्क्रिप्ट लिखना नहीं चाहता था इसलिए एक अलग समाधान की मांग की। कुंजी यह खोज रही है कि आप स्थानीय रूप से टैग हटा सकते हैं, फिर रिमोट सर्वर से "इसे वापस लाने" के लिए git fetch का उपयोग करें। यदि टैग रिमोट पर मौजूद नहीं है, तो यह हटा दिया जाएगा।

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

git tag -l | xargs git tag -d
git fetch --tags

इन:

  1. स्थानीय रेपो से सभी टैग हटाएं। FWIW, xargs प्रत्येक टैग आउटपुट को "टैग -d" के लिए कमांड लाइन पर "टैग -l" द्वारा रखता है। इसके बिना, git कुछ भी नहीं हटाएगा क्योंकि यह stdin (मूर्खतापूर्ण git) नहीं पढ़ता है।

  2. रिमोट रेपो से सभी सक्रिय टैग प्राप्त करें।

यह भी विंडोज पर एक इलाज काम करता है।


57
StackOverflow पर यह मेरा पसंदीदा git उत्तर होना चाहिए। यह ज्ञान, सरलता और चतुराई को जोड़ती है जो सब कुछ समझाती है।
बजे

25
जैसा कि एक अलग उत्तर में उल्लेख किया गया है, यह सभी स्थानीय टैग हटाता है, और रिमोट रेपो में नहीं स्पष्ट रूप से फिर से नहीं बनाया जाएगा
दूसरा

13
FWIW यह पूरी तरह से अनावश्यक होना चाहिए। एक git tag prune originकमांड होनी चाहिए ।
void.pointer

9
यह हर किसी के लिए काम नहीं कर सकता है। आपको सुरक्षित रूप से होने के लिए git fetch --tags करना चाहिए।
एडम कुर्कविज़ जूल

5
मुझे git tag -l | %{git tag -d $_}पॉवरशेल में यह काम करने के लिए जाना था । किसी और के बारे में निश्चित नहीं।
एलेन

244

Git v1.7.8 से v1.8.5.6 तक, आप इसका उपयोग कर सकते हैं:

git fetch <remote> --prune --tags

अपडेट करें

यह e66ef7ae6f31f2 के कारण git के नए संस्करणों (v1.9.0 से शुरू) पर काम नहीं करता है । मैं वास्तव में इसे हटाना नहीं चाहता, क्योंकि इसने कुछ लोगों के लिए काम किया।

जैसा कि v1.7.8 के बाद से सभी Git संस्करण के साथ "चाड जूलियानो" द्वारा सुझाया गया है, आप निम्न कमांड का उपयोग कर सकते हैं:

git fetch --prune <remote> +refs/tags/*:refs/tags/*

वाइल्डकार्ड विस्तार से बचने के लिए आपको उद्धरण चिह्नों के साथ भाग (उदाहरण के लिए विंडोज पर) संलग्न करना पड़ सकता है:

git fetch --prune <remote> "+refs/tags/*:refs/tags/*"

2
मैं Windows 1.9.4-पूर्वावलोकन20140611 के लिए गिट के साथ पैक किए गए दस्तावेज़ का संदर्भ देता हूं (और मुझे पिछले सभी संस्करणों पर संदेह है)। मैंने कहा कि "git fetch --help" के साथ प्रलेखन का उपयोग किया जाता है [उद्धरण] टैग प्रूनिंग के अधीन नहीं हैं यदि उन्हें केवल डिफ़ॉल्ट टैग ऑटो-अनुसरण के कारण या एक .tags विकल्प के कारण प्राप्त किया जाता है। [/ उद्धरण]
Félive Cantournet

2
git fetch --prune <remote> +refs/tags/*:refs/tags/*ZSH में काम नहीं किया, लेकिन यह BASH में काम करता है
Alex

3
@ एलेक्स सिर्फ इसलिए कि zsh का विस्तार होता है *लेकिन अगर आप एक ही उद्धरण देते हैं कि यह ठीक होना चाहिए।
NSF

3
@ v01pe - अब प्रिटिंग सेक्शन के तहत डॉक्यूमेंट में वर्णित git 2.17.0 के बाद से अब एक git शॉर्टकट-prune- टैग उपलब्ध है: git-scm.com/docs/git-fetch/2.17.0 डॉक्युमेंट से: - -prune- टैग विकल्प refs / टैग / *: refs / टैग / * दूरस्थ के refspecs में घोषित होने के बराबर है। समकक्ष: git fetch origin --prune --prune-tagsया git fetch origin --prune 'refs/tags/*:refs/tags/*'या git fetch <url of origin> --prune --prune-tagsयाgit fetch <url of origin> --prune 'refs/tags/*:refs/tags/*'
mkisaacs

3
git fetch origin --prune --prune-tagsसुदूर ट्रैकिंग शाखाएँ और टैग दोनों को prune करें। 2.18 संस्करण में git की जाँच की।
नंबर 945

158

यदि आप केवल उन टैग को चाहते हैं जो रिमोट पर मौजूद हैं, तो बस अपने सभी स्थानीय टैग हटा दें:

$ git tag -d $(git tag)

और फिर सभी दूरस्थ टैग प्राप्त करें:

$ git fetch --tags

1
निर्दोष, मैं xargs के साथ समस्या थी एक यह कुछ टैग नहीं मिल रहा है
Marcio Toshio

3
@ocroquette, मुझे यकीन नहीं है कि यह किस तरह से अच्छा है xargs। यदि आपके पास ARG_MAXया इसी तरह की सीमाओं से अधिक टैग हैं, तो यह काम नहीं करेगा। गैर- xargsजरूरी , लेकिन संभव है, और यही कारण है कि महान है।
पॉल ड्रेपर 15

2
"अच्छा" एक व्यक्तिपरक चीज है, हर कोई अपनी राय खुद बनाएगा। ARG_MAX के बारे में, यह सच है। हालाँकि, मेरे द्वारा उपयोग किए जाने वाले सिस्टम पर, ARG_MAX किसी भी रिपॉजिटरी में मेरे द्वारा टैग किए जाने की संख्या से बहुत अधिक है, इसलिए मैं सीमा को बुरा नहीं मानता, जैसा कि मैं इसके बारे में बुरा नहीं मानता जब मैं "ls * .jpg" लिखता हूं। ।
ऑक्ट्रोक्वेट 16

2
सबसे साफ समाधान
16

2
git config --global alias.prune-tags '!git tag -d $(git tag) && git fetch --tags'अप्रचलित उर्फ ​​कमान। का आनंद लें। :-)
कार्ल विल्बर

87

Git के हालिया संस्करणों की तरह दिखता है (मैं git v2.20 पर हूँ) एक को बस कहने की अनुमति देता है

git fetch --prune --prune-tags

बहुत क्लीनर!

https://git-scm.com/docs/git-fetch#_pruning

जब आप लाते हैं, तो आप हमेशा टैग टैग को git कॉन्फ़िगर कर सकते हैं:

git config fetch.pruneTags true

यदि आप केवल एक विशिष्ट रिमोट से लाते समय टैग को चुभाना चाहते हैं, तो आप remote.<remote>.pruneTagsविकल्प का उपयोग कर सकते हैं । उदाहरण के लिए, मूल से प्राप्त करने पर हमेशा टैग टैग करें, लेकिन अन्य रीमोट न करें,

git config remote.origin.pruneTags true

महान एक। मैंने इसे SOes पर पोस्ट करने के लिए अनुकूलित किया है -> p Cómo puedo finishar las etiquetas de Git que solo tengo en local?
फेडोरक्वी 'एसओ स्टॉप हर्टिंग'

अति उत्कृष्ट! मुझे "सिग्नल -13 की सिग्नल 13 से मृत्यु हो गई" के साथ git पुश विफलता मिली। बढ़े हुए http.postbuffer से भी कोई प्रभाव नहीं। GIT_TRACE_PACKET और GIT_TRACE को सक्षम करने के बाद, मैंने "--prune-tags" का उपयोग करते हुए अमान्य रीफ़्स / टैग पर जोर दिया। आपका बहुत बहुत धन्यवाद!
Ivellios

78

V1.7.8 के बाद से Git के सभी संस्करण git fetchएक refspec के साथ समझते हैं , क्योंकि v1.9.0 के बाद से --tagsविकल्प ओवरराइड करता --pruneहै। एक सामान्य उद्देश्य समाधान के लिए, यह प्रयास करें:

$ git --version
git version 2.1.3

$ git fetch --prune origin "+refs/tags/*:refs/tags/*"
From ssh://xxx
 x [deleted]         (none)     -> rel_test

Git v1.9.0 में "--prune" व्यवहार के साथ "--tags" कैसे बदला जाता है, इस पर आगे पढ़ने के लिए, देखें: https://github.com/git/git/commit/e66ef7ae6f31f246dead62f74cc2acb75fd001c


7
यह शीर्ष उत्तर होना चाहिए। यह एक एकल git कमांड है, जिसमें कोई बैश नहीं, कोई पाइप नहीं है, और कोई xargs नहीं है।
जी। सिल्वी डेविस

1
अपस्ट्रीम पर आधारित मेरे स्थानीय टैग्स को बदल दिया originगया upstreamऔर उनके साथ बदल दिया गया; git push origin :<deleted-tag-name>हटाए गए टैग को हटाते हुए, अगली बार मेरा GitHub कांटा अपडेट किया गया।
दुबला

3
कम से कम गिट 2.18.0 के साथ भी इस वाक्यविन्यास का उपयोग कर सकते हैं:git fetch --prune --prune-tags origin
मार्टिन

3
Git 2.17.0 के साथ शुरू - --prune टैग विकल्प शामिल किया गया था और निम्नलिखित दस्तावेज़ में बराबर आदेशों के साथ विस्तार से छंटाई खंड में वर्णित: git-scm.com/docs/git-fetch/2.17.0 git fetch origin --prune --prune-tags या git fetch origin --prune 'refs/tags/*:refs/tags/*' या git fetch <url of origin> --prune --prune-tags याgit fetch <url of origin> --prune 'refs/tags/*:refs/tags/*'
mkisaacs

8

Git स्थानीय टैग्स की सफाई का मूल समर्थन करता है:

git fetch --tags --prune

यह कमांड नवीनतम टैग में खींचती है और हटाए गए सभी टैग को हटा देती है।


ऐसा लगता है कि इसे "--prune-tags" के बजाय "--prune" होना चाहिए, अन्यथा मुझे यही चाहिए, धन्यवाद।
AnyDev

मैं स्रोत पेड़ में समस्या हो रही है कुछ रेफरी पुश करने में विफल रहा है ...: यह मेरे लिए काम करता है :) धन्यवाद Alot
अभिषेक थपलियाल


4

स्थानीय और दूरस्थ टैग के बीच अंतर दिखाएं:

diff <(git tag | sort) <( git ls-remote --tags origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort)
  • git tag स्थानीय टैग की सूची देता है
  • git ls-remote --tags दूरस्थ टैग के लिए पूर्ण पथों की सूची देता है
  • cut -f2 | grep -v '\^' | sed 's#refs/tags/##' दूरस्थ टैग पथों की सूची से केवल टैग नाम निकालता है
  • अंत में हम प्रत्येक दो सूचियों को क्रमबद्ध करते हैं और उन्हें अलग करते हैं

"<" से शुरू होने वाली लाइनें आपके स्थानीय टैग हैं जो अब दूरस्थ रेपो में नहीं हैं। यदि वे कुछ हैं, तो आप उन्हें मैन्युअल रूप से एक-एक करके निकाल सकते हैं, यदि वे कई हैं, तो आप इसे स्वचालित करने के लिए अधिक grep-ing और पाइपिंग करते हैं।


2
कृपया अपने कोड में कुछ स्पष्टीकरण जोड़ने पर विचार करें। यह निश्चित रूप से आपके उत्तर की गुणवत्ता में सुधार करेगा।
हार्न

स्थानीय रूप से मौजूद सभी रिमोट टैग को हटाने की पूरी कमान तब नहीं होगी:diff <(git tag | sort) <( git ls-remote --tags origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort) | grep ">" | cut -c3- | xargs -I{} git push origin :refs/tags/{}
डैनियल गेहरीर

यदि आपको एक ही समय में इस तरह के एक diff <(git show-ref --tags | grep -v '{}' | awk '{print $1 " " $2}') <(git ls-remote --tags origin | grep -v '{}' | awk '{print $1 " " $2}')
बदलाव

यह तुलना बिल्कुल वैसी थी, जिसकी मुझे तलाश थी, धन्यवाद। केवल एक चीज जो मुझे उलझन में है, वह यह है कि यह एक दो पंक्तियों को भी आउटपुट करता है, जो एक तीर से शुरू नहीं होता है <, लेकिन एक संख्या जिसके बाद अल्पविराम होता है और फिर एक प्रतिबद्ध हैश (?) के पहले तीन वर्णों की तरह क्या दिखता है? उदाहरण 7,8d4...
Kay

3

बस GitHub पर मणि कांटा pivotal_git_scripts के लिए एक git सिंक-लोकल-टैग कमांड जोड़ा गया:

https://github.com/kigster/git_scripts

मणि स्थापित करें, फिर रिमोट पर मौजूद स्थानीय टैग को हटाने के लिए अपनी रिपॉजिटरी में "गिट सिंक-लोकल-टैग" चलाएं।

वैकल्पिक रूप से आप बस इस स्क्रिप्ट को नीचे स्थापित कर सकते हैं और इसे "गिट-सिंक-लोकल-टैग्स" कह सकते हैं:


#!/usr/bin/env ruby

# Delete tags from the local Git repository, which are not found on 
# a remote origin
#
# Usage: git sync-local-tags [-n]
#        if -n is passed, just print the tag to be deleted, but do not 
#        actually delete it.
#
# Author: Konstantin Gredeskoul (http://tektastic.com)
#
#######################################################################

class TagSynchronizer
  def self.local_tags
    `git show-ref --tags | awk '{print $2}'`.split(/\n/)
  end

  def self.remote_tags
    `git ls-remote --tags origin | awk '{print $2}'`.split(/\n/)
  end

  def self.orphaned_tags
    self.local_tags - self.remote_tags
  end

  def self.remove_unused_tags(print_only = false)
    self.orphaned_tags.each do |ref|
      tag = ref.gsub /refs\/tags\//, ''
      puts "deleting local tag #{tag}"
      `git tag -d #{tag}` unless print_only
    end
  end
end

unless File.exists?(".git")
  puts "This doesn't look like a git repository."
  exit 1
end

print_only = ARGV.include?("-n")
TagSynchronizer.remove_unused_tags(print_only)

3

मुझे पता है कि मुझे पार्टी में देर हो रही है, लेकिन अब इसका त्वरित जवाब है:

git fetch --prune --prune-tags # or just git fetch -p -P

हां, अब इसे लाने का विकल्प है।

यदि आप प्राप्त नहीं करना चाहते हैं, और सिर्फ prune:

git remote prune origin

1

इसके बारे में कैसे - सभी स्थानीय टैग ड्रॉप करें और फिर से लाएं? आपके रेपो को ध्यान में रखते हुए सबमॉड्यूल हो सकते हैं:

git submodule foreach --recursive  'git tag | xargs git tag -d'
(alternatively, "for i in `find .git  -type d -name '*tags*'`; do rm -f $i/*;  done")
git fetch -t
git submodule foreach --recursive git fetch -t

1

TortoiseGit अब टैग की तुलना कर सकते हैं।

लेफ्ट लॉग रिमोट पर है, राइट लोकल पर है।

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

सिंक संवाद की तुलना टैग सुविधा का उपयोग करना:

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

इसके अलावा कछुआ मुद्दा 2973 देखें


1

@Richard W के समान लेकिन Windows (PowerShell) के लिए उत्तर

git tag | foreach-object -process { git tag -d $_ }
git fetch -t

1

मैं SourceTreeअपने MacOS पर एक कस्टम एक्शन के रूप में कमांड जोड़ता हूं।


Custom Actionsद्वारा सेटिंग Sourcetree-> Preferences...->Custom Actions


Script to rungitरास्ता बनना है ।

मैं git fetch --prune --prune-tags originरिमोट से स्थानीय में टैग को सिंक करने के लिए उपयोग करता हूं ।

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


0

नए git संस्करण में (जैसे v2.26.2)

-P, --prune- टैग लाने से पहले, --prune सक्षम होने पर रिमोट पर मौजूद किसी भी स्थानीय टैग को हटा दें। इस विकल्प का उपयोग अधिक सावधानी से किया जाना चाहिए - इसके विपरीत, यह किसी भी स्थानीय संदर्भ (स्थानीय टैग) को हटा देगा जो बनाया गया है। यह विकल्प --prune के साथ स्पष्ट टैग refspec प्रदान करने के लिए एक शॉर्टहैंड है, इसके प्रलेखन में इसके बारे में चर्चा देखें।

तो आपको चलाने की आवश्यकता होगी:

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