Controlla se è necessario pull in Git


623

Come posso verificare se il repository remoto è stato modificato e devo estrarlo?

Ora uso questo semplice script:

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

Ma è piuttosto pesante.

Esiste un modo migliore? La soluzione ideale dovrebbe controllare tutti i rami remoti e restituire i nomi dei rami modificati e il numero di nuovi commit in ognuno.


14
Nota: "git pull --dry-run" non funziona come probabilmente previsto. Sembra che git pull passi direttamente opzioni sconosciute a git fetch. Il risultato è quello di una normale git pull.

27
"pull" è solo un modo breve per eseguire "fetch" e "unire" in una volta, se è necessario controllare lo stato del repository remoto si sta davvero simulando un "fetch". Quindi git fetch -v --dry-runè quello che ti serve.
Claudio Floreani,

Risposte:


859

Primo utilizzo git remote update, per aggiornare i riferimenti remoti. Quindi puoi fare una delle diverse cose, come ad esempio:

  1. git status -unoti dirà se il ramo che stai seguendo è avanti, indietro o divergente. Se non dice nulla, locale e remoto sono uguali.

  2. git show-branch *masterti mostrerà i commit in tutte le filiali i cui nomi finiscono in "master" (ad esempio master e origin / master ).

Se usi -vcon git remote update( git remote -v update) puoi vedere quali rami sono stati aggiornati, quindi non hai davvero bisogno di ulteriori comandi.

Tuttavia, sembra che tu voglia farlo in uno script o in un programma e finire con un valore vero / falso. In tal caso, ci sono modi per verificare la relazione tra il tuo attuale HEAD commit e il responsabile del ramo che stai monitorando, anche se poiché ci sono quattro possibili risultati non puoi ridurlo a una risposta sì / no. Tuttavia, se sei pronto a farlo pull --rebase, puoi considerare "local is behind" e "local is diverged" come "bisogno di tirare", e gli altri due come "non hanno bisogno di tirare".

È possibile ottenere l'id di commit di qualsiasi riferimento usando git rev-parse <ref>, quindi è possibile farlo per master e origin / master e confrontarli. Se sono uguali, i rami sono gli stessi. Se sono disuguali, vuoi sapere quale è davanti all'altro. L'utilizzo git merge-base master origin/masterti dirà l'antenato comune di entrambi i rami e se non sono divergenti sarà lo stesso dell'uno o dell'altro. Se ottieni tre ID diversi, i rami sono divergenti.

Per farlo correttamente, ad esempio in uno script, devi essere in grado di fare riferimento al ramo corrente e al ramo remoto che sta monitorando. La funzione di impostazione del prompt di bash in /etc/bash_completion.dha del codice utile per ottenere i nomi dei rami. Tuttavia, probabilmente non è necessario effettivamente ottenere i nomi. Git ha alcune scorciatoie per fare riferimento a filiali e commit (come documentato in git rev-parse --help). In particolare, puoi usarlo @per il ramo corrente (supponendo che tu non sia in uno stato a testa staccata) e @{u}per il suo ramo a monte (ad es origin/master.). Quindi git merge-base @ @{u}restituirà il (hash of the) commit in cui divergono il ramo corrente e il suo upstream git rev-parse @e git rev-parse @{u}ti darà gli hash dei due suggerimenti. Questo può essere riassunto nel seguente script:

#!/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

Nota: le versioni precedenti di git non lo consentivano @da sole, quindi potrebbe essere necessario utilizzare @{0}invece.

La linea UPSTREAM=${1:-'@{u}'}consente facoltativamente di passare esplicitamente un ramo a monte, nel caso in cui si desideri verificare un ramo remoto diverso da quello configurato per il ramo corrente. Questo sarebbe in genere nel formato remotename / branchname . Se non viene fornito alcun parametro, il valore predefinito è @{u}.

Lo script presuppone che tu abbia fatto una git fetcho git remote updateprima, per aggiornare i rami di tracciamento. Non ho inserito questo nello script perché è più flessibile poter eseguire il recupero e il confronto come operazioni separate, ad esempio se si desidera confrontare senza recuperare perché hai già recuperato di recente.


