bash 스크립트를 사용하여 모든 git 브랜치를 반복하는 방법
bash 스크립트를 사용하여 저장소 내의 모든 로컬 브랜치를 반복하려면 어떻게 해야 합니까?지점과 원격지점에 차이가 있는지 다시 한 번 확인해 봐야 합니다.예
for branch in $(git branch);
do
git log --oneline $branch ^remotes/origin/master;
done
위와 같은 작업을 수행해야 하는데, 현재 직면한 문제는 $(git branch)가 저장소에 있는 분기와 함께 저장소 폴더 내의 폴더를 제공한다는 것입니다.
이것이 이 문제를 해결하는 올바른 방법입니까?아니면 다른 방법이 있을까요?
감사해요.
스크립트를 작성할 때 git branch를 사용하면 안 됩니다.Git은 스크립팅에 사용하도록 명시적으로 설계된 "플럼핑" 인터페이스를 제공합니다(일반 Git 명령어(추가, 체크아웃, 병합 등)의 현재 및 과거 구현된 많은 것들이 이 동일한 인터페이스를 사용합니다).
필요한 배관 명령어는 git for each-ref 입니다.
git for-each-ref --shell \
--format='git log --oneline %(refname) ^origin/master' \
refs/heads/
의: 다음음음음음 note note note note note note note note note note 는 필요 없습니다.remotes/
(다른 한에 프레픽스).origin/master
참조 이름 검색 경로에서 여러 위치를 일치시키려면 "심볼릭 참조 이름"을 참조하십시오...."는 git-rev-parse(1)의 "수정사항 지정" 섹션에 있습니다.애매함을 명확하게 회피하려면 , 완전한 참조명을 사용합니다.refs/remotes/origin/master
다음과 같은 출력이 표시됩니다.
git log --oneline 'refs/heads/master' ^origin/master
git log --oneline 'refs/heads/other' ^origin/master
git log --oneline 'refs/heads/pu' ^origin/master
이 출력을 sh로 파이핑할 수 있습니다.
셸 코드를 생성하는 것이 마음에 들지 않는 경우는, 조금의* 견고성을 포기하고, 다음과 같이 할 수 있습니다.
for branch in $(git for-each-ref --format='%(refname)' refs/heads/); do
git log --oneline "$branch" ^origin/master
done
* 참조명은 셸의 단어 분할로부터 안전해야 합니다(git-check-ref-format(1) 참조).개인적으로 나는 이전 버전(생성된 셸 코드)을 고수하고 싶다.나는 그것으로는 부적절한 일이 일어날 수 없다는 것을 더 확신한다.
bash를 지정하고 어레이를 지원하므로 안전을 유지하면서 루프의 내장이 생성되지 않도록 할 수 있습니다.
branches=()
eval "$(git for-each-ref --shell --format='branches+=(%(refname))' refs/heads/)"
for branch in "${branches[@]}"; do
# …
done
해서 이렇게 할 도 있어요.$@
하지 않는 (어레이를 지원하지 않는 경우).set --
set -- "$@" %(refname)
요소를 추가합니다).
그 이유는git branch
는 현재 브랜치에 아스타리스크 마크를 붙입니다.하다
$ git branch
* master
mybranch
$
$(git branch)
장됩니니다다* master mybranch
그에 , 이에요.*
현재 디렉토리의 파일 목록으로 확장됩니다.
애초에 아스타리스크를 인쇄하지 않는 방법은 잘 모르겠습니다만, 잘라내도 괜찮습니다.
$(git branch | cut -c 3-)
빌트인 " " " "mapfile
되어 있습니다.
브랜치: "git git" :git branch --all --format='%(refname:short)'
브랜치: "GIT 브랜치: " "GIT 브랜치"git branch --format='%(refname:short)'
브런치: branches든 all GIT 브 branches :git branch --remotes --format='%(refname:short)'
브랜치를 합니다.mapfile -t -C my_callback -c 1 < <( get_branches )
예:
my_callback () {
INDEX=${1}
BRANCH=${2}
echo "${INDEX} ${BRANCH}"
}
get_branches () {
git branch --all --format='%(refname:short)'
}
# mapfile -t -C my_callback -c 1 BRANCHES < <( get_branches ) # if you want the branches that were sent to mapfile in a new array as well
# echo "${BRANCHES[@]}"
mapfile -t -C my_callback -c 1 < <( get_branches )
OP의 특정 상황:
#!/usr/bin/env bash
_map () {
ARRAY=${1?}
CALLBACK=${2?}
mapfile -t -C "${CALLBACK}" -c 1 <<< "${ARRAY[@]}"
}
get_history_differences () {
REF1=${1?}
REF2=${2?}
shift
shift
git log --oneline "${REF1}" ^"${REF2}" "${@}"
}
has_different_history () {
REF1=${1?}
REF2=${2?}
HIST_DIFF=$( get_history_differences "${REF1}" "${REF2}" )
return $( test -n "${HIST_DIFF}" )
}
print_different_branches () {
read -r -a ARGS <<< "${@}"
LOCAL=${ARGS[-1]?}
for REMOTE in "${SOME_REMOTE_BRANCHES[@]}"; do
if has_different_history "${LOCAL}" "${REMOTE}"; then
# { echo; echo; get_history_differences "${LOCAL}" "${REMOTE}" --color=always; } # show differences
echo local branch "${LOCAL}" is different than remote branch "${REMOTE}";
fi
done
}
get_local_branches () {
git branch --format='%(refname:short)'
}
get_different_branches () {
_map "$( get_local_branches )" print_different_branches
}
# read -r -a SOME_REMOTE_BRANCHES <<< "${@}" # use this instead for command line input
declare -a SOME_REMOTE_BRANCHES
SOME_REMOTE_BRANCHES=( origin/master remotes/origin/another-branch another-remote/another-interesting-branch )
DIFFERENT_BRANCHES=$( get_different_branches )
echo "${DIFFERENT_BRANCHES}"
출처: 별표 없이 모든 로컬 git 브랜치를 나열합니다.
예를 들어 다음과 같이 반복합니다.
for BRANCH in `git branch --list|sed 's/\*//g'`;
do
git checkout $BRANCH
git fetch
git branch --set-upstream-to=origin/$BRANCH $BRANCH
done
git checkout master;
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads); do
...
done
이것은 스크립트용으로 설계된 git compensing 명령을 사용합니다.또한 심플하고 표준적입니다.
레퍼런스:Git의 Bash 완료
단순하게 받아들여라.
bash 스크립트를 사용하여 분기 이름을 루프로 가져오는 간단한 방법입니다.
#!/bin/bash
for branch in $(git for-each-ref --format='%(refname)' refs/heads/); do
echo "${branch/'refs/heads/'/''}"
done
출력:
master
other
$(git branch|grep -o "[0-9A-Za-z]\+")
가 숫자, A-Z 로만 명명된 , a-z "/" A-Z " " "
인정된 답변은 정확하고 실제로 사용되는 접근법이어야 하지만, bash에서 문제를 해결하는 것은 셸이 어떻게 작동하는지 이해하는 데 있어 훌륭한 연습입니다.추가 텍스트 조작을 수행하지 않고 bash를 사용하여 이를 수행하는 비결은 셸에 의해 실행되는 명령의 일부로 git 분기의 출력이 확장되지 않도록 하는 것입니다.이것에 의해, 셸 확장의 파일명 전개(스텝 8)로 아스타리스크가 전개되는 것을 막을 수 있습니다(http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html) 참조).
git 브랜치 출력을 행으로 자르려면 read 명령을 사용하여 bash while constructure를 사용합니다.'*'는 리터럴 문자로 읽힙니다.일치하는 패턴에 특히 주의하면서 대/소문자를 사용하여 일치시킵니다.
git branch | while read line ; do
case $line in
\*\ *) branch=${line#\*\ } ;; # match the current branch
*) branch=$line ;; # match all the other branches
esac
git log --oneline $branch ^remotes/origin/master
done
bash 케이스 구성 및 파라미터 치환 양쪽의 아스타리스크는 백슬래시로 이스케이프하여 셸이 패턴 매칭 문자로 해석하지 않도록 해야 합니다.문자 그대로 '*'와 일치하기 때문에 (토큰화를 방지하기 위해) 공백도 이스케이프됩니다.
내 생각에 가장 기억하기 쉬운 방법:
git branch | grep "[^* ]+" -Eo
출력:
bamboo
develop
master
Grep의 -o 옵션(--only-matching)은 출력을 입력과 일치하는 부분만 제한합니다.
Git 브랜치 이름에는 공백과 *가 모두 유효하지 않기 때문에 추가 문자가 없는 브랜치 목록이 반환됩니다.
편집: 'detached head' 상태인 경우 현재 항목을 필터링해야 합니다.
git branch --list | grep -v "HEAD detached" | grep "[^* ]+" -oE
결국 가 하게 된 것은 ccpizza가 ccpizza에서 ).tr
):
git branch | tr -d ' *' | while IFS='' read -r line; do git log --oneline "$line" ^remotes/origin/master; done
(루프를 많이 하는 편입니다.특정 사항에는 반드시 포인트 변수 이름 [예를 들어 분기]를 사용해야 하지만 대부분의 경우 저는 각 입력 행에 대해 무언가를 수행하는 데만 관심이 있습니다.여기서 '브런치'가 아닌 '라인'을 사용하는 것은 재사용 가능성/근육 기억력/효율성에 동의하는 것입니다.)
Googlian의 답변, 하지만 다음 질문에 대해서는 사용하지 않습니다.
git for-each-ref --format='%(refname:lstrip=-1)' refs/heads/
이 상태일 경우:
git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/branch1
remotes/origin/branch2
remotes/origin/branch3
remotes/origin/master
이 코드를 실행합니다.
git branch -a | grep remotes/origin/*
for BRANCH in `git branch -a | grep remotes/origin/*` ;
do
A="$(cut -d'/' -f3 <<<"$BRANCH")"
echo $A
done
다음과 같은 결과를 얻을 수 있습니다.
branch1
branch2
branch3
master
로컬 브랜치명을 간단하게 반복하는 올바른 방법은for-each-ref
에 걸쳐서refs/heads/
. 예:
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/); do
echo branch="${branch}"
done
이것은 다음 표준/기본값으로 동작합니다.IFS
git의 지점 이름에는 공백이 불법이기 때문입니다.
드디어 출력 방법을 확정했습니다.git branch
별표도 없고 마법도 없이git for-each-ref
인수:
$ git branch --format="%(refname:short)"
이게 왜 가치 있는 거죠? git branch
명령어에는 다음과 같은 추가 필터가 있습니다.--merged
를 사용하여 구현하기가 쉽지 않습니다.git for-each-ref
(적어도 내가 보기엔)
@finn의 답변(감사합니다!)에서 확장하면, 다음은 개입하는 셸 스크립트를 작성하지 않고 브랜치상에서 반복할 수 있습니다.브랜치명에 새로운 행이 없는 한, 충분히 견고합니다. : )
git for-each-ref --format='%(refname)' refs/heads | while read x ; do echo === $x === ; done
while 루프는 서브셸에서 실행됩니다.이는 현재 셸에서 액세스하려는 셸 변수를 설정하지 않는 한 일반적으로 문제가 없습니다.이 경우 프로세스 치환을 사용하여 파이프를 반전시킵니다.
while read x ; do echo === $x === ; done < <( git for-each-ref --format='%(refname)' refs/heads )
로컬 저장소에 헤드(브런치) 나열
git show-ref --heads
git show-ref
- 로컬 저장소에 참조 목록 표시--heads
유일한 리스트heads
(태그 없음)
이렇게 하면 앞면이 표시됩니다.
682e47c01dc8d0f4e4102f183190a48aaf34a3f0 refs/heads/main
....
그래서 이름에만 관심이 있다면 이런 걸 쓸 수 있어요.sed
원하는 결과를 얻기 위해
git show-ref --heads | sed 's/.*refs\/heads\///'
나뭇가지 사이를 반복하다
이 출력으로 쉽게 반복할 수 있습니다. 예를 들어 배쉬 루프, xargs 등 보트가 뜨는 모든 것을 사용할 수 있습니다.
for SHA in $(git show-ref --heads | awk '{ print $1 }'); do
echo "magic! $SHA"
done
git show-ref --heads
위와 같이 가지를 받다awk '{ print $1 }'
SHA를 취득하다echo "magic! $SHA"
여기가 마법을 부릴 곳이야
물론 이론적으로는 Git이 스크립팅할 때 실제로 사용하는 특별한 인터페이스를 사용해야 한다.하지만 종종 오넬라이너에게 편리한 심플한 것을 원합니다.git for each-ref --format … refs … amen 등의 내용을 기억하도록 재촉하지 않는 것.결국 UNIX가 되었습니다.그 후, 다음과 같이 됩니다.
- 마지막 칼럼을 인쇄하는 방법은 모호하지만 간결하기로 널리 알려진 유틸리티가 있습니다.
git branch
는 지점명 앞에 아스타리스크를 붙입니다.그 말은 우리가 항상 마지막 칼럼에 정확히 관심이 있다는 뜻이죠
결과:
git branch | awk '{print $NF}'
것은 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 맞다.'awk
변수가 .NF
마지막 필드의 번호입니다.을 붙입니다.$
그 들 마녀의 내용물이 바로 여기에 필요한 것이다.
#/bin/bash
for branch in $(git branch -r);
do
echo $branch
done
언급URL : https://stackoverflow.com/questions/3846380/how-to-iterate-through-all-git-branches-using-bash-script
'source' 카테고리의 다른 글
MVVM을 사용하는 wpf의 대화상자에 대한 바람직한 방법 또는 나쁜 방법? (0) | 2023.04.14 |
---|---|
Excel에서 번다운 차트를 작성하려면 어떻게 해야 하나요? (0) | 2023.04.14 |
취소선 텍스트를 사용하여 UILabel을 작성하려면 어떻게 해야 합니까? (0) | 2023.04.14 |
Value Conversion Attribute 클래스의 포인트? (0) | 2023.04.14 |
SQL Server:CLR이 활성화 되어 있는지 확인하려면 어떻게 해야 합니다. (0) | 2023.04.14 |