Check if pull needed in Git

后端 未结 24 1289
忘了有多久
忘了有多久 2020-11-22 13:34

How do I check whether the remote repository has changed and I need to pull?

Now I use this simple script:

git pull --dry-run | grep -q -v \'Already          


        
相关标签:
24条回答
  • 2020-11-22 13:57

    After reading many answers and multiple posts, and spending half a day trying various permutations, this is what I have come up with.

    If you are on Windows, you may run this script in Windows using Git Bash provided by Git for Windows (installation or portable).

    This script requires arguments

    - local path e.g. /d/source/project1
    - Git URL e.g. https://username@bitbucket.org/username/project1.git
    - password
    
    if a password should not be entered on the command line in plain text,
    then modify the script to check if GITPASS is empty; do not
    replace and let Git prompt for a password
    

    The script will

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

    If there is a change as printed by the script, then you may proceed to fetch or pull. The script may not be efficient, but it gets the job done for me.

    Update - 2015-10-30: stderr to dev null to prevent printing the URL with the password to the console.

    #!/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 讨论(0)
  • 2020-11-22 13:57

    For the windows users who end up on this question looking for this, I've modified some of the answer into a powershell script. Tweak as necessary, save to a .ps1 file and run on demand or scheduled if you like.

    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 讨论(0)
  • 2020-11-22 13:59

    The command

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

    will list the current head on the remote -- you can compare it to a previous value or see if you have the SHA in your local repo.

    0 讨论(0)
  • 2020-11-22 13:59

    Using simple regexp:

    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
    
    0 讨论(0)
  • 2020-11-22 14:02

    Here's a Bash one-liner that compares the current branch's HEAD commit hash against its remote upstream branch, no heavy git fetch or git pull --dry-run operations required:

    [ $(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
    

    Here's how this somewhat dense line is broken down:

    • Commands are grouped and nested using $(x) Bash command-substitution syntax.
    • git rev-parse --abbrev-ref @{u} returns an abbreviated upstream ref (e.g. origin/master), which is then converted into space-separated fields by the piped sed command, e.g. origin master.
    • This string is fed into git ls-remote which returns the head commit of the remote branch. This command will communicate with the remote repository. The piped cut command extracts just the first field (the commit hash), removing the tab-separated reference string.
    • git rev-parse HEAD returns the local commit hash.
    • The Bash syntax [ a = b ] && x || y completes the one-liner: this is a Bash string-comparison = within a test construct [ test ], followed by and-list and or-list constructs && true || false.
    0 讨论(0)
  • 2020-11-22 14:03

    I would do the way suggested by brool. The following one-line script takes the SHA1 of your last commited version and compares it to the one of the remote origin, and pull changes only if they differ. And it's even more light-weight of the solutions based on git pull or git fetch.

    [ `git log --pretty=%H ...refs/heads/master^` != `git ls-remote origin
    -h refs/heads/master |cut -f1` ] && git pull
    
    0 讨论(0)
提交回复
热议问题