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


622

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

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

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

그러나 다소 무겁습니다.

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


14
"git pull --dry-run"은 예상대로 작동하지 않습니다. git pull은 알 수없는 옵션을 git fetch로 직접 전달하는 것으로 보입니다. 결과는 정상적인 git pull의 결과입니다.

27
"pull"은 한 번에 "fetch"및 "merge"를 수행하는 짧은 방법입니다. 원격 repo 상태를 확인해야하는 경우 실제로 "fetch"를 시뮬레이션하는 것입니다. 그래서 git fetch -v --dry-run당신이 필요로하는 것입니다.
Claudio Floreani

답변:


858

먼저을 사용 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먼저 수행 한 것으로 가정합니다 . 필자는 최근에 이미 페치했기 때문에 페치하지 않고 비교하려는 경우와 같이 가져 오기 및 비교를 별도의 작업으로 수행 할 수 있기 때문에 스크립트에 작성하지 않았습니다.


4
@takeshin @brool이 제안한대로 git ls-remote origin -h refs / heads / master를 git rev-list --max-count = 1 origin / master와 결합 할 수 있다고 생각합니다. 동일한 해시를 반환하는 경우 원격 지사를 마지막으로 업데이트 한 이후 (풀, 페치, 원격 업데이트 등) 원격 지사가 변경되지 않았습니다. 그러면 해당 컨텐츠를 풀다운 할 필요가없는 이점이 있습니다. 모든 커밋을 즉시 수행하지만 더 편리한 시간 동안 그대로 둘 수 있습니다. 그러나 원격 업데이트는 비파괴 적이므로 어쨌든 할 수 있습니다.
Neil Mayhew

2
git status -s -u no보다 더 짧은 출력을 제공하는을 시도 할 수도 있습니다 git status -u no.
Phillip Cloud

2
@mhulse, git remote -v update. git remote --help자세한 설명 은 출력을 참조하십시오 .
Neil Mayhew

1
@ChrisMaes 좋은 지적입니다. 이전 버전의 git에는보다 명확한 구문이 필요합니다. 나는 내가 가지고있는 다양한 시스템을 실험 @{u}했지만 git 1.8.3.2에서는 작동하지만 @그렇지는 않다는 것을 알았습니다 . 그러나 @와 작동합니다 1.8.5.4. 이야기의 교훈 : git은 계속 개선되고 있으며 가능한 최신 버전을 보유 할 가치가 있습니다.
Neil Mayhew

1
@에는 ​​지정자가 필요합니다. @ 대신 @ {0}을 사용할 수 있습니다.
벤 데이비스

132

업스트림 지점이있는 경우

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하는 업스트림 분기 를 암시 적으로 사용하는 대신 명시 적으로 참조하는 경우 추적 리모트가없는 기능 분기에 있어도 작동 합니다.


2
git fetch; git log HEAD.. --oneline로컬에 대한 기본 원격 브랜치가있는 경우 더 짧은 표기법도 사용할 수 있습니다.
phil pirozhkov

@philpirozhkov 만약 당신이 기본 원격 브랜치를 가지고 있다면, 간단한 "git status"가 생각되어야한다. 내 대답은 두 가지에 대한 일반적인 답변으로 다른 지점을 추적하거나 추적하지 않을 수 있습니다.
PlagueHammer

55
git rev-list HEAD...origin/master --count둘 사이에 "다른"커밋의 총 수를 제공합니다.
Jake Berger

1
짧고 간단합니다. 새로운 커밋을 보여주는 가장 좋아하는 솔루션 (두 번 엄지 손가락)
spankmaster79

(우분투) 배치 파일에서 이것을 사용하여 풀이 필요하다는 것을 나타내는 경우에만 다른 명령을 실행할 수 있습니까?
율리시스 알베스

69

스크립트 용인 경우 다음을 사용할 수 있습니다.

git fetch
$(git rev-parse HEAD) == $(git rev-parse @{u})

