원격 저장소가 변경되었는지 확인하고 풀해야합니까?
이제이 간단한 스크립트를 사용합니다.
git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1
그러나 다소 무겁습니다.
더 좋은 방법이 있습니까? 이상적인 솔루션은 모든 원격 분기를 확인하고 변경된 분기의 이름과 각 분기의 새 커밋 수를 반환합니다.
답변
먼저을 사용 git remote update
하여 원격 심판을 최신 상태로 만드십시오. 그러면 다음과 같은 여러 가지 작업 중 하나를 수행 할 수 있습니다.
-
git status -uno
추적중인 지점이 앞, 뒤 또는 분기되었는지 여부를 알려줍니다. 아무 것도 말하지 않으면 로컬과 원격이 동일합니다. -
git show-branch *master
이름이 ‘master'(예 : master 및 origin / master )로 끝나는 모든 브랜치에서 커밋을 표시합니다 .
당신이 사용하는 경우 -v
에 git remote update
( git remote -v update
당신이 정말로 더 이상 명령을 필요가 없습니다) 당신은 가지가 업데이트되었다 확인할 수 있습니다.
그러나 스크립트 또는 프로그램 에서이 작업을 수행하고 true / false 값으로 끝나는 것처럼 보입니다. 그렇다면 현재 HEAD 커밋과 추적중인 지점의 헤드 사이의 관계를 확인할 수있는 방법이 있지만 네 가지 가능한 결과가 있기 때문에 예 / 아니오로 줄일 수는 없습니다. 그러나, 준비가 되었다면 pull --rebase
“local is behind”와 “local has diverted”을 “need to need”로 취급하고 다른 두 개는 “tull을 가져올 필요가 없다”고 취급 할 수 있습니다.
를 사용하여 심판의 커밋 ID를 얻을 수 git rev-parse <ref>
있으므로 master 및 origin / master에 대해이 작업을 수행 하고 비교할 수 있습니다. 동일하면 가지가 동일합니다. 그들이 동일하지 않으면, 당신은 어느 것이 다른 것보다 앞서 있는지 알고 싶습니다. 를 사용 git merge-base master origin/master
하면 두 가지의 공통 조상을 알 수 있으며 분기되지 않은 경우 둘 중 하나와 동일합니다. 세 가지 다른 ID를 얻으면 가지가 분기 된 것입니다.
예를 들어 스크립트에서이 작업을 올바르게 수행하려면 현재 분기 및 추적중인 원격 분기를 참조 할 수 있어야합니다. bash 프롬프트 설정 기능 /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}'}
분기에 대해 구성된 것과 다른 원격 분기를 검사하려는 경우 선을 통해 선택적으로 업스트림 분기를 명시 적으로 전달할 수 있습니다. 일반적으로 remotename / branchname 형식 입니다. 매개 변수를 지정하지 않으면 기본값은 @{u}
입니다.
스크립트는 추적 분기를 최신 상태로 유지하기 위해 git fetch
또는 git remote update
먼저 수행 한 것으로 가정합니다 . 필자는 최근에 이미 페치했기 때문에 페치하지 않고 비교하려는 경우와 같이 가져 오기 및 비교를 별도의 작업으로 수행 할 수 있기 때문에 스크립트에 작성하지 않았습니다.
답변
업스트림 지점이있는 경우
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
병합 할 것이 없습니다.
Git에서 기억 origin/master
하는 업스트림 분기 를 암시 적으로 사용하는 대신 명시 적으로 참조하는 경우 추적 리모트가없는 기능 분기에 있어도 작동 합니다.
답변
스크립트 용인 경우 다음을 사용할 수 있습니다.
git fetch
$(git rev-parse HEAD) == $(git rev-parse @{u})
(참고 :이 답변과 이전 답변의 이점은 현재 분기 이름을 얻기 위해 별도의 명령이 필요하지 않다는 것입니다. “HEAD”및 “@ {u}”(현재 분기의 업스트림)가이를 처리합니다. 자세한 내용은 “git rev-parse –help”를 참조하십시오.)
답변
명령
git ls-remote origin -h refs/heads/master
리모컨의 현재 헤드를 나열합니다. 이전 값과 비교하거나 로컬 리포지토리에 SHA가 있는지 확인할 수 있습니다.
답변
다음은 현재 브랜치의 HEAD 커밋 해시를 원격 업스트림 브랜치와 비교 git fetch
하거나 무거운 git pull --dry-run
작업이 필요 없는 Bash one-liner입니다 .
[ $(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)
Bash 명령 대체 구문을 사용하여 그룹화되고 중첩됩니다 . git rev-parse --abbrev-ref @{u}
축약 된 업스트림 참조 (예 :)를 반환 한origin/master
다음 파이프sed
명령에 의해 공백으로 구분 된 필드로 변환됩니다 (예 🙂origin master
.- 이 문자열은
git ls-remote
원격 브랜치의 헤드 커밋을 반환합니다. 이 명령은 원격 저장소와 통신합니다. pipedcut
명령은 첫 번째 필드 (커밋 해시) 만 추출하여 탭으로 구분 된 참조 문자열을 제거합니다. git rev-parse HEAD
로컬 커밋 해시를 반환합니다.- Bash 구문
[ a = b ] && x || y
은 one-liner를 완성합니다. 이것은 테스트 구문 내의 Bash 문자열 비교 와 and-list 및 or-list 구문 입니다.=
[ test ]
&& true || false
답변
https://github.com/badele/gitcheck 스크립트를 참조하십시오 . 나는 당신의 모든 Git 저장소를 한 번에 체크인하기 위해이 스크립트를 코딩했으며, 누가 커밋하지 않았는지, 누가 밀거나 당기지 않았는지 보여줍니다.
샘플 결과는 다음과 같습니다.
답변
나는이 솔루션을 @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