4
@takeshin Immagino che potresti combinare git ls-remote origin -h refs / heads / master come suggerito da @brool con git rev-list --max-count = 1 origin / master. Se restituiscono lo stesso hash, il ramo remoto non è cambiato dall'ultimo aggiornamento dei riferimenti remoti (con pull, fetch, aggiornamento remoto, ecc.) Ciò avrebbe il vantaggio di non dover ridurre il contenuto di tutti si impegnano subito, ma potrebbero lasciarlo per un tempo più conveniente. Tuttavia, poiché l'aggiornamento remoto non è distruttivo, è possibile farlo comunque.
Neil Mayhew,

2
Potresti anche provare git status -s -u no, il che dà un output più breve di git status -u no.
Phillip Cloud,

2
@mhulse, git remote -v update. Guarda l'output di git remote --helpper una spiegazione più completa.
Neil Mayhew,

1
@ChrisMaes Un buon punto. La sintassi più esplicita è necessaria con le versioni precedenti di git. Ho sperimentato i vari sistemi che ho e ho scoperto che @{u}funziona con git 1.8.3.2 ma @non lo fa. Tuttavia @funziona con 1.8.5.4. Morale della storia: git continua a migliorare e vale la pena avere la versione più recente che puoi.
Neil Mayhew,

1
Ora è richiesto un identificatore per @. Puoi usare @ {0} invece di @.
Ben Davis,

132

Se hai un ramo a monte

git fetch <remote>
git status

Se non si dispone di un ramo a monte

Confronta i due rami:

git fetch <remote>
git log <local_branch_name>..<remote_branch_name> --oneline

Per esempio:

git fetch origin

# See if there are any incoming changes
git log HEAD..origin/master --oneline

(Suppongo origin/mastersia il tuo ramo di monitoraggio remoto)

Se un qualsiasi commit è elencato nell'output sopra, allora hai delle modifiche in entrata - devi unire. Se nessun commit è elencato per git logallora non c'è nulla da unire.

Si noti che questo funzionerà anche se ci si trova in un ramo di funzionalità - che non ha un telecomando di tracciamento, poiché se si riferisce esplicitamente origin/masterinvece di utilizzare implicitamente il ramo a monte ricordato da Git.


2
git fetch; git log HEAD.. --onelineÈ possibile utilizzare anche una notazione più breve se esiste un ramo remoto predefinito per quello locale.
phil pirozhkov,

@philpirozhkov Se hai un ramo remoto predefinito, penso che dovrebbe essere un semplice "stato git". La mia risposta era generica per due rami, in cui uno potrebbe o meno seguire l'altro.
PlagueHammer,

55
git rev-list HEAD...origin/master --countti darà il numero totale di commit "diversi" tra i due.
Jake Berger,

1
breve e semplice. La mia soluzione preferita che mostra solo i nuovi commit (pollice in su due volte)
spankmaster79

Come posso usarlo in un file batch (Ubuntu), in modo da poter eseguire altri comandi nel caso in cui questo comando mostri che è necessario un pull?
Ulisse Alves,

69

Se questo è per uno script, puoi usare:

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

(Nota: il vantaggio di questo rispetto alle risposte precedenti è che non è necessario un comando separato per ottenere il nome del ramo corrente. "HEAD" e "@ {u}" (il ramo corrente a monte) se ne occupano. "git rev-parse --help" per maggiori dettagli.)


Ho scoperto @ {u} in modo indipendente e avevo aggiornato la mia risposta prima di vedere la tua.
Neil Mayhew,

1
Mostrerà git rev-parse @{u}effettivamente l'ultimo commit senza un git fetch?
Kyle Strand,

3
Questo era il biglietto! Tuttavia, la tua logica sta usando il ==che significa "se non ci sono cambiamenti dall'upstream". Ho usato !=per verificare "se ci sono modifiche dall'upstream" per la mia applicazione. Non dimenticare di git fetchprima!
ChrisPrime,

1
Ho aggiunto git fetch, perché è davvero necessario rispondere alla domanda originale. @è l'abbreviazione di HEADBTW.
user1338062,

Gli utenti Windows avranno bisogno di virgolette singole intorno @{u}ad es.git rev-parse '@{u}'
spuder