(참고 :이 답변과 이전 답변의 이점은 현재 분기 이름을 얻기 위해 별도의 명령이 필요하지 않다는 것입니다. "HEAD"및 "@ {u}"(현재 분기의 업스트림)가이를 처리합니다. 자세한 내용은 "git rev-parse --help"를 참조하십시오.)


@ {u}을 (를) 독립적으로 발견하고 답변을 업데이트하기 전에 답변을 업데이트했습니다.
Neil Mayhew

1
git rev-parse @{u}실제로 최신이없이 커밋 보여 git fetch?
Kyle Strand

3
이것은 티켓이었다! 그러나 논리가 =="상류에서 변경 사항이없는 경우"를 사용하고 있습니다. 내가 사용 !=확인하기 위해 내 응용 프로그램에 대한 "상류의 변경이있는 경우". git fetch먼저 잊지 마십시오 !
ChrisPrime

1
원래 질문에 대답해야하기 때문에 git fetch를 추가했습니다. btw의 @줄임말입니다 HEAD.
user1338062

Windows 사용자는 @{u}예를 들어 작은 따옴표가 필요합니다.git rev-parse '@{u}'
spuder

36

명령

git ls-remote origin -h refs/heads/master

리모컨의 현재 헤드를 나열합니다. 이전 값과 비교하거나 로컬 리포지토리에 SHA가 있는지 확인할 수 있습니다.


1
이 값을 비교할 샘플 스크립트가 있습니까?
takeshin

18
git rev-list HEAD...origin/master --count둘 사이에 "다른"커밋의 총 수를 제공합니다.
Jake Berger

3
@jberger는 명확하게, 그것은 당신이 (앞뒤가 아닌) 커밋의 수를 보여줄 것이고 당신 git fetch이나 git remote update첫 번째 경우에만 작동합니다 . git status또한 카운트, btw를 보여줍니다.
Dennis

1
@Dennis 나는 .."원본 / 마스터 커밋, HEAD 빼기"(즉, 커밋 수) 라고 생각했다 . 반면, ...는 IS 대칭 차이 (즉, 앞과 뒤)를
제이크 버거

3
우수한. 내가 알 수있는 한, 이것은 실제로 업데이트의 출처를 확인하지만 암시 적으로을 수행하지 않는 유일한 솔루션입니다 fetch.
Kyle Strand

35

다음은 현재 브랜치의 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

2
나는 것 없는 당신이 지점 이름에 슬래시를 사용하는 경우 나오지에 / g 사용합니다. "sed 's / \ // /"입니다.
Martyn Davis 5

@wjordan 원격 저장소에 접근 할 수 없거나 유지 관리 중일 때 솔루션이 실패하고 "최신"트리거
프레임

20

https://github.com/badele/gitcheck 스크립트를 참조하십시오 . 나는 당신의 모든 Git 저장소를 한 번에 체크인하기 위해이 스크립트를 코딩했으며, 누가 커밋하지 않았는지, 누가 밀거나 당기지 않았는지 보여줍니다.

샘플 결과는 다음과 같습니다.

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


6
순수한 쉘에서 다시 작성에 대한 깔끔한, 생각
올리비에 Refalo을

1
이제 도커 컨테이너에서 직접 gitcheck를 사용할 수도 있습니다 (호스트에 파일이 있음) 자세한 내용은 gitcheck github 프로젝트
Bruno Adelé

bash git-multi-repo-tooling 과 비슷한 도구입니다 . git mrepo -c보류중인 모든 커밋이 표시됩니다.
그렉

11

나는이 솔루션을 @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

귀하의 이전 의견을 참조하면 현재 시점에서 명확한 답변을 드릴 수 없습니다. 내가 그 의견을 말할 때, 나는 git의 깊이, 특히 리모컨과 diff로 뛰어 들었다. 그로부터 몇 달이 지났고 많은 지식이 내 뇌 속에 묻혀 있습니다. ;) 둘 사이의 '다른'커밋 수를 찾고 있다면 ...솔루션의 유효한 부분 인 것 같습니다.
Jake Berger

1
감사. 이것은 깨끗했다.
Shobhit Puri

10

