Programing

더 이상 원격 저장소에없는 로컬 자식 태그를 제거하십시오.

lottogame 2020. 2. 19. 21:19
반응형

더 이상 원격 저장소에없는 로컬 자식 태그를 제거하십시오.


배포 프로세스의 일부로 git에서 태그를 사용합니다. 때때로이 태그를 원격 저장소에서 제거하여 정리하려고합니다.

이것은 매우 간단합니다. 한 명의 사용자가 하나의 명령 세트에서 로컬 태그와 원격 태그를 삭제합니다. 우리는 두 단계를 결합한 작은 쉘 스크립트를 가지고 있습니다.

두 번째 (3, 4, ...) 사용자는 이제 더 이상 리모컨에 반영되지 않는 로컬 태그를 갖습니다.

git remote prune origin원격 분기가 삭제 된 로컬 추적 분기를 정리하는 것과 유사한 명령을 찾고 있습니다.

또는을 통해 반환 된 로컬 태그와 비교하기 위해 원격 태그를 나열하는 간단한 명령을 사용할 수 있습니다 git tag -l.


좋은 질문. :) 완전한 대답이 없습니다 ...

을 통해 원격 태그 목록을 얻을 수 있습니다 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

이 목록에 의해 생성 된 태그와 로컬에있는 태그를 비교하기 위해 bash 스크립트를 확실히 만들 수 있습니다. 를 살펴보면 ) git show-ref --tags와 같은 형식으로 태그 이름이 생성됩니다 git ls-remote.


제쳐두고, git show-ref당신이 원하는 것과 반대되는 옵션이 있습니다. 다음 명령은 로컬에 없는 원격 브랜치의 모든 태그를 나열합니다 .

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

이것은 좋은 질문입니다. 나는 똑같은 것을 궁금해했습니다.

스크립트를 작성하고 싶지 않아 다른 솔루션을 찾았습니다. 키는 로컬에서 태그를 삭제 한 다음 git fetch를 사용하여 원격 서버에서 "다시 가져 오기"할 수 있음을 발견했습니다. 태그가 리모컨에 없으면 삭제 된 상태로 유지됩니다.

따라서 순서대로 두 줄을 입력해야합니다.

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

이들:

  1. 로컬 저장소에서 모든 태그를 삭제하십시오. xargs는 "tag -l"의 각 태그 출력을 "tag -d"의 명령 줄에 배치합니다. 이것이 없으면 git은 stdin (silly git)을 읽지 않기 때문에 아무것도 삭제하지 않습니다.

  2. 원격 저장소에서 모든 활성 태그를 가져옵니다.

이것은 심지어 Windows에서도 잘 작동합니다.


Git v1.7.8에서 v1.8.5.6까지 다음을 사용할 수 있습니다.

git fetch <remote> --prune --tags

최신 정보

커밋 e66ef7ae6f31f2 때문에 최신 버전의 git (v1.9.0으로 시작)에서는 작동하지 않습니다 . 일부 사람들에게는 효과가 있었으므로 삭제하고 싶지 않습니다.

v1.7.8 이후의 모든 Git 버전과 함께 "Chad Juliano"에서 제안한대로 다음 명령을 사용할 수 있습니다.

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

와일드 카드 확장을 피하려면 태그 부분을 따옴표로 묶어야합니다 (예 : Windows에서).

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

리모컨에 존재하는 태그 만 원하는 경우 모든 로컬 태그를 삭제하십시오.

$ git tag -d $(git tag)

그런 다음 모든 원격 태그를 가져옵니다.

$ git fetch --tags

git fetchv1.7.8 이후의 모든 버전의 Git 은 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/e66ef7ae6f31f246dead62f574cc2acb75fd001c를 참조하십시오.


최신 버전의 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

이것은 좋은 방법입니다.

git tag -l | xargs git tag -d && git fetch -t

출처 : demisx.GitHub.io


Git은 기본적으로 로컬 태그 정리를 지원합니다.

git fetch --tags --prune

이 명령은 최신 태그를 가져 와서 삭제 된 모든 태그를 제거합니다.


로컬 태그와 원격 태그의 차이점을 보여줍니다.

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/##' 원격 태그 경로 목록에서 태그 이름 만 구문 분석합니다.
  • 마지막으로 우리는 두 목록 각각을 정렬하고 diff

"<"로 시작하는 줄은 더 이상 원격 저장소에없는 로컬 태그입니다. 그것들이 적 으면 하나씩 수동으로 제거 할 수 있고, 많으면 자동화하기 위해 더 많은 greping 및 배관을 수행합니다.


GitHub에서 git sync-local-tags 명령을 pivotal_git_scripts Gem fork에 추가했습니다.

https://github.com/kigster/git_scripts

gem을 설치 한 다음 리포지토리에서 "git sync-local-tags"를 실행하여 원격에 존재하지 않는 로컬 태그를 삭제하십시오.

또는 아래에이 스크립트를 설치하고 "git-sync-local-tags"라고 부르십시오.


#!/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)

TortoiseGit은 이제 태그를 비교할 수 있습니다.

왼쪽 로그는 원격에 있고 오른쪽은 로컬에 있습니다.

여기에 이미지 설명을 입력하십시오

동기화 대화 상자의 태그 비교 기능 사용 :

여기에 이미지 설명을 입력하십시오

TortoiseGit 문제 2973 참조


어떻습니까? 모든 로컬 태그를 삭제 한 다음 다시 가져 오십시오. 리포지토리에 하위 모듈이 포함되어 있다고 생각하면 :

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

@Richard W와 같은 대답이지만 Windows (PowerShell)

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

참고 URL : https://stackoverflow.com/questions/1841341/remove-local-git-tags-that-are-no-longer-on-the-remote-repository



반응형