Program Club

리모컨없이 모든 로컬 브랜치 나열

proclub 2020. 11. 3. 19:27
반응형

리모컨없이 모든 로컬 브랜치 나열


문제점 : 리모컨이없는 모든 로컬 브랜치를 삭제하는 방법을 원합니다. 브랜치의 이름을으로 파이프하는 것은 간단 git branch -D {branch_name}하지만 처음에 그 목록을 어떻게 얻습니까?

예를 들면 :

리모컨없이 새 분기를 만듭니다.

$ git co -b no_upstream

내 모든 지점을 나열 해, 리모컨이있는 지점은 1 개뿐

$ git branch -a
master
* no_upstream
remotes/origin/HEAD -> origin/master
remotes/origin/master

no_upstream을 얻기 위해 어떤 명령을 실행할 수 있습니까?

실행할 git rev-parse --abbrev-ref --symbolic-full-name @{u}수 있으며 리모컨이 없음을 보여줍니다.

$ git rev-parse --abbrev-ref --symbolic-full-name @{u}
error: No upstream configured for branch 'no_upstream'
error: No upstream configured for branch 'no_upstream'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

그러나 이것은 오류이기 때문에 그것을 사용하거나 다른 명령으로 파이프 할 수 없습니다. 나는 이것을 쉘 스크립트 별칭으로 사용 git-delete-unbranched하거나 아마도 매우 간단한 Gem을 만들려고합니다.git-branch-delete-orphans


나는 최근 git branch -vvgit branch명령 의 "매우 장황한"버전을 발견했습니다 .

원격 분기가있는 경우 다음 형식으로 분기와 함께 분기를 출력합니다.

  25-timeout-error-with-many-targets    206a5fa WIP: batch insert
  31-target-suggestions                 f5bdce6 [origin/31-target-suggestions] Create target suggestion for team and list on save
* 54-feedback-link                      b98e97c [origin/54-feedback-link] WIP: Feedback link in mail
  65-digest-double-publish              2de4150 WIP: publishing-state

이 정중하게 형식화 된 출력이 있으면, 그것을 통해 파이프로 쉽게 cutawk목록을 얻을 :

git branch -vv | cut -c 3- | awk '$3 !~/\[/ { print $1 }'

결과는 다음과 같습니다.

25-timeout-error-with-many-targets
65-digest-double-publish

cut부분은 (포함 처음 두 문자를 제거함으로써 데이터를 정상화 *로 전달하기 전에 출력을 행) awk.

awk세 번째 열에 대괄호가 없으면 해당 부분은 첫 번째 열을 인쇄합니다.

보너스 : 별칭 만들기

전역 .gitconfig파일 (또는 어디에서나)에 별칭을 만들어 쉽게 실행할 수 있습니다 .

[alias]
  local-branches = !git branch -vv | cut -c 3- | awk '$3 !~/\\[/ { print $1 }'

중요 : 백 슬래시는 별칭에서 이스케이프 처리해야합니다. 그렇지 않으면 잘못된 gitconfig 파일이 생성됩니다.

보너스 : 원격 필터링

어떤 이유로 서로 다른 지점에 대해 여러 개의 추적 리모컨이있는 경우 확인할 리모컨을 지정하는 것이 쉽습니다. awk 패턴에 원격 이름을 추가하기 만하면됩니다. 제 경우에는 origin이렇게 할 수 있습니다.

git branch -vv | cut -c 3- | awk '$3 !~/\[origin/ { print $1 }'

git branch (옵션없이) 로컬 브랜치 만 나열하지만 원격 브랜치를 추적하는지 여부는 알 수 없습니다.

일반적으로 이러한 로컬 브랜치는 다음으로 병합되면 삭제되어야합니다 master( 이 git-sweep 문제 에서 볼 수 있음 ).

git branch --merged master | grep -v master | xargs git branch -d

이것은 당신이 원하는만큼 완전하지는 않지만 시작입니다.

를 사용하면 --merged명명 된 커밋에 병합 된 분기 (즉, 명명 된 커밋에서 팁 커밋에 도달 할 수있는 분기) 만 나열됩니다.