이미 풍부하고 독창적 인 답변이 많이 있습니다. 약간의 대비를 제공하기 위해 매우 간단한 라인으로 할 수 있습니다.

# Check return value to see if there are incoming updates.
if ! git diff --quiet remotes/origin/HEAD; then
 # pull or whatever you want to do
fi

2
원래 답변에는 '!'가 부족했습니다. 경우에. 변경 사항이 없으면 git diff의 반환 값은 0입니다.
thuovila

"원격 / 원산지 / HEAD"를 "원산지 / 마스터"또는 다른 개정판으로 대체해야하지만, IMO 최고의 솔루션
Matthias Michael Engh

9

가장 좋은 방법은 다음과 같습니다.

git diff remotes/origin/HEAD

이 참조 스펙이 등록되었다고 가정하십시오. 리포지토리를 복제 한 경우 (그렇지 않으면 리포지토리가 로컬로 생성되고 원격으로 푸시 된 경우) refspec을 명시 적으로 추가해야합니다.


9

아래 스크립트는 완벽하게 작동합니다.

changed=0
git remote update && git status -uno | grep -q 'Your branch is behind' && changed=1
if [ $changed = 1 ]; then
    git pull
    echo "Updated successfully";
else
    echo "Up-to-date"
fi

6

나는 brool이 제안한 방법을 할 것입니다. 다음의 한 줄 스크립트는 마지막 커밋 된 버전의 SHA1을 가져 와서 원격 원점 중 하나와 비교하고 변경 사항이 다른 경우에만 변경 사항을 가져옵니다. 그리고 그것은 기반으로 솔루션을 더욱 경량의 git pullgit fetch.

[ `git log --pretty=%H ...refs/heads/master^` != `git ls-remote origin
-h refs/heads/master |cut -f1` ] && git pull

git 저장소가 "--depth 1"(다운로드 크기 제한)로 복제 된 경우이 명령이 실패합니다. 고칠 방법이 있다면 알고 있습니까?
Adam Ryczkowski

자식 로그는 많은 행을 반환하고 오류 "bash : [: too arguments")를 표시합니다.git rev-parse --verify HEAD
Drew Pierce

1
이것은 bash가 수행하는 간단한 문자열 비교입니다. 무언가가 실패하면 구문을 확인하는 것이 좋습니다 (즉, 잘못 입력하고 있습니다). 먼저 git log --pretty=%H ...refs/heads/master^ 마지막으로 커밋 된 버전 git ls-remote origin -h refs/heads/master |cut -f1 의 SHA1을 가져 오기 위해 실행 한 다음 실행 하여 원격 원본의 SHA1을 가져옵니다. 이 두 가지는 git 명령이며 bash와 관련이 없습니다. 대괄호 안에서 bash가하는 일은 첫 번째 명령의 출력을 두 번째 명령의 출력과 비교하는 것이며, 같으면 true를 반환하고 실행 git pull합니다.
Claudio Floreani

"동일하면 true를 반환하고 git pull"를 실행 합니다. 나는 이질적인 것을 알고 있지만, 누군가 혼란을 막기 위해 "그리고 그들이 같지 않으면 "되어야합니다 . 또한 어떤 이유로 든 첫 번째 git 명령이 작동하지 않습니다. (git에 2.4.1있습니다.) 그래서 git log --pretty=%H master | head -n1대신에 사용 하고 있습니다. 그러나 그것이 정확히 같은지 확실하지 않습니다.
xd1le

6

이 스크립트를 실행하면 현재 분기에 다음이 필요한지 테스트합니다 git pull.

#!/bin/bash

git fetch -v --dry-run 2>&1 |
    grep -qE "\[up\s+to\s+date\]\s+$(
        git branch 2>/dev/null |
           sed -n '/^\*/s/^\* //p' |
                sed -r 's:(\+|\*|\$):\\\1:g'
    )\s+" || {
        echo >&2 "Current branch need a 'git pull' before commit"
        exit 1
}

피하기 위해 Git hook pre-commit으로 두는 것이 매우 편리합니다.

Merge branch 'foobar' of url:/path/to/git/foobar into foobar

