746 Stimmen

Prüfen, ob ein Pull in Git erforderlich ist

Wie prüfe ich, ob sich das entfernte Repository geändert hat und ich einen Pull durchführen muss?

Jetzt verwende ich dieses einfache Skript:

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

Aber es ist ziemlich schwer.

Gibt es einen besseren Weg? Die ideale Lösung würde alle entfernten Zweige überprüfen und die Namen der geänderten Zweige sowie die Anzahl der neuen Übertragungen in jedem Zweig zurückgeben.

16 Stimmen

Bitte beachten Sie: "git pull --dry-run" funktioniert nicht so, wie vermutlich erwartet. Es scheint, dass git pull unbekannte Optionen direkt an git fetch weitergibt. Das Ergebnis ist das eines normalen git pull.

34 Stimmen

"pull" ist nur ein kurzer Weg, um "fetch" und "merge" auf einmal zu machen, wenn Sie den Status der entfernten Repo überprüfen müssen, simulieren Sie wirklich ein "fetch". Also git fetch -v --dry-run ist das, was Sie brauchen.

0 Stimmen

Ich habe die von OP vorgeschlagene Lösung ausprobiert, und es hat nichts gebracht. Wahrscheinlich nicht der beste Ansatz?

2voto

Henry Schreiner Punkte 755

Hier ist meine Version eines Bash-Skripts, das alle Repositories in einem vordefinierten Ordner überprüft:

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

Es kann zwischen gängigen Situationen wie "Pull needed" und "Push needed" unterscheiden und ist multithreading-fähig, so dass der Abruf auf einmal erfolgt. Es hat mehrere Befehle, wie pull und status.

Setzen Sie einen Symlink (oder das Skript) in einen Ordner in Ihrem Pfad, dann funktioniert es wie git all status (, etc.). Sie unterstützt nur Ursprung/Master, kann aber bearbeitet oder mit einer anderen Methode kombiniert werden.

2voto

user9869932 Punkte 5353

Dieser Einzeiler funktioniert bei mir in zsh (aus der Antwort von @Stephen Haberman)

git fetch; [ $(git rev-parse HEAD) = $(git rev-parse @{u}) ] \
    && echo "Up to date" || echo "Not up to date"

1voto

Roko C. Buljan Punkte 178158

Zu automatisieren git pull auf einen gewünschten Zweig:
Verwenden Sie wie: ./pull.sh "origin/main"

#!/bin/bash

UPSTREAM=${1:-'@{u}'}
DIFFCOMM=$(git fetch origin --quiet; git rev-list HEAD..."$UPSTREAM" --count)
if [ "$DIFFCOMM" -gt 0 ]; then
  echo "Pulling $UPSTREAM";
  git pull;
else
  echo "Up-to-date";
fi

1voto

frans Punkte 7880

Weil Neils Antwort mir so sehr geholfen hat, hier eine Python-Übersetzung ohne Abhängigkeiten:

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

1voto

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

von brool ist die leichteste Weg, um einfach siehe ob sich überhaupt etwas an der Fernbedienung geändert hat.

Ausgehend vom Ortsvorsteher:

$ git log -1 --oneline @
9e1ff307c779 (HEAD -> master, tag: v5.15-rc4, origin/master, origin/HEAD) Linux 5.15-rc4

Ich sehe, dass mein gezogener Ursprung an diesem Tag auf dem neuesten Stand ist. git status sagt dies auch. Aber das ist nur das lokale Up-to-Date, das (schnelle) Merge nach einem Fetch.

Um zu überprüfen, ob der entfernte HEAD irgendwo hingegangen ist, und auch Master, und vielleicht einige neue Tags:

$ git ls-remote origin HEAD master --tags 'v5.1[56]-rc[345]*'

84b3e42564accd94c2680e3ba42717c32c8b5fc4        HEAD
84b3e42564accd94c2680e3ba42717c32c8b5fc4        refs/heads/master
71a6dc2a869beafceef1ce46a9ebefd52288f1d7        refs/tags/v5.15-rc3
5816b3e6577eaa676ceb00a848f0fd65fe2adc29        refs/tags/v5.15-rc3^{}
f3cee05630e772378957a74a209aad059714cbd2        refs/tags/v5.15-rc4
9e1ff307c779ce1f0f810c7ecce3d95bbae40896        refs/tags/v5.15-rc4^{}

HEAD befindet sich immer noch auf demselben Zweig, aber nicht mehr auf demselben Commit. Diese lokale @ Commit bleibt mit dem Tag v5.15-rc4. Dies ist ungefähr die gleiche Information wie oben auf der Zusammenfassung Blatt auf kernel.org git:

Branch: master <commit message> <author> age: 2 hours

Nur das ls-remote sammelt weniger Informationen - aber auch hier weiß ich nur, dass ich auf 9e1ff... alias v5.15-rc4.

Anstatt Refs (HEAD, master) oder Tags zu benennen, kann man auch eine Liste von Heads oder Branches von jedem Repo erhalten:

