Comment forcer «git pull» pour écraser les fichiers locaux?


7191

Comment forcer l'écrasement des fichiers locaux sur un git pull?

Le scénario est le suivant:

  • Un membre de l'équipe modifie les modèles d'un site Web sur lequel nous travaillons
  • Ils ajoutent des images au répertoire images (mais oublient de les ajouter sous contrôle de source)
  • Ils m'envoient les images par courrier, plus tard,
  • J'ajoute les images sous le contrôle de la source et je les pousse vers GitHub avec d'autres changements
  • Ils ne peuvent pas extraire les mises à jour de GitHub car Git ne veut pas écraser leurs fichiers.

Voici l'erreur que je reçois:

erreur: le fichier d'arbre de travail non suivi 'public / images / icon.gif' serait écrasé par la fusion

Comment forcer Git à les écraser? La personne est un concepteur - généralement, je résous tous les conflits à la main, donc le serveur a la version la plus récente dont ils ont juste besoin de mettre à jour sur leur ordinateur.


17
toute personne lisant ceci qui pense perdre des fichiers, j'ai été dans cette position et j'ai trouvé que le tampon de Sublime Text m'a sauvé - si je travaille sur quelque chose, supprimez accidentellement tout en essayant de résoudre un problème similaire à celui-ci ou en utilisant une réponse à cette question et que les fichiers ont été ouverts dans Sublime (ce qui a de bonnes chances), alors les fichiers seront toujours là est Sublime, soit juste là, soit dans l'historique d'annulation
Toni Leigh

64
git reset --hard origin/branch_to_overwrite
Andrew Atkinson

1
Fondamentalement, ne faites un pull from develop qu'après le checkout initial -b. faites votre travail, puis repoussez.
ldgorman