당신이 commit전에 pulling.

이 코드를 후크로 사용하려면 스크립트를 복사 / 붙여 넣기 만하면됩니다.

.git/hooks/pre-commit

chmod +x .git/hooks/pre-commit

6

코멘트에서 이것을 놓치기 쉽기 때문에 이것을 실제 게시물로 게시하고 싶습니다.

이 질문에 대한 정답과 최상의 답변은 @Jake Berger에 의해 주어졌습니다. 대단히 감사합니다. 모든 사람이 이것을 필요로하며 모든 사람들이 의견에서 이것을 놓칩니다. 따라서 여기에 어려움을 겪고있는 모든 사람들이 정답입니다.이 명령의 출력을 사용하여 git pull을 수행 해야하는지 확인하십시오. 출력이 0이면 업데이트 할 것이 없습니다.

@ stackoverflow,이 사람에게 종을 줘. 감사합니다 @ Jake Berger

git rev-list HEAD...origin/master --count will give you the total number of "different" commits between the two.  Jake Berger Feb 5 '13 at 19:23

4

git fetch (remote)원격 심판을 업데이트하기 위해 실행 하면 새로운 기능이 표시됩니다. 그런 다음 로컬 지점을 체크 아웃하면 업스트림 뒤에 있는지 여부가 표시됩니다.


나는 이미 현지 지점을 체크 아웃 했으므로 뒤에 있는지 여부를 표시하기 위해 다른 것이 필요하다고 생각합니다. 그는 git status 로이 작업을 수행 할 수 있습니다.
Neil Mayhew

사실, 리모컨을 가져온 후에도 git status마찬가지입니다.
che

1
그것은 분위기 git pull --dry-run에 있지만, 매분마다 cron 스크립트를 실행하는 것이 무겁다 고 생각합니다.
takeshin

@takeshin : 네트워크에 연결하지 않고 원격 리포지토리를 확인할 수 없습니다. 새로운 것이 없다면 fetch상태를 확인하는 것 이상을 할 수 없습니다. 원격 업데이트에 대해 매우 빠르고 가벼운 반응이 필요한 경우 일종의 알림을 원격 리포지토리에 연결하는 것이 좋습니다.
che

@takeshin : 1 분마다 원격 저장소를 확인하려면 DVCS의 요점을 놓친 것 같습니다. 전체 아이디어는 한동안 독립적으로 개발 한 다음 나중에 원활하게 통합 할 수 있도록하는 것입니다. cvs, svn, p4 등과는 다릅니다. 여기서 항상 저장소의 최신 항목을 처리해야합니다. 다른 사람이 작업하고있는 것이 정말로 필요한 경우 이메일과 같은 다른 통신 메커니즘을 사용하여 준비가되었을 때 알려야합니다.
Neil Mayhew

4

솔루션이 너무 짧고 쉬운 동안 모든 복잡한 sugestions :

#!/bin/bash

BRANCH="<your branch name>"
LAST_UPDATE=`git show --no-notes --format=format:"%H" $BRANCH | head -n 1`
LAST_COMMIT=`git show --no-notes --format=format:"%H" origin/$BRANCH | head -n 1`

git remote update
if [ $LAST_COMMIT != $LAST_UPDATE ]; then
        echo "Updating your branch $BRANCH"
        git pull --no-edit
else
        echo "No updates available"
fi

LAST_COMMIT 및 LAST_UPDATE은 항상이있는 경우에도 변경과 동일
canbax

이 솔루션은 훌륭하고 간단 git remote update합니다. 최신 오리진 커밋 정보를 얻으려면 코드 전에 실행해야합니다
ak93

git remote update앞에 git show명령을 추가 해서는 안 됩니까?
Setop

2

미리 정의 된 폴더의 모든 리포지토리를 확인하는 내 Bash 스크립트 버전은 다음과 같습니다.

https://gist.github.com/henryiii/5841984

풀 필요 및 푸시 필요와 같은 일반적인 상황을 구별 할 수 있으며 멀티 스레드이므로 페치가 한 번에 발생합니다. 끌어 오기 및 상태와 같은 몇 가지 명령이 있습니다.