비슷한 문제가 있습니다. 이제 삭제 된 원격 분기를 추적하던 모든 로컬 분기를 제거하고 싶습니다. 나는 git remote prune origin내가 원하는 가지를 제거하기에 불충분하다는 것을 알고 있습니다. 리모컨이 삭제되면 로컬도 삭제하고 싶습니다. 나를 위해 일한 것은 다음과 같습니다.

~/.gitconfig:

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -d

편집 : 요청한대로 다음과 같이 git config --global ...쉽게 추가 할 수 있는 명령이 있습니다 git prune-branches.

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

참고 : 나는 변경 -d-D내가 망할 놈의 병합 지점에 대해 불평을 듣고 싶지 않기 때문에 내 실제 설정에. 이 기능도 원할 있습니다 . 그렇다면 해당 명령의 끝에 -D대신 사용 -d하십시오.

또한 FWIW, 전역 구성 파일은 거의 항상 ~/.gitconfig.

EDIT:(OSX Fix) As written, this does not work on OSX because of the use of xargs -r (thanks, Korny).

The -r is to prevent xargs from running git branch -d with no branch name, which will result in an error message "fatal: branch name required". If you don't mind the error message, you can simply remove the -r argument to xargs and you're all set.

However, if you don't want to see an error message (and really, who could blame you) then you'll need something else that checks for an empty pipe. If you might be able to use ifne from moreutils. You would insert ifne before xargs, which will stop xargs from running with empty data. NOTE: ifne considers anything to be not empty, this includes blank lines, so you may still see that error message. I've not tested this on OSX.

Here is that git config line with ifne:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | ifne xargs git branch -d'

Late edit: better is

git for-each-ref  --format='%(refname:short) %(upstream)'  refs/heads \
| awk '$2 !~/^refs\/remotes/'

on GNU/anything

for b in `git branch|sed s,..,,`; do
    git config --get branch.$b.remote|sed Q1 && echo git branch -D $b
done

If more than a handful of branches were likely there'd be better ways, using comm -23 on the output of git branch|sed|sort and git config -l|sed|sort.


This works for me:

git branch -vv | grep -v origin

(if your remote is named anything other than origin, substitute that).

This will list all the branches that aren't tracking a remote, which sounds like what you're looking for.


Rough powershell implementation: (if origin is your only remote)

@($branches = git br -r; git branch | %{ echo $_ | sed 's/..//' }) `
   | %{ if (($branches | ss "origin/$_") -eq $null) { `
          echo "git branch -D $_" `
        } `
      }

Here is something I have used in PowerShell with comments to explain what it's doing. In an attempt to make it clear what's going on, I've not used any abbreviated PS commands. Feel free to compress it to your desired level of crypticness :)

$verboseList = @(git br -vv)
foreach ($line in $verboseList)
{    
    #get the branch name
    $branch = [regex]::Match($line, "\s(\S+)\s").Captures.Groups[1].Value
    #check if the line contains text to indicate if the remote is deleted
    $remoteGone = $line.Contains(": gone]")
    #check if the line does not contain text to indicate it is a tracking branch (i.e., it's local)
    $isLocal = !($line.Contains("[origin/"))
    if ($remoteGone -or $isLocal)
    {
        #print the branch name
        $branch
    }
}

I sinthetize my own git command to get the origin/***: gone branches:

git remote prune origin && git branch -vv | cut -c 3- | grep ': gone]' | awk '{print $1}' | xargs -n1 -r echo git branch -d

git remote prune origin && git branch -vv will print branches in verbose mode

cut -c 3- will remove very first chars

grep ': gone]' will print only the gone remote branches

awk '{print $1}' will print the branch name

xargs -n1 -r echo git branch -d will print the git branch -d command to remove branches (-n1 will manage one command per time, -r to avoid issuing command if no branch is present)

HINT: remove the "echo" command to run the commands instead of print only, I left this in the command to check commands before issuing to git.

HINT 2: issue git branch -D if and only if you are sure you want to remove unmerged branches

참고URL : https://stackoverflow.com/questions/15661853/list-all-local-branches-without-a-remote

반응형