1
Réponse courte: supprimer et recréer une branche. 1. Supprimer la branche: git branch <branch> -D2. Réinitialiser à un commit avant le conflit: git reset <commit> --hard3. Recréer la branche: git branch <branch>4. Définir le suivi sur le serveur: git --set-upstream-to=origin/<branch> <branch> 5. Pull: git pull`
Nino Filiu

1
Pour changer toutes les terminaisons CRLF en LF, (commencer propre)git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Chloé

Réponses:


10046

Important: Si vous avez des modifications locales, elles seront perdues. Avec ou sans --hardoption, tous les commits locaux qui n'ont pas été poussés seront perdus. [*]

Si vous avez des fichiers qui sont ne pas suivis par Git (par exemple, le contenu utilisateur téléchargé), ces fichiers ne seront pas affectés.


Je pense que c'est la bonne façon:

git fetch --all

Ensuite, vous avez deux options:

git reset --hard origin/master

OU Si vous êtes sur une autre branche:

git reset --hard origin/<branch_name>

Explication:

git fetch télécharge la dernière version à distance sans essayer de fusionner ou de rebaser quoi que ce soit.

Ensuite, le git resetréinitialise la branche principale à ce que vous venez de récupérer. L' --hardoption modifie tous les fichiers de votre arborescence de travail pour correspondre aux fichiersorigin/master


Maintenir les engagements locaux actuels

[*] : Il convient de noter qu'il est possible de conserver les validations locales actuelles en créant une branche masteravant de réinitialiser:

git checkout master
git branch new-branch-to-save-current-commits
git fetch --all
git reset --hard origin/master

Après cela, tous les anciens commits seront conservés new-branch-to-save-current-commits.

Modifications non validées

Les modifications non validées (même par étapes) seront perdues. Assurez-vous de ranger et de valider tout ce dont vous avez besoin. Pour cela, vous pouvez exécuter ce qui suit:

git stash

Et puis pour réappliquer ces modifications non validées:

git stash pop

14
Fais attention! Si vous avez des commits locaux non poussés, cela les supprimera de votre branche! Cette solution conserve intacts les fichiers non suivis dans le référentiel, mais écrase tout le reste.
Matthijs P

479
C'est une question populaire, je voudrais donc clarifier le commentaire du haut ici. Je viens d'exécuter des commandes comme décrit dans cette réponse et cela n'a pas supprimé TOUS les fichiers locaux. Seuls les fichiers suivis à distance ont été remplacés et tous les fichiers locaux qui se trouvaient ici n'ont pas été modifiés.
Red

14
dans le cas où vous tirez d'un référentiel dont le nom de branche distante est différent de "master", utilisezgit reset --hard origin/branch-name
Nerrve

97
Étant donné le nombre de votes positifs à cette question et réponse, je pense que git devrait incorporer une commande commegit pull -f
Sophivorus

7
Les validations qui n'ont pas été poussées avant la réinitialisation matérielle peuvent être récupérées à l'aide de git reflog, qui répertorie toutes les validations, y compris celles sans base. Jusqu'à ce que vous nettoyiez votre copie locale en utilisant git gc, alors tout est perdu
Koen.

936

Essaye ça:

git reset --hard HEAD
git pull

Il devrait faire ce que vous voulez.


16
Je l'ai fait et certains fichiers locaux qui n'étaient plus en dépôt ont été laissés sur le disque.
Piotr Owsiak du

26
Je ne pense pas que ce soit correct. ce qui précède effectuera une fusion, pas un écrasement, ce qui était demandé dans la question: "Comment forcer git à les écraser?" Je n'ai pas la réponse, je la recherche actuellement .. en ce moment je passe à la branche avec le code que je veux garder "git checkout BranchWithCodeToKeep", puis "git branch -D BranchToOverwrite" puis enfin msgstr "git checkout -b BranchToOverwrite". vous aurez maintenant le code exact de BranchWithCodeToKeep sur la branche BranchToOverwrite sans avoir à effectuer une fusion.
felbus

252
au lieu de fusionner en utilisant 'git pull', essayez git fetch --all suivi de 'git reset --hard origin / master'
Lloyd Moore

5
oui, la solution @lloydmoore a fonctionné pour moi. Pourrait être une réponse plutôt qu'un simple commentaire.
Max Williams

2
Cela réinitialisera les modifications actuelles à la dernière validation de branche tirée. Ensuite, git pull fusionne les modifications de la dernière branche. Cela a fait exactement ce que je voulais qu'il fasse. Merci!
Codeversed

459

AVERTISSEMENT: git cleansupprime tous vos fichiers / répertoires non suivis et ne peut pas être annulé.


Parfois, clean -fça n'aide pas. Si vous avez des ANNUAIRES non suivis, l'option -d a également besoin:

# WARNING: this can't be undone!

git reset --hard HEAD
git clean -f -d
git pull

ATTENTION: git cleansupprime tous vos fichiers / répertoires non suivis et ne peut pas être annulé.

Pensez à utiliser le drapeau -n( --dry-run) en premier. Cela vous montrera ce qui sera supprimé sans supprimer quoi que ce soit:

git clean -n -f -d

Exemple de sortie:

Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...

33
Génial ... Ran cela contre mon repo dotfiles ... Dans mon répertoire personnel. Heureusement que je n'avais rien d'important là-bas ...
Lauri

7
Je pense que la description du scénario indique clairement qu'il ne veut pas vraiment jeter le contenu. Ce qu'il veut plutôt, c'est cesser de se gêner pour écraser les fichiers. @Lauri, cela ne devrait pas vous arriver. Malheureusement, les gens semblent avoir mal compris l'essence de la description du scénario - voir ma suggestion.
Hedgehog

19
ENFIN . git clean -f -d est pratique lorsque make clean ne parvient pas à tout nettoyer.
earthmeLon

7
@crizCraig sauf s'ils sont ajoutés.gitignore
Bleeding Fingers

5
@earthmeLon, pour cela vous voudrez peut-être git clean -dfx. Le -xignore .gitignore. Généralement, vos produits de build seront en .gitignore.
Paul Draper

384

Comme Hérisson, je pense que les réponses sont terribles. Mais bien que la réponse de Hedgehog puisse être meilleure, je ne pense pas qu'elle soit aussi élégante qu'elle pourrait l'être. La façon dont j'ai trouvé cela est d'utiliser "fetch" et "merge" avec une stratégie définie. Ce qui devrait faire en sorte que vos modifications locales soient préservées tant qu'elles ne font pas partie des fichiers avec lesquels vous essayez de forcer l'écrasement.

Commencez par valider vos modifications

 git add *
 git commit -a -m "local file server commit message"

Récupérez ensuite les modifications et remplacez-les en cas de conflit

 git fetch origin master
 git merge -s recursive -X theirs origin/master

"-X" est un nom d'option et "leur" est la valeur de cette option. Vous choisissez d'utiliser "leurs" modifications, au lieu de "vos" modifications en cas de conflit.


56
C'est la meilleure réponse que j'ai vue jusqu'à présent. Je ne l'ai pas essayé, mais contrairement à d'autres réponses, cela n'essaie pas de neutraliser tous vos fichiers non suivis, ce qui est très dangereux pour des raisons évidentes.
huyz

5
Idem - cela a fonctionné pour moi lors d'une fusion très importante (demande de pull GitHub) où je voulais juste tout accepter en plus de ce que j'avais. Bonne réponse! Dans mon cas, les deux dernières commandes étaient: 1) get fetch other-repo; 2)git merge -s recursive -X theirs other-repo/master
quux00

2
Cela écrasera tous les conflits avec les fichiers de référentiels et non avec vos fichiers locaux, correct?
Nathan F.

2
Meilleure réponse. La réponse la plus élevée acceptée m'a laissé dans mon cas sur la tête détachée. Je suis revenu à la branche maître locale et git merge -X theirs origin/master
j'ai

2
Le problème avec cette (excellente) réponse, c'est qu'elle ajoute tous les fichiers locaux, ce qui peut parfois ne pas être ce que vous voulez. Vous souhaiterez peut-être simplement ajouter les fichiers spécifiques qui ont été omis. Mais la meilleure chose à ce sujet est qu'il lui permet de faire ce qu'il aurait dû faire - les ajouter localement. Vous n'aurez probablement pas besoin de la stratégie -X leur, car ils sont la même image. En fait, je suggérerais de le laisser au début, juste pour savoir s'il y a des anomalies, et de l'ajouter s'il y en a, après avoir vérifié que `` la leur '' est toujours le bon choix. Mais alors, je suis paranoïaque.
Bob Kerns

279

Au lieu de faire:

git fetch --all
git reset --hard origin/master

Je vous conseille de faire ce qui suit:

git fetch origin master
git reset --hard origin/master

Pas besoin de récupérer toutes les télécommandes et les branches si vous allez réinitialiser la branche d'origine / principale, n'est-ce pas?


3
Votre réponse est exactement ce dont vous aviez besoin pour votre représentant. Je dois demander, cela supprime-t-il également tous les fichiers non suivis?
Nicolas De Jay

5
Oui, la plupart de mes représentants viennent d'ici :) Cela supprimera également tous les fichiers non suivis. Quelque chose que j'avais oublié et dont je me rappelais douloureusement il y a seulement 2 jours ...
Johanneke

1
Voir les commentaires sur cette autre réponse: stackoverflow.com/a/8888015/2151700
Johanneke

Cela n'a pas supprimé mes fichiers non suivis; qui est en fait ce à quoi je m'attendais. Y a-t-il une raison à cela pour certaines personnes et pas pour d'autres?
arichards

Les fichiers non suivis ne sont pas affectés par la réinitialisation de git. Si vous souhaitez également les supprimer, faites-le d' git add .abord, avantgit reset --hard
Johanneke

131

Il semble que la meilleure façon est de faire d'abord:

git clean

Pour supprimer tous les fichiers non suivis, puis continuer avec la procédure habituelle git pull...


4
J'ai essayé d'utiliser "git clean" pour résoudre le même problème, mais il ne l'a pas résolu. git status indique "Votre branche et 'origin / master' ont divergé, # et ont respectivement 2 et 9 commit (s) différent (s)." et git pull dit quelque chose de similaire à ce que vous avez ci-dessus.
slacy

43
git clean est un instrument plutôt contondant, et pourrait jeter beaucoup de choses que vous voudrez peut-être garder. Mieux vaut supprimer ou renommer les fichiers dont git se plaint jusqu'à ce que le pull réussisse.
Neil Mayhew

2
Je ne pense pas que cela fonctionne en général. N'y a-t-il pas un moyen de faire essentiellement une télécommande de clone git via un pull git forcé?
mathtick

10
@mathick:git fetch origin && git reset --hard origin/master
Arrowmaster

3
Est git cleanla meilleure réponse ici? On dirait que la suppression de fichiers n'est pas nécessairement ce que l'OP veut. Ils ont demandé «une réécriture des fichiers locaux» et non la suppression.
JohnAllen

111

Attention, cela supprimera définitivement vos fichiers si vous avez des entrées de répertoire / * dans votre fichier gitignore.

Certaines réponses semblent terribles. Terrible dans le sens de ce qui est arrivé à @Lauri en suivant la suggestion de David Avsajanishvili.

Plutôt (git> v1.7.6):

git stash --include-untracked
git pull

Plus tard, vous pouvez nettoyer l'historique de la cachette.

Manuellement, un par un:

$ git stash list
stash@{0}: WIP on <branch>: ...
stash@{1}: WIP on <branch>: ...

$ git stash drop stash@{0}
$ git stash drop stash@{1}

Brutalement, tout à la fois:

$ git stash clear

Bien sûr, si vous voulez revenir à ce que vous avez caché:

$ git stash list
...
$ git stash apply stash@{5}

2
Non je ne pense pas. Le masquage déplace simplement les fichiers non validés. Ce qui précède déplace également (stashes) les fichiers que git ne suit pas. Cela empêche les fichiers qui ont été ajoutés à la télécommande, qui ne sont pas encore descendus sur votre machine - mais que vous avez créés (!) - d'être retirés. Le tout sans détruire le travail non engagé. J'espère que cela a du sens?
Hérisson

3
Si vous n'avez pas 1.7.6, vous pouvez imiter --include-untrackedsimplement en temporairement temporairement git addl'intégralité de votre dépôt, puis en le cachant immédiatement.
nategood

3
Je suis d'accord avec Hedgehog. Si vous faites les réponses populaires ici, vous allez probablement découvrir que vous avez tué par inadvertance beaucoup de choses que vous ne vouliez pas vraiment perdre.
Guardius

1
J'avais d'autres fichiers non suivis - en plus de celui que la fusion / extraction voulait écraser, donc cette solution fonctionnait le mieux. git stash applya ramené tous mes fichiers non suivis à l'exception (à juste titre) de ceux que la fusion avait déjà créés: "existe déjà, pas de paiement". Fonctionne parfaitement.
BigBlueHat

2
C'est la réponse la plus claire, et devrait être celle qui est acceptée. Pour économiser quelques secondes, vous pouvez utiliser la forme abrégée: git stash -u.
ccpizza

93

Vous pourriez trouver cette commande utile pour supprimer les modifications locales:

git checkout <your-branch> -f

Et puis faites un nettoyage (supprime les fichiers non suivis de l'arborescence de travail):

git clean -f

Si vous souhaitez supprimer des répertoires non suivis en plus des fichiers non suivis:

git clean -fd

Je pense que la description du scénario indique clairement qu'il ne veut pas vraiment jeter le contenu. Ce qu'il veut plutôt, c'est cesser de git rechigner à écraser les fichiers. Voir ma suggestion.
Hedgehog

3
Bien que cette réponse ne corresponde pas exactement à la description, elle m'a quand même sauvé de la frustration de git twiddling avec les retours chariot (événement avec autocrlf false). Lorsque git reset --hard HEAD ne vous laisse pas avec "aucun" fichier modifié, ces drapeaux "-f" sont très utiles. Merci beaucoup.
Kellindil

88

Au lieu de fusionner avec git pull, essayez ceci:

git fetch --all

suivi par:

git reset --hard origin/master.


61

La seule chose qui a fonctionné pour moi était:

git reset --hard HEAD~5

Cela vous ramènera cinq commits, puis avec

git pull

J'ai trouvé cela en recherchant comment annuler une fusion Git .


C'est ce qui a finalement fonctionné pour moi car j'avais forcé ma branche à repo d'origine et continuais à obtenir des conflits de fusion lorsque j'essayais de le
ramener

Salut, en fait c'est un truc pour un work around mais vraiment efficace. Étant donné que certains conflits peuvent survenir juste en quelques validations, la restauration de 5 validations garantira l'absence de conflits avec le code distant.
Hoang Le

54

Le problème avec toutes ces solutions est qu'elles sont toutes trop complexes ou, encore plus grave, qu'elles suppriment tous les fichiers non suivis du serveur Web, ce que nous ne voulons pas car il y a toujours des fichiers de configuration nécessaires qui sont sur le serveur et non dans le référentiel Git.

Voici la solution la plus propre que nous utilisons:

# Fetch the newest code
git fetch

# Delete all files which are being added, so there
# are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • La première commande récupère les données les plus récentes.

  • La deuxième commande vérifie s'il y a des fichiers qui sont ajoutés au référentiel et supprime ces fichiers non suivis du référentiel local qui pourraient provoquer des conflits.

  • La troisième commande extrait tous les fichiers modifiés localement.

  • Enfin, nous faisons un pull pour mettre à jour vers la dernière version, mais cette fois sans conflits, car les fichiers non suivis qui sont dans le repo n'existent plus et tous les fichiers modifiés localement sont déjà les mêmes que dans le référentiel.


Utiliser "git merge origin / master" comme dernière ligne (comme vous le dites dans votre note) au lieu de "git pull" sera plus rapide car vous avez déjà supprimé toutes les modifications du git repo.
Josh

1
Oui, bien sûr, ce git merge origin/mastersera plus rapide et probablement encore plus sûr. Puisque si quelqu'un a poussé de nouveaux changements lors de la suppression des fichiers de ce script (ce qui n'est pas susceptible de se produire, mais possible), le pull complet pourrait échouer. La seule raison pour laquelle j'y mets pullest parce que quelqu'un ne travaille peut-être pas sur la branche principale, mais une autre branche et je voulais que le script soit universel.
Strahinja Kustudic

Si vous avez des fichiers créés localement comme des fichiers d'options, placez-les .gitignore.
Sebi

52

Tout d'abord, essayez la méthode standard:

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!

Attention : les commandes ci-dessus peuvent entraîner la perte de données / fichiers uniquement si vous ne les avez pas validées! Si vous n'êtes pas sûr, effectuez d'abord la sauvegarde de l'ensemble de votre dossier de référentiel.

Tirez-le ensuite à nouveau.

Si ci-dessus ne vous aide pas et que vous ne vous souciez pas de vos fichiers / répertoires non suivis (effectuez d'abord la sauvegarde au cas où), essayez les étapes simples suivantes:

cd your_git_repo  # where 'your_git_repo' is your git repository folder
rm -rfv *         # WARNING: only run inside your git repository!
git pull          # pull the sources again

Cela supprimera tous les fichiers git (excempt .git/dir, où vous avez tous les commits) et le tirera à nouveau.


Pourquoi git reset HEAD --hardpourrait échouer dans certains cas?

  1. Règles personnalisées dans .gitattributes file

    Ayant eol=lf règle dans .gitattributes pourrait amener git à modifier certaines modifications de fichier en convertissant les fins de ligne CRLF en LF dans certains fichiers texte.

    Si tel est le cas, vous devez valider ces modifications CRLF / LF (en les examinant dans git status), ou essayer: git config core.autcrlf falsede les ignorer temporairement.

  2. Incompabilité du système de fichiers

    Lorsque vous utilisez un système de fichiers qui ne prend pas en charge les attributs d'autorisation. Par exemple, vous avez deux référentiels, un sur Linux / Mac ( ext3/hfs+ ) et un autre sur un système de fichiers basé sur FAT32 / NTFS.

    Comme vous le remarquez, il existe deux types de systèmes de fichiers différents, donc celui qui ne prend pas en charge les autorisations Unix ne peut pas réinitialiser les autorisations de fichiers sur un système qui ne prend pas en charge ce type d'autorisations, donc peu importe comment --hardvous essayez, git toujours détecter certains "changements".


47

J'ai eu le même problème. Personne ne m'a donné cette solution, mais cela a fonctionné pour moi.

Je l'ai résolu en:

  1. Supprimez tous les fichiers. Laissez juste le .gitrépertoire.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Maintenant ça marche.


1
Pareil ici. Parfois, seule la solution très difficile fonctionne, il arrive souvent que seules la réinitialisation et le nettoyage ne suffisent pas en quelque sorte ...
jdehaan

41

Prime:

En parlant de pull / fetch / merge dans les réponses précédentes, je voudrais partager une astuce intéressante et productive,

git pull --rebase

Cette commande ci-dessus est la commande la plus utile de ma vie Git qui a permis de gagner beaucoup de temps.

Avant de pousser votre nouveau commit sur le serveur, essayez cette commande et elle synchronisera automatiquement les dernières modifications du serveur (avec un fetch + merge) et placera votre commit en haut dans le journal Git. Il n'y a aucun besoin de s'inquiéter de l'extraction / fusion manuelle.

Trouvez les détails dans Que fait "git pull --rebase"? .


3
En bref: git pull -r.
kenorb

29

J'avais un problème similaire. Je devais faire ça:

git reset --hard HEAD
git clean -f
git pull

6
à utiliser git cleanavec prudence
nategood

29

J'ai résumé d'autres réponses. Vous pouvez exécuter git pullsans erreurs:

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Avertissement : ce script est très puissant, vous pouvez donc perdre vos modifications.


2
Cela écrasera les fichiers modifiés (fichiers qui ont été précédemment archivés) et supprimera les fichiers non suivis (fichiers qui n'ont jamais été archivés). Exactement ce que je cherchais, merci!
styfle

3
Je soupçonne que la troisième ligne git reset --hard HEADpeut être redondante; ma page de manuel locale (2.6.3) dit qu'à resetla deuxième ligne git reset --hard origin/master "par défaut HEAD sous toutes ses formes".
arichards

2
@arichards Je pense que votre suspect a raison, mais si la deuxième ligne ne fonctionne pas (pour une raison quelconque), la troisième ligne fonctionne bien pour réinitialiser. Cette solution n'a pas besoin d'être optimisée. Je viens de résumer d'autres réponses. C'est tout. Merci pour votre commentaire. :)
Robert Moon

28

Sur la base de mes propres expériences similaires, la solution proposée par Strahinja Kustudic ci-dessus est de loin la meilleure. Comme d'autres l'ont souligné, une simple réinitialisation matérielle supprimera tout les fichiers non suivis qui pourraient inclure de nombreuses choses que vous ne souhaitez pas supprimer, telles que les fichiers de configuration. Ce qui est plus sûr, c'est de ne supprimer que les fichiers qui sont sur le point d'être ajoutés, et d'ailleurs, vous voudrez probablement retirer tous les fichiers modifiés localement qui sont sur le point d'être mis à jour.

Dans cet esprit, j'ai mis à jour le script de Kustudic pour faire exactement cela. J'ai également corrigé une faute de frappe (une manquante 'dans l'original).

#/bin/sh

# Fetch the newest code
git fetch

# Delete all files which are being added,
# so there are no conflicts with untracked files
for file in `git diff HEAD..origin/master --name-status | awk '/^A/ {print $2}'`
do
    echo "Deleting untracked file $file..."
    rm -vf "$file"
done

# Checkout all files which have been locally modified
for file in `git diff HEAD..origin/master --name-status | awk '/^M/ {print $2}'`
do
    echo "Checking out modified file $file..."
    git checkout $file
done

# Finally merge all the changes (you could use merge here as well)
git pull

Utiliser "git merge origin / master" comme dernière ligne (comme vous le dites dans votre note) au lieu de "git pull" sera plus rapide car vous avez déjà supprimé toutes les modifications du git repo.
Josh

La récupération des fichiers modifiés est nécessaire, cela fonctionne donc 100% des fois. J'ai mis à jour mon script avec cela il y a longtemps, mais j'ai également oublié de le mettre à jour ici. Je l'utilise aussi un peu différemment de vous. Je vérifie les fichiers qui ont tout type de modification, pas seulement M, donc ça marche tout le temps.
Strahinja Kustudic

24

Je pense qu'il y a deux causes possibles de conflit, qui doivent être résolues séparément, et pour autant que je sache, aucune des réponses ci-dessus ne traite des deux:

  • Les fichiers locaux non suivis doivent être supprimés, manuellement (plus sûr) ou comme suggéré dans d'autres réponses, par git clean -f -d

  • Les validations locales qui ne sont pas sur la branche distante doivent également être supprimées. IMO la façon la plus simple d'y parvenir est de: git reset --hard origin/master(remplacer 'master' par la branche sur laquelle vous travaillez, et exécutez une git fetch originpremière)


22

Un moyen plus simple serait de:

git checkout --theirs /path/to/file.extension
git pull origin master

Cela remplacera votre fichier local par le fichier sur git


21

Il semble que la plupart des réponses se concentrent ici sur master branche; Cependant, il y a des moments où je travaille sur la même branche de fonctionnalité à deux endroits différents et je veux qu'un rebase dans l'un soit reflété dans l'autre sans beaucoup de sauts dans les cerceaux.

Sur la base d'une combinaison de la réponse de l' ARN et la réponse de torek à une question similaire , je suis venu avec ce qui fonctionne à merveille:

git fetch
git reset --hard @{u}

Exécutez cela à partir d'une branche et cela ne fera que réinitialiser votre branche locale à la version en amont.

Cela peut également être bien placé dans un git alias ( git forcepull):

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Ou, dans votre .gitconfigdossier:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Prendre plaisir!


Cette réponse est également intéressante car elle fonctionne quelle que soit la branche sur laquelle vous vous trouvez!
farine de feuilles

19

J'ai eu le même problème et pour une raison quelconque, même un git clean -f -dne le ferait pas. Voici pourquoi: pour une raison quelconque, si votre fichier est ignoré par Git (via une entrée .gitignore, je suppose), cela dérange toujours d'écraser cela avec une traction ultérieure , mais un nettoyage ne le supprimera pas, sauf si vous l'ajoutez -x.


19

Je connais une méthode beaucoup plus facile et moins douloureuse:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

C'est ça!


18

Je viens de résoudre cela moi-même en:

git checkout -b tmp # "tmp" or pick a better name for your local changes branch
git add -A
git commit -m 'tmp'
git pull
git checkout master # Or whatever branch you were on originally
git pull
git diff tmp

où la dernière commande donne une liste de vos modifications locales. Continuez à modifier la branche "tmp" jusqu'à ce qu'elle soit acceptable, puis fusionnez à nouveau sur master avec:

git checkout master && git merge tmp

Pour la prochaine fois, vous pouvez probablement gérer cela d'une manière plus propre en recherchant "git stash branch" bien que stash soit susceptible de vous causer des problèmes lors des premiers essais, alors essayez d'abord sur un projet non critique ...


17

J'ai une situation étrange que ni l'un git cleanni l' autre ne git resetfonctionne. Je dois supprimer le fichier en conflit git indexà l'aide du script suivant sur chaque fichier non suivi:

git rm [file]

Ensuite, je suis capable de tirer très bien.


16

git fetch --all && git reset --hard origin/master && git pull


14

Malgré la question d'origine, les meilleures réponses peuvent causer des problèmes aux personnes qui ont un problème similaire, mais ne veulent pas perdre leurs fichiers locaux. Par exemple, voir les commentaires d'Al-Punk et crizCraig.

La version suivante valide vos modifications locales dans une branche temporaire ( tmp), extrait la branche d'origine (ce que je suppose master) et fusionne les mises à jour. Vous pouvez le faire avec stash, mais j'ai trouvé qu'il est généralement plus facile d'utiliser simplement l'approche branche / fusion.

git checkout -b tmp
git add *; git commit -am "my temporary files"
git checkout master

git fetch origin master
git merge -s recursive -X theirs origin master

où nous supposons que l' autre référentiel est origin master.


13

Ces quatre commandes fonctionnent pour moi.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Pour vérifier / tirer après avoir exécuté ces commandes

git pull origin master

J'ai beaucoup essayé mais j'ai finalement réussi avec ces commandes.


2
"git branch -D master" supprime la branche. alors soyez prudent avec ça. Je préfère utiliser "git checkout origin / master -b <nouveau nom de la branche>" qui crée une nouvelle branche avec un nouveau nom et vous avez besoin de 3,4 lignes. Il est également recommandé d'utiliser également "git clean -f".
Chand Priyankara

13

Fais juste

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

Vous évitez ainsi tous les effets secondaires indésirables, comme la suppression de fichiers ou de répertoires que vous souhaitez conserver, etc.


12

Réinitialisez l'index et la tête origin/master, mais ne réinitialisez pas l'arborescence de travail:

git reset origin/master

J'ai personnellement trouvé cela très utile. Il conserve ensuite votre arbre de travail afin que vous puissiez le réintégrer. Pour mon problème, j'ai fait supprimer les mêmes fichiers que ceux ajoutés, il était donc bloqué. Bizarre, je sais.
Jason Sebring

12

Exigences:

  1. Suivez les changements locaux afin que personne ici ne les perde.
  2. Faites correspondre le référentiel local au référentiel d'origine distant.

Solution:

  1. Cachez les changements locaux.
  2. Récupérez avec un nettoyage des fichiers et des répertoires en ignorant .gitignore et réinitialisation matérielle à l' origine .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
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.