경로의 폴더에 심볼릭 링크 (또는 스크립트)를 넣은 다음 git all status(등) 으로 작동합니다 . 원산지 / 마스터 만 지원하지만 다른 방법으로 편집하거나 결합 할 수 있습니다.


1
git ls-remote | cut -f1 | git cat-file --batch-check >&-

리포지토리에없는 리모콘에서 참조 된 모든 항목을 나열합니다. 이미 가지고있는 것들에 대한 원격 참조 변경 사항을 잡으려면 (예 : 이전 커밋으로 재설정) 약간 더 걸립니다.

git pack-refs --all
mine=`mktemp`
sed '/^#/d;/^^/{G;s/.\(.*\)\n.* \(.*\)/\1 \2^{}/;};h' .git/packed-refs | sort -k2 >$mine
for r in `git remote`; do 
    echo Checking $r ...
    git ls-remote $r | sort -k2 | diff -b - $mine | grep ^\<
done

1

crontab으로 작업을 추가하려면 다음과 같이하십시오.

#!/bin/bash
dir="/path/to/root"
lock=/tmp/update.lock
msglog="/var/log/update.log"

log()
{
        echo "$(date) ${1:-missing}" >> $msglog
}

if [ -f $lock ]; then
        log "Already run, exiting..."
else
        > $lock
        git -C ~/$dir remote update &> /dev/null
        checkgit=`git -C ~/$dir status`
        if [[ ! "$checkgit" =~ "Your branch is up-to-date" ]]; then
                log "-------------- Update ---------------"
                git -C ~/$dir pull &>> $msglog
                log "-------------------------------------"
        fi
        rm $lock

fi
exit 0

1

간단한 정규 표현식 사용 :

str=$(git status) 
if [[ $str =~ .*Your\ branch\ is\ behind.*by.*commits,\ and\ can\ be\ fast-forwarded ]]; then
    echo `date "+%Y-%m-%d %H:%M:%S"` "Needs pull"
else
    echo "Code is up to date"
fi

작동하지 않습니다. 자식 상태는 로컬 검사 일 뿐이므로 이미 원격 정의를 업데이트 한 경우 지점이 뒤에 있는지 여부 만 알려줍니다.
minhaz1

0

Stephen Haberman의 답변을 기반으로 한 스크립트 버전을 사용합니다.

if [ -n "$1" ]; then
    gitbin="git -C $1"
else
    gitbin="git"
fi

# Fetches from all the remotes, although --all can be replaced with origin
$gitbin fetch --all
if [ $($gitbin rev-parse HEAD) != $($gitbin rev-parse @{u}) ]; then
    $gitbin rebase @{u} --preserve-merges
fi

이 스크립트를 호출 하면 로컬 Git 리포지토리 git-fetch-and-rebase의 선택적 인수로 호출 directory name하여 작업을 수행 할 수 있습니다. 스크립트가 인수없이 호출되면 현재 디렉토리가 Git 저장소의 일부라고 가정합니다.

예 :

# Operates on /abc/def/my-git-repo-dir
git-fetch-and-rebase /abc/def/my-git-repo-dir

# Operates on the Git repository which the current working directory is part of
git-fetch-and-rebase

여기 에서도 사용할 수 있습니다 .


0

많은 답변과 여러 게시물을 읽은 후 반나절을 다양한 순열을 시도한 후에 이것이 내가 생각해 낸 것입니다.

Windows를 사용하는 경우 Windows 용 Git (설치 또는 휴대용)에서 제공하는 Git Bash를 사용하여 Windows에서이 스크립트를 실행할 수 있습니다.

이 스크립트에는 인수가 필요합니다