36

Il comando

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

elencherà l'attuale capo sul telecomando: puoi confrontarlo con un valore precedente o vedere se hai lo SHA nel tuo repository locale.


1
Qualche script di esempio per confrontare questi valori?
Takeshin,

18
git rev-list HEAD...origin/master --countti darà il numero totale di commit "diversi" tra i due.
Jake Berger,

3
@jberger per chiarire, questo mostrerà solo il numero di commit che sei dietro (non avanti e indietro) e funziona solo se tu git fetcho git remote updateprima. git statusmostra anche un conteggio, tra l'altro.
Dennis,

1
@Dennis Pensavo ..fosse "commit in origine / master, sottraendo HEAD" (cioè il numero di commit dietro). Considerando che, ...è la differenza simmetrica (cioè avanti e indietro)
Jake Berger

3
Eccellente. Per quanto ne so, questa è l'unica soluzione che controlla effettivamente l'origine per gli aggiornamenti ma non lo fa implicitamente fetch.
Kyle Strand,

35

Ecco un one-liner di Bash che confronta l'hash di commit HEAD del ramo corrente con il suo ramo remoto a monte, senza operazioni pesanti git fetcho git pull --dry-runoperazioni richieste:

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

Ecco come viene scomposta questa linea piuttosto densa:

  • I comandi sono raggruppati e nidificati usando la sintassi di sostituzione dei comandi di$(x) Bash .
  • git rev-parse --abbrev-ref @{u}restituisce un riferimento a monte abbreviato (ad es. origin/master), che viene quindi convertito in campi separati da spazio dal sedcomando convogliato , ad es origin master.
  • Questa stringa viene immessa in git ls-remotecui restituisce il commit principale del ramo remoto. Questo comando comunicherà con il repository remoto. Il cutcomando piped estrae solo il primo campo (l'hash di commit), rimuovendo la stringa di riferimento separata da tabulazione.
  • git rev-parse HEAD restituisce l'hash di commit locale.
  • La sintassi di Bash [ a = b ] && x || ycompleta il one-liner: si tratta di un confronto di stringhe di Bash =all'interno di un costrutto di test [ test ], seguito dai costrutti e-list e o-list && true || false.

2
Vorrei non usare / g sulla sed se si utilizzano barre nei nomi ramo. Questo è solo "sed 's / \ // /".
Martyn Davis,

@wjordan La tua soluzione fallisce quando il repository remoto non è raggiungibile (o in manutenzione) e si attiverà "aggiornato"
frame

20

Ti suggerisco di andare a vedere lo script https://github.com/badele/gitcheck . Ho codificato questo script per verificare in un unico passaggio tutti i tuoi repository Git e mostra chi non ha eseguito il commit e chi non ha eseguito il push / pull.

Ecco un risultato di esempio:

Inserisci qui la descrizione dell'immagine


6
pulito, pensando di riscriverlo in puro guscio
Olivier Refalo

1
Ora puoi anche usare gitcheck direttamente da un contenitore docker (con i tuoi file nell'host) Per maggiori informazioni vedi il progetto gitchub github
Bruno Adelé,

Uno strumento simile nella bash git-multi-repo-tooling . git mrepo -cquesto mostrerà tutti i commit in sospeso.
Greg,

11

Ho basato questa soluzione sui commenti di @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

facendo riferimento al tuo commento precedente , a questo punto non posso darti una risposta definitiva. Al momento in cui ho fatto quei commenti, mi sono tuffato nelle profondità di git e in particolare telecomandi e diff. Sono passati alcuni mesi da allora e molta di quella conoscenza è sepolta nel mio cervello. ;) Se stai cercando il numero di commit 'diversi' tra i due, allora ...sembra essere una parte valida della tua soluzione.
Jake Berger,

1
Grazie. Questo era pulito.
Shobhit Puri,

10

Ci sono già molte risposte molto ingegnose e ricche di funzionalità. Per fornire un po 'di contrasto, potrei accontentarmi di una linea molto semplice.

# 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
Mancava la risposta originale "!" nel se. Il valore di ritorno da git diff è zero, quando non ci sono cambiamenti.
thuovila

La migliore soluzione IMO là fuori, tuttavia devo sostituire "telecomandi / origine / TESTA" con "origine / padrone" o altra revisione
Matthias Michael Engh,

9

Penso che il modo migliore per farlo sarebbe:

git diff remotes/origin/HEAD

Supponendo di avere registrato questo refspec. Dovresti se hai clonato il repository, altrimenti (cioè, se il repository è stato creato de novo localmente e inviato al telecomando), devi aggiungere esplicitamente refspec.


9

Lo script seguente funziona perfettamente.

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

Vorrei fare come suggerito da Brool. Il seguente script di una riga prende l'SHA1 dell'ultima versione di cui è stato eseguito il commit e lo confronta con quello dell'origine remota e estrae le modifiche solo se differiscono. Ed è ancora più leggero delle soluzioni basate su git pullo git fetch.

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

Questo comando ha esito negativo, se il repository git viene clonato con "--depth 1" (per limitare le dimensioni del download). Sai, se c'è un modo per risolverlo?
Adam Ryczkowski l'

Il log git restituisce molte righe e riporta un errore "bash: [: troppi argomenti" su cui passareigit rev-parse --verify HEAD
Drew Pierce,

1
Questo è un semplice confronto di stringhe fatto da bash. Se qualcosa non funziona ti suggerirei di verificare la sintassi (ovvero la digiti in modo errato). Prima eseguire git log --pretty=%H ...refs/heads/master^ per ottenere SHA1 dell'ultima versione di cui è stato eseguito git ls-remote origin -h refs/heads/master |cut -f1 il commit , quindi eseguire per ottenere SHA1 di origine remota. Questi due sono comandi git e non hanno nulla a che fare con bash. Ciò che bash fa tra parentesi quadre è confrontare l'output del primo comando con il secondo, e se sono uguali restituisce vero e funziona git pull.
Claudio Floreani,

"e se sono uguali restituisce vero e funziona git pull". So di essere pignolo, ma solo per salvare qualcuno di confusione, dovrebbe essere "e se non sono uguali". Inoltre, per qualsiasi motivo, il primo comando git non funziona per me. (Sono su Git 2.4.1.) Quindi sto solo usando git log --pretty=%H master | head -n1invece. Ma non sono sicuro che sia esattamente lo stesso.
xd1le

6

Se si esegue questo script, verrà verificato se il ramo corrente necessita di 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
}