$ git ls-remote --heads git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git 

af06aff2a0007976513134dfe993d55992dd866a        refs/heads/akpm
20bcee8e95f783c11a7bea1b6a40c70a37873e0a        refs/heads/akpm-base
a25006a77348ba06c7bc96520d331cd9dd370715        refs/heads/master
4d5a088c93cea1c821d02a2217c592391d9682e2        refs/heads/pending-fixes
4de593fb965fc2bd11a0b767e0c65ff43540a6e4        refs/heads/stable

Hier ersetzt eine URL den Begriff "Herkunft".


Wie kann ich überprüfen, ob sich das entfernte Repository geändert hat und ich ziehen?

Wenn Sie so fragen, ziehen Sie einfach.

Wie überprüfe ich, ob das entfernte Repository endlich etwas getan hat und ich es abrufen möchte?

Dann holt man sie, prüft sie und führt sie zusammen.


Mit einzelnen Git-Befehlen:

$ git rev-list -1  master
9e1ff307c779ce1f0f810c7ecce3d95bbae40896
$ git rev-list -1  @
9e1ff307c779ce1f0f810c7ecce3d95bbae40896

Das allein sagt noch nicht viel aus, aber angenommen, ich weiß, dass ich nichts verbrochen habe:

$ git ls-remote origin HEAD master
60a9483534ed0d99090a2ee1d4bb0b8179195f51        HEAD
60a9483534ed0d99090a2ee1d4bb0b8179195f51        refs/heads/master

Sagt mir, dass die Fernbedienung eine geändert . Das hat sich seit der letzten Änderung wirklich geändert. kernel.org sagt Age: 46 min. über diesen letzten Commit auf Master.

Nach git fetch :

$ git rev-list -1 master     
9e1ff307c779ce1f0f810c7ecce3d95bbae40896

$ git rev-list -1 FETCH_HEAD
60a9483534ed0d99090a2ee1d4bb0b8179195f51

$ git log --oneline ..FETCH_HEAD        
60a9483534ed (origin/master, origin/HEAD) Merge tag 'warning-fixes-20211005' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
f6274b06e326 Merge tag 'linux-kselftest-fixes-5.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
ef31499a87cf fscache: Remove an unused static variable
d9e3f82279bf fscache: Fix some kerneldoc warnings shown up by W=1
bc868036569e 9p: Fix a bunch of kerneldoc warnings shown up by W=1
dcb442b13364 afs: Fix kerneldoc warning shown up by W=1
c0b27c486970 nfs: Fix kerneldoc warning shown up by W=1
84b3e42564ac Merge tag 'media/v5.15-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
b60be028fc1a Merge tag 'ovl-fixes-5.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs
df5c18838ea8 Merge tag 'mips-fixes_5.15_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
206704a1fe0b media: atomisp: restore missing 'return' statement
740da9d7ca4e MIPS: Revert "add support for buggy MT7621S core detection"
1dc1eed46f9f ovl: fix IOCB_DIRECT if underlying fs doesn't support direct IO
2f9602870886 selftests: drivers/dma-buf: Fix implicit declaration warns
a295aef603e1 ovl: fix missing negative dentry check in ovl_rename()

Jetzt habe ich alle Informationen lokal, aber ich habe sie (noch) nicht zusammengeführt. Ich habe auch alle Objekte heruntergeladen. git show HASH o git diff HASH travail.

In diesem Fall ist das Zusammenführen fast ein Nullsummenspiel: schnelles Vorspulen zum letzten Commit und keine zusätzliche (echte) Zusammenführung, geschweige denn Konflikte. Dies kann durch --ff-only sichergestellt werden:

$ git merge --ff-only FETCH_HEAD
Updating 9e1ff307c779..60a9483534ed
Fast-forward
...
... 

Wie kann ich also wissen, wann ich ziehen muss? Sobald diese beiden Hashes unterschiedlich sind/wird, sind sie unterschiedlich: Updating 9e1ff307c779..60a9483534ed Fast-forward . Sie können nicht identisch sein, das wäre "nichts zum Aktualisieren".

Die neuesten Reflog-Commits sagen das Gleiche:

$ git log -10 --oneline -g
60a9483534ed (HEAD -> master, origin/master, origin/HEAD) HEAD@{0}: merge 60a9483534ed0d99090a2ee1d4bb0b8179195f51: Fast-forward
9e1ff307c779 (tag: v5.15-rc4) HEAD@{1}: pull: Fast-forward

Das Auftauchen eines neuen Tags ist in diesem Fall vielleicht der beste Auslöser und auch das beste Ziel; das führt zurück zu den git ls-remote origin --tags PATTERN .


...und sagen Sie mir nicht, dass git remote show es eine andere Methode:

show Zeigt einige Informationen über die Fernbedienung an.

Mit der Option -n werden die abgesetzten Köpfe nicht zuerst mit git ls-remote abgefragt stattdessen werden zwischengespeicherte Informationen verwendet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X