-로컬 경로 (예 : / d / source / project1)
-Git URL (예 : https : //username@bitbucket.org/username/project1.git)
-비밀번호

명령 행에 비밀번호를 일반 텍스트로 입력하지 않아야하는 경우,
그런 다음 스크립트를 수정하여 GITPASS가 비어 있는지 확인하십시오. 하지 마라
암호를 바꾸고 Git에게 프롬프트하도록하라

스크립트는

- Find the current branch
- Get the SHA1 of the remote on that branch
- Get the SHA1 of the local on that branch
- Compare them.

스크립트가 인쇄 한대로 변경 사항이 있으면 가져 오기 또는 가져 오기를 진행할 수 있습니다. 스크립트가 효율적이지 않을 수도 있지만 작업이 완료됩니다.

업데이트-2015-10-30 : 암호가 포함 된 URL을 콘솔에 인쇄하지 못하도록 stderr을 null로 설정했습니다.

#!/bin/bash

# Shell script to check if a Git pull is required.

LOCALPATH=$1
GITURL=$2
GITPASS=$3

cd $LOCALPATH
BRANCH="$(git rev-parse --abbrev-ref HEAD)"

echo
echo git url = $GITURL
echo branch = $BRANCH

# Bash replace - replace @ with :password@ in the GIT URL
GITURL2="${GITURL/@/:$GITPASS@}"
FOO="$(git ls-remote $GITURL2 -h $BRANCH 2> /dev/null)"
if [ "$?" != "0" ]; then
  echo cannot get remote status
  exit 2
fi
FOO_ARRAY=($FOO)
BAR=${FOO_ARRAY[0]}
echo [$BAR]

LOCALBAR="$(git rev-parse HEAD)"
echo [$LOCALBAR]
echo

if [ "$BAR" == "$LOCALBAR" ]; then
  #read -t10 -n1 -r -p 'Press any key in the next ten seconds...' key
  echo No changes
  exit 0
else
  #read -t10 -n1 -r -p 'Press any key in the next ten seconds...' key
  #echo pressed $key
  echo There are changes between local and remote repositories.
  exit 1
fi

0

이 질문을 끝내는 Windows 사용자를 위해이 답변을 powershell 스크립트로 수정했습니다. 필요에 따라 조정하고 .ps1파일에 저장 한 후 필요 에 따라 실행하거나 원하는 경우 예약하십시오.

cd C:\<path to repo>
git remote update                           #update remote
$msg = git remote show origin               #capture status
$update = $msg -like '*local out of date*'
if($update.length -gt 0){                   #if local needs update
    Write-Host ('needs update')
    git pull
    git reset --hard origin/master
    Write-Host ('local updated')
} else {
    Write-Host ('no update needed')
}

0

Neils의 답변이 도움이 되었기 때문에 여기에 의존성이없는 Python 번역이 있습니다.

import os
import logging
import subprocess

def check_for_updates(directory:str) -> None:
    """Check git repo state in respect to remote"""
    git_cmd = lambda cmd: subprocess.run(
        ["git"] + cmd,
        cwd=directory,
        stdout=subprocess.PIPE,
        check=True,
        universal_newlines=True).stdout.rstrip("\n")

    origin = git_cmd(["config", "--get", "remote.origin.url"])
    logging.debug("Git repo origin: %r", origin)
    for line in git_cmd(["fetch"]):
        logging.debug(line)
    local_sha = git_cmd(["rev-parse", "@"])
    remote_sha = git_cmd(["rev-parse", "@{u}"])
    base_sha = git_cmd(["merge-base", "@", "@{u}"])
    if local_sha == remote_sha:
        logging.info("Repo is up to date")
    elif local_sha == base_sha:
        logging.info("You need to pull")
    elif remote_sha == base_sha:
        logging.info("You need to push")
    else:
        logging.info("Diverged")

check_for_updates(os.path.dirname(__file__))

hth


-5

또한 지금이를 수행 하는 Phing 스크립트 를 찾을 수 있습니다 .

프로덕션 환경을 자동으로 업데이트 할 수있는 솔루션이 필요했으며이 스크립트 덕분에 매우 기쁩니다.

스크립트는 XML로 작성되었으며 Phing이 필요 합니다 .


어쩌면 여기에 스크립트를 붙여 넣어 복사하는 것이 좋지 않을 수도 있습니다. 여전히 업데이트 중입니다 ...
Pol Dellaiera
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.