È molto conveniente metterlo come un pre-commit hook Git per evitare

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

quando commitprima pulling.

Per utilizzare questo codice come hook, è sufficiente copiare / incollare lo script

.git/hooks/pre-commit

e

chmod +x .git/hooks/pre-commit

6

Voglio solo pubblicare questo come un post reale in quanto è facile perdere questo nei commenti.

La risposta corretta e migliore a questa domanda è stata data da @Jake Berger, grazie amico, tutti hanno bisogno di questo e tutti lo mancano nei commenti. Quindi per tutti coloro che lottano con questo qui è la risposta corretta, basta usare l'output di questo comando per sapere se è necessario eseguire un pull git. se l'output è 0, ovviamente non c'è nulla da aggiornare.

@stackoverflow, dai un campanello a questo ragazzo. Grazie @ 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

Esegui git fetch (remote)per aggiornare i tuoi riferimenti remoti, ti mostrerà le novità. Quindi, quando effettui il checkout della tua filiale locale, ti mostrerà se è dietro a monte.


Penso che abbia già verificato la filiale locale, quindi ha bisogno di qualcos'altro per mostrare se è dietro ecc. Può farlo con lo stato git.
Neil Mayhew,

Vero, dopo aver recuperato i telecomandi, git statuslo dimostrerà anche questo.
che il

1
Questo è qualcosa dell'umore git pull --dry-rungiusto, ma penso che sia troppo pesante per uno script cron eseguito ogni minuto.
Takeshin,

@takeshin: non è possibile controllare i repository remoti senza accedere alla rete. Se non c'è nulla di nuovo fetchnon farà molto di più che controllare lo stato. Se hai bisogno di una reazione molto veloce e leggera sugli aggiornamenti remoti, potresti voler agganciare un qualche tipo di notifica al repository remoto.
che il

