[git] 힘내에서 당길 필요가 있는지 확인

원격 저장소가 변경되었는지 확인하고 풀해야합니까?

이제이 간단한 스크립트를 사용합니다.

git pull --dry-run | grep -q -v 'Already up-to-date.' && changed=1

그러나 다소 무겁습니다.

더 좋은 방법이 있습니까? 이상적인 솔루션은 모든 원격 분기를 확인하고 변경된 분기의 이름과 각 분기의 새 커밋 수를 반환합니다.



답변

먼저을 사용 git remote update하여 원격 심판을 최신 상태로 만드십시오. 그러면 다음과 같은 여러 가지 작업 중 하나를 수행 할 수 있습니다.

  1. git status -uno추적중인 지점이 앞, 뒤 또는 분기되었는지 여부를 알려줍니다. 아무 것도 말하지 않으면 로컬과 원격이 동일합니다.

  2. git show-branch *master이름이 ‘master'(예 : masterorigin / master )로 끝나는 모든 브랜치에서 커밋을 표시합니다 .

당신이 사용하는 경우 -vgit 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>있으므로 masterorigin / 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원격 브랜치의 헤드 커밋을 반환합니다. 이 명령은 원격 저장소와 통신합니다. piped cut명령은 첫 번째 필드 (커밋 해시) 만 추출하여 탭으로 구분 된 참조 문자열을 제거합니다.
  • 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