Synchronisation d'un référentiel Git local avec un référentiel distant


297

Je veux synchroniser mon référentiel local avec un référentiel distant afin que mon référentiel local devienne une copie à 100% du référentiel distant - ce qui signifie que si certains fichiers diffèrent dans ces référentiels, nous remplaçons les locaux par les distants, et s'il y en a fichiers dans des référentiels locaux qui n'existent pas dans la télécommande, les fichiers locaux sont supprimés.

Existe-t-il un moyen d'y parvenir autrement qu'en faisant un nouveau clone de référentiel distant?

Question similaire à Sync local git repo with remote in one shot discarding local changes / commits .


4
Toujours quand je viens ici, je cherche Synchroniser une fourche
Martin Thoma

1
git fetch --prune
hassanzadeh.sd

Réponses:


342
git fetch --prune

-p, --prune
Après la récupération, supprimez toutes les branches de suivi à distance qui n'existent plus sur la télécommande. options de taille


6
Voilà ce que je cherchais! PS La prochaine fois, je lirai les pages de manuel plus attentivement avant de creuser stackoverflow :-)
Sergiy Sokolenko

5
Oui, git pull -pfait la même chose - 'git pull exécute git fetch avec les paramètres donnés et appelle git merge pour fusionner les têtes de branche récupérées dans la branche actuelle' - git-scm.com/docs/git-pull
jobwat

2
À utiliser git fetch <remote> --prune, au cas où quelqu'un n'aurait besoin que d' --pruneune télécommande spécifique. par exemple. git fetch upstream --prune.
Fery Wardiyanto

git fetch origin --prunepour synchroniser votre repo local avec votre fork d'un upstreamprojet
Stuart Cardall

2
@SergiySokolenko c'est ce que nous disons tous, mais au fond, nous savons que SO est devenu plus pratique que les pages de manuel :-P
Marcello Romani

144

Ces étapes le feront:

git reset --hard HEAD
git clean -f -x -d -n

puis sans -n

Cela prendra en charge tous les changements locaux. Maintenant, les commits ...

git status

et notez la ligne telle que:

Your branch is ahead of 'xxxx' by N commits.

Prenez note du numéro «N» maintenant:

git reset --hard HEAD~N
git pull

et enfin:

git status

ne doit rien montrer à ajouter / valider. Tout propre.

Cependant, un nouveau clone peut faire de même (mais est beaucoup plus lent).

=== Mise à jour ===

Comme mes connaissances git se sont légèrement améliorées au fil du temps, j'ai trouvé une autre façon plus simple de faire de même. Voici comment (# avec explication). Dans votre branche de travail:

git fetch # This updates 'remote' portion of local repo. 
git reset --hard origin/<your-working-branch>
# this will sync your local copy with remote content, discarding any committed
# or uncommitted changes.

Bien que vos validations et modifications locales disparaissent de la vue après cela, il est possible de récupérer les modifications validées, si nécessaire.


1
merci beaucoup pour la mise à jour fonctionne parfaitement avec github et bitbucket :)
CommonSenseCode

cette réponse a été pour moi la solution la plus fiable.
AlanH

95

Vous devez comprendre qu'un référentiel Git n'est pas seulement une arborescence de répertoires et de fichiers, mais stocke également un historique de ces arborescences - qui peuvent contenir des branches et des fusions.

Lors de la récupération à partir d'un référentiel, vous y copiez tout ou partie des branches dans votre référentiel. Celles-ci sont ensuite dans votre référentiel en tant que "branches de suivi à distance", par exemple des branches nommées comme remotes/origin/masterou telles.

La récupération de nouvelles validations à partir du référentiel distant ne changera rien à votre copie de travail locale.

Votre copie de travail a normalement un commit extrait, appelé HEAD. Ce commit est généralement la pointe de l'une de vos succursales locales.

Je pense que vous souhaitez mettre à jour votre branche locale (ou peut-être toutes les branches locales?) Vers la branche distante correspondante, puis consultez la dernière branche.

Pour éviter tout conflit avec votre copie de travail (qui pourrait avoir des modifications locales), vous devez d'abord nettoyer tout ce qui n'est pas versionné (en utilisant git clean). Ensuite, vous extrayez la branche locale correspondant à la branche distante que vous souhaitez mettre à jour et utilisez git resetpour la basculer vers la branche distante récupérée. ( git pullincorporera toutes les mises à jour de la branche distante dans votre branche locale, ce qui pourrait faire de même, ou créera une validation de fusion si vous avez des validations locales.)

(Mais alors vous perdrez vraiment toutes les modifications locales - à la fois dans la copie de travail et les validations locales. Assurez-vous que vous le voulez vraiment - sinon, utilisez mieux une nouvelle branche, cela enregistre vos validations locales. Et utilisez git stashpour enregistrer les modifications qui ne sont pas encore validées .)


Modifier: si vous n'avez qu'une seule branche locale et que vous suivez une branche distante, tout ce que vous avez à faire est de

git pull

depuis l'intérieur du répertoire de travail.

Cela récupérera la version actuelle de toutes les branches distantes suivies et mettra à jour la branche actuelle (et le répertoire de travail) vers la version actuelle de la branche distante qu'elle suit.