@takeshin: se vuoi controllare il repository remoto ogni minuto penso che ti sia sfuggito il punto di DVCS. L'idea è quella di essere in grado di svilupparsi in modo indipendente per un po ', e poi mettere tutto insieme senza problemi in seguito. Non è come cvs, svn, p4 ecc. Dove devi sempre lavorare in cima a qualunque sia l'ultimo del repository. Se hai davvero bisogno di qualcosa su cui qualcun altro sta lavorando, allora dovresti usare un meccanismo di comunicazione diverso, come l'e-mail, per dirti quando è pronto per essere estratto.
Neil Mayhew,

4

Tutti questi suggerimenti complessi mentre la soluzione è così breve e semplice:

#!/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 e LAST_UPDATE sono sempre uguali anche se ci sono cambiamenti
canbax

Questa soluzione è buona e semplice, metti deve essere git remote updateeseguita prima del tuo codice, per ottenere le ultime informazioni sul commit dell'origine
ak93

git remote updateNon dovrebbe aggiungere prima dei git showcomandi?
Setop,

2

Ecco la mia versione di uno script Bash che controlla tutti i repository in una cartella predefinita:

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

Può distinguere tra situazioni comuni, come pull necessità e push necessarie, ed è multithread, quindi il recupero avviene tutto in una volta. Ha diversi comandi, come pull e status.

Inserisci un link simbolico (o lo script) in una cartella nel tuo percorso, quindi funziona come git all status(, ecc.). Supporta solo origin / master, ma può essere modificato o combinato con un altro metodo.


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

elencherà tutto ciò a cui si fa riferimento in qualsiasi telecomando non presente nel repository. Per rilevare le modifiche di ref remote alle cose che hai già avuto (ad es. Ripristini ai commit precedenti) ci vuole un po 'di più:

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

Forse questo, se si desidera aggiungere attività come 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

Usando regexp semplice:

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

Questo non funzionerà. lo stato git è solo un controllo locale, quindi ti dirà solo se il tuo ramo è indietro se hai già aggiornato le tue impostazioni remote.
minhaz1

0

Uso una versione di una sceneggiatura basata sulla risposta di 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

Supponendo che questo script venga chiamato git-fetch-and-rebase, può essere invocato con un argomento facoltativodirectory name del repository Git locale su cui eseguire l'operazione. Se lo script viene chiamato senza argomenti, presuppone che la directory corrente faccia parte del repository Git.

Esempi:

# 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

È disponibile anche qui .


0

Dopo aver letto molte risposte e post multipli e aver trascorso mezza giornata a provare varie permutazioni, questo è quello che ho escogitato.

Se sei su Windows, puoi eseguire questo script in Windows usando Git Bash fornito da Git per Windows (installazione o portatile).

Questo script richiede argomenti

- percorso locale ad es. / d / source / project1
- URL Git, ad esempio https: //username@bitbucket.org/username/project1.git
- parola d'ordine

se una password non deve essere inserita nella riga di comando in testo semplice,
quindi modificare lo script per verificare se GITPASS è vuoto; non
sostituisci e lascia che Git richieda una password

La sceneggiatura lo farà

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

Se c'è una modifica stampata dallo script, puoi procedere con il recupero o il pull. La sceneggiatura potrebbe non essere efficiente, ma fa il lavoro per me.

Aggiornamento - 30-10-2015: stderr su dev null per impedire la stampa dell'URL con la password sulla 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

Per gli utenti di Windows che finiscono per cercare questa domanda, ho modificato alcune delle risposte in uno script PowerShell. Modifica se necessario, salva su un .ps1file ed esegui su richiesta o pianificato se lo desideri.

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

Perché la risposta di Neils mi ha aiutato così tanto, ecco una traduzione di Python senza dipendenze:

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

Puoi anche trovare uno script Phing che lo fa ora.

Avevo bisogno di una soluzione per aggiornare automaticamente i miei ambienti di produzione e siamo molto felici grazie a questo script che sto condividendo.

Lo script è scritto in XML e necessita di Phing .


Forse non è una buona idea copiare incollare lo script qui, lo sto ancora aggiornando ...
Pol Dellaiera,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.