Si je change RIEN dans mon référentiel local, seul a.) Veut avoir une copie de tout depuis la télécommande, et b.) Veut une possibilité de montrer les différences entre les versions. Donc, je ne m'engage pas, je ne change rien = pas de mises à jour / changements locaux. Quelles commandes dois-je utiliser périodiquement (par exemple toutes les semaines environ) pour obtenir les deux fonctionnalités ci-dessus? S'il vous plaît, répondez KISS (Keep It Simple Stupid) - je suis un git noob aussi, et ofc RTFM - mais pour le début, j'ai besoin d'aide. ;)
kobame

Dans votre cas simple, un git pulldevrait suffire, je pense. (J'ai mis à jour la réponse.)
Paŭlo Ebermann

et si j'ai des changements locaux que je ne veux pas commettre. Maintenant, quand je fais un pull, il me dit de les commettre ou de les ranger. Donc dans ce cas, comment puis-je dire à git de remplacer ceux-ci et de faire le pull?
Harshana

89

Vous voulez faire

git fetch --prune origin
git reset --hard origin/master
git clean -f -d

Cela rend votre dépôt local exactement comme votre dépôt distant.

N'oubliez pas de remplacer l'origine et le maître par la télécommande et la branche avec lesquelles vous souhaitez vous synchroniser.


2
il supprime également tous les répertoires de l'installation de npm et de l'installation de bower, déconseillé sauf si vous souhaitez réinstaller toutes les dépendances qui sont dans .gitignore
chwagssd

Il n'a pas supprimé mon node_modules, il fonctionne exactement comme je le souhaite.
Vahid Amiri

AVERTISSEMENT: il supprime les fichiers non suivis
Amit Yadav

J'ai perdu toutes mes données en utilisant ce code, j'ai essayé de synchroniser mon référentiel local avec le référentiel git. Mais cela a synchronisé mon référentiel global avec mon référentiel local.
Zahid Khan

10

Réinitialiser et synchroniser le référentiel local avec la branche distante

La commande: N'oubliez pas de remplacer origine et maître par la télécommande et la branche avec lesquelles vous souhaitez vous synchroniser.

git fetch origin && git reset --hard origin/master && git clean -f -d

Ou pas à pas:

git fetch origin
git reset --hard origin/master
git clean -f -d

Votre branche locale est maintenant une copie exacte (commits et tout) de la branche distante.

Sortie de commande:

Voici un exemple d'exécution de la commande sur un clone local du référentiel Forge a git.

sharkbook:forge lbaxter$ git fetch origin && git reset --hard origin/master && git clean -f -d
HEAD is now at 356cd85 FORGE-680
Removing forge-example-plugin/
Removing plugin-container-api/
Removing plugin-container/
Removing shell/.forge_settings
sharkbook:forge lbaxter$

4

(Ces informations proviennent du manuel de l'utilisateur de Git )

J'apprends aussi, donc ce n'est peut-être pas exactement une réponse à la question, mais cela pourrait aider quelqu'un:

  1. Lorsqu'un référentiel distant est initialement cloné, des copies de toutes les branches sont stockées dans votre référentiel local (visualisez-les avec git branch -r)
  2. Pour mettre à jour ces copies et les actualiser (c'est-à-dire les synchroniser avec la branche distante), utilisez git fetch . Cela n'affectera aucun de vos succursales existantes créées sur mesure.
  3. Pour remplacer votre extraction de branche locale, une nouvelle version de la branche sur laquelle vous travaillez (en supposant que vous avez déjà exécuté git add origin /path/to/repository) utiliser git checkout origin/branch_name, cela remplacera vos modifications locales sur la branchebranch_name

3

On dirait que vous voulez un miroir du référentiel distant:

git clone --mirror url://to/remote.git local.git

Cette commande crée un référentiel nu. Si vous ne voulez pas d'un référentiel nu, les choses deviennent plus compliquées.


3

Si vous parlez de synchroniser un dépôt fourchu, vous pouvez suivre ces étapes.

Comment synchroniser un référentiel fork depuis git

  1. vérifiez votre branche git actuelle

    git branch

  2. caisse à maîtriser si vous n'êtes pas maître

    git checkout master

  3. Récupérez le référentiel en amont si vous disposez des droits d'accès corrects

    git fetch upstream

  4. Si vous obtenez une erreur en dessous, exécutez

    git remote add upstream git@github.com:upstream_clone_repo_url/xyz.git

    fatal: 'upstream/master' does not appear to be a git repository  
    fatal: Could not read from remote repository.
    Please make sure you have the correct access rights and the repository exists.
    
  5. Exécutez maintenant la commande ci-dessous.

    git fetch upstream

  6. Maintenant, si vous êtes maître, fusionnez l'amont / maître dans la branche maître

    git merge upstream/master

    C'est tout!!

    Vérification croisée via la git remotecommande, plus spécifiquegit remote -v

    Si j'ai également des droits de validation sur le référentiel en amont, je peux créer une branche en amont locale et effectuer un travail qui ira en amont.


Pourquoi devrais-je faire 5.git fetch en amont alors que j'y ai déjà une erreur à la troisième étape?
Md Sifatul Islam

-2

Vous pouvez utiliser des crochets git pour cela. Il suffit de créer un hook qui pousse le changement vers l'autre référentiel après une mise à jour.

Bien sûr, vous pouvez obtenir des conflits de fusion, vous devez donc trouver comment les gérer.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.