Comment puis-je forcer "git pull" à écraser les fichiers locaux?

comment forcer un écrasement de fichiers locaux sur un git pull ?

le scénario est le suivant:

  • un membre de l'équipe est en train de modifier 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 source)
  • ils m'envoient les images par courrier, plus tard,
  • j'Ajoute les images sous le contrôle des sources et les poussant à GitHub avec d'autres changements
  • ils ne peuvent pas tirer les mises à jour de GitHub parce que Git ne veut pas écraser leurs fichiers.

C'est l'erreur que j'obtiens:

error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge

comment forcer Git à les écraser? La personne est un concepteur - habituellement Je résous tous les conflits à la main, de sorte que le serveur a la version la plus récente qu'ils ont juste besoin de mettre à jour sur leur ordinateur.

5409
demandé sur JimHawkins 2009-07-14 18:58:15

30 réponses

Important: si vous avez des changements locaux, ils seront perdus. Avec ou sans l'option --hard , toute propagation locale qui n'a pas été poussée sera perdue. [*]

si vous avez des fichiers qui sont et non suivis par Git (par ex. Contenu utilisateur téléchargé), ces fichiers ne seront pas affectés.


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

git fetch --all

alors, 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 reformater quoi que ce soit.

puis le git reset réinitialise la branche principale à ce que vous venez de récupérer. L'option --hard modifie tous les fichiers de votre arborescence de travail pour faire correspondre les fichiers origin/master


"1519290920 de" Maintenir l'actuel local s'engage

[*] : il est à noter qu'il est possible de maintenir les propagations locales actuelles en créant une branche à partir de master avant 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 vieux commits seront conservés dans new-branch-to-save-current-commits .

changements non engagés

Non engagé les changements, cependant (même par étapes), seront perdus. Assurez-vous de cacher et de commettre tout ce dont vous avez besoin. Pour cela, vous pouvez exécuter ce qui suit:

git stash

et ensuite de réitérer ces changements non engagés:

git stash pop
7543
répondu RNA 2018-07-17 21:53:17

essayez ceci:

git reset --hard HEAD
git pull

il devrait faire ce que vous voulez.

774
répondu Travis Reeder 2017-01-14 15:10:38

avertissement: git clean supprime tous vos fichiers/répertoires Non tracés et ne peut pas être défait.


parfois juste clean -f n'aide pas. Dans le cas où vous avez des répertoires Non tracés, l'option-d est également nécessaire:

# WARNING: this can't be undone!

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

avertissement: git clean supprime tous vos fichiers/répertoires Non tracés et ne peut pas être défait.

envisager d'utiliser -n ( --dry-run ) drapeau. Cela vous montrera ce qui sera supprimé sans réellement 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
...
389
répondu David Avsajanishvili 2018-08-17 19:32:32

comme Hedgehog je pense que les réponses sont terribles. Mais si Hérisson de réponse pourrait être mieux, je ne pense pas que c'est aussi élégante qu'elle pourrait l'être. J'ai trouvé à faire c'est à l'aide de "chercher" et "fusion" avec une stratégie définie. Qui doit faire en sorte que vos modifications sont conservées tant qu'elles ne sont pas l'un des fichiers que vous essayez de forcer le remplacer.

Première validation de vos modifications

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

Puis récupérez les modifications et réécrivez s'il y a un conflit

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

"- X" est un nom d'option, et "leur" est la valeur pour cette option. Vous choisissez d'utiliser "leurs" changements, au lieu de" vos " changements s'il y a un conflit.

339
répondu Richard Kersey 2017-02-23 13:45:53

au lieu de:

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 tous les télécommandes et les branches si vous voulez réinitialiser à la branche origine/master n'est-ce pas?

242
répondu Johanneke 2016-09-14 09:46:30

Il ressemble à la meilleure façon est d'abord de faire:

git clean

pour supprimer tous les fichiers non tracés et continuer avec l'habituel git pull ...

124
répondu Jakub Troszok 2017-01-14 15:10:01

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'histoire 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-à-coup:

$ git stash clear

bien sûr si vous voulez retourner à ce que vous avez caché:

$ git stash list
...
$ git stash apply stash@{5}
99
répondu Hedgehog 2018-03-07 07:00:46

vous pourriez trouver cette commande utile pour jeter les changements locaux:

git checkout <your-branch> -f

et ensuite faire un nettoyage (supprime les fichiers non tracés de l'arbre de travail):

git clean -f

si vous voulez supprimer les répertoires Non tracés en plus des fichiers non tracés:

git clean -fd
86
répondu Vishal 2017-01-14 15:12:22

au lieu de fusionner avec git pull , essayez ceci:

git fetch --all

suivi de:

git reset --hard origin/master .

76
répondu Lloyd Moore 2018-03-21 07:21:12

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

git reset --hard HEAD~5

cela vous ramènera cinq commits et puis avec

git pull

j'ai trouvé qu'en regardant vers le haut comment annuler une fusion Git .

53
répondu Chris BIllante 2017-05-23 10:31:37

le problème avec toutes ces solutions est qu'elles sont toutes soit trop complexes, soit, un problème encore plus grand, est qu'elles suppriment tous les fichiers non tracés 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 pas dans le dépôt 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 }'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print }'`
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 dépôt et supprime les fichiers non tracés du dépôt local qui causeraient des conflits.

  • La troisième commande vérifie tous les fichiers qui ont été modifiés localement.

  • enfin nous faisons un pull pour mettre à jour vers la version la plus récente, mais cette fois sans conflits, depuis sans traces fichiers 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.

50
répondu Strahinja Kustudic 2014-05-23 21:14:30

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 par:

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

maintenant ça marche.

38
répondu John John Pichler 2014-05-23 21:09:53

tout d'abord, essayer la voie standard:

git reset HEAD --hard # Remove all not committed changes

Si ci-dessus ne vous aidera pas et que vous ne vous souciez pas de vos fichiers/répertoires non suivis (faites la sauvegarde d'abord juste 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 va supprimer tous les fichiers git (excempt .git/ dir, où vous avez tous les commits) et tirez à nouveau.


pourquoi git reset HEAD --hard pourrait échouer dans certains cas?

  1. règles Personnalisées dans .gitattributes file

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

    si c'est le cas, vous devez effectuer ces changements de CRLF/LF (en les passant en revue dans git status ), ou essayer: git config core.autcrlf false pour les ignorer temporairement.

  2. fichier incapacité du système

    lorsque vous utilisez un système de fichiers qui ne supporte pas les attributs de permission. Par exemple, vous avez deux dépôts, un sur Linux/Mac ( ext3 / hfs+ ) et un autre sur le système de fichiers basé sur FAT32/NTFS.

    comme vous le remarquez, il y a deux types différents de systèmes de fichiers, donc celui qui ne supporte pas les permissions Unix ne peut pas réinitialiser les permissions de fichiers sur un système qui ne supporte pas ce genre de permissions, donc n'importe comment --hard vous essayez, git toujours détecter des "changements".

32
répondu kenorb 2015-09-30 08:30:43

j'ai eu un problème similaire. Je devais faire ceci:

git reset --hard HEAD
git clean -f
git pull
27
répondu Ryan 2011-11-06 16:35:34

j'ai résumé d'autres réponses. Vous pouvez exécuter git pull sans erreurs:

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

Warning : ce script est très puissant, donc vous pourriez perdre vos modifications.

26
répondu Robert Moon 2017-01-14 15:42: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 fait remarquer, le simple fait de réinitialiser dur supprimera tous les fichiers non tracés qui pourraient inclure beaucoup de choses que vous ne voulez pas supprimer, comme les fichiers de configuration. Ce qui est plus sûr, c'est de supprimer uniquement les fichiers qui sont sur le point d'être ajoutés, et d'ailleurs, vous voudrez probablement aussi vérifier tous les fichiers modifiés localement qui sont sur le point d'être ajoutés. mettre.

que dans l'esprit, j'ai mis à jour le script de Kustudic pour faire exactement cela. J'ai aussi corrigé une typographie (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 }'`
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 }'`
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
25
répondu Rolf Kaiser 2015-08-13 23:12:27

Bonus:

en parlant de pull / fetch / merge dans les réponses précédentes, je voudrais partager un truc intéressant et productif,

git pull --rebase

cette commande ci-dessus est la commande la plus utile dans ma vie Git qui a sauvé beaucoup de temps.

avant de pousser votre nouveau commit vers le serveur, essayez cette commande et il synchronisera automatiquement les dernières modifications du serveur (avec une fusion fetch+) et placera votre commit en haut du git log. Il n'y a pas besoin de s'inquiéter de la traction/fusion manuelle.

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

25
répondu Sazzad Hissain Khan 2018-04-27 13:02:41

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

  • les fichiers locaux qui ne sont pas tracés doivent être supprimés manuellement (plus sûrs) ou comme suggéré dans d'autres réponses, par git clean -f -d

  • modifications Locales, qui ne sont pas sur la télécommande de la branche doivent être supprimées. IMO la manière la plus facile de réalisez ceci avec: git reset --hard origin/master (remplacez "master" par n'importe quelle branche sur laquelle vous travaillez, et lancez un git fetch origin d'abord)

22
répondu tiho 2011-12-12 20:05:07

un moyen plus facile serait:

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

cela outrepassera votre fichier local avec le fichier sur git

20
répondu maximus 69 2015-05-05 08:03:29

il semble que la plupart des réponses ici sont axées sur la branche master ; cependant, il y a des moments où je travaille sur la même branche de fonctionnalité à deux endroits différents et je veux qu'une rebase dans l'un se reflète dans l'autre sans beaucoup de sauts à travers des cerceaux.

basé sur une combinaison de réponse de RNA et réponse de torek à une question similaire , j'ai trouvé ce qui fonctionne à merveille:

git fetch
git reset --hard @{u}

exécutez ceci à partir d'une branche et cela ne réinitialisera votre branche locale que vers la version amont.

cela peut être joliment mis dans un alias git ( git forcepull ) ainsi:

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

Ou, dans votre .gitconfig fichier:

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

Profitez-en!

19
répondu JacobEvelyn 2017-05-23 12:18:32

j'ai eu le même problème et pour une raison quelconque, même un git clean -f -d ne le ferait pas. Voici pourquoi: Pour une raison quelconque, si votre fichier est ignoré par Git (via un .gitignore entrée, je suppose), il se embête toujours sur l'écriture de ce avec un plus tard pull , mais un propre ne sera pas enlever, sauf si vous ajoutez -x .

18
répondu Tierlieb 2015-03-18 19:46:19

je viens de résoudre ce moi-même par:

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 des modifications locales. Continuez à modifier la branche "tmp" jusqu'à ce qu'elle soit acceptable, puis fusionnez avec:

git checkout master && git merge tmp

pour la prochaine fois, vous pouvez probablement gérer cela d'une manière plus propre en regardant vers le haut "git stash branch" bien stash est susceptible de vous causer des problèmes sur les premiers essais, alors faire la première expérience sur un non-critique projet...

17
répondu Simon B. 2017-01-14 15:13:29

j'ai une situation étrange que ni git clean ni git reset ne fonctionne. Je dois supprimer le fichier en conflit de git index en utilisant le script suivant sur chaque fichier non suivi:

git rm [file]

alors je suis capable de tirer très bien.

15
répondu Chen Zhang 2017-12-05 04:35:20

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 essayé beaucoup mais j'ai finalement eu du succès avec ces commandes.

13
répondu vishesh chandra 2014-03-20 04:24:02

malgré la question originale, les réponses les plus fréquentes peuvent causer des problèmes pour les personnes qui ont un problème similaire, mais qui ne veulent pas perdre leurs fichiers locaux. Par exemple, voir les commentaires D'Al-Punk et de crizCraig.

la version suivante propage vos modifications locales à une branche temporaire ( tmp ), vérifie la branche originale (qui je présume est master ) et fusionne les mises à jour. Vous pouvez faire cela avec stash , mais j'ai trouvé qu'il est généralement plus facile de utilisez 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 autre dépôt est origin master .

12
répondu Snowcrash 2015-03-18 19:43:07

Just do

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

donc vous évitez tous les effets secondaires indésirables, comme la suppression de fichiers ou de répertoires que vous vouliez garder, etc.

12
répondu user2696128 2017-01-14 15:48:47

réinitialiser l'indice et la tête en origin/master , mais ne pas réinitialiser l'arbre de travail:

git reset origin/master
11
répondu 2013-02-15 13:41:43

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!

10
répondu ddmytrenko 2018-09-05 16:52:42

j'ai lu toutes les réponses, mais je cherchais une seule commande pour ce faire. Voici ce que j'ai fait. Ajout d'un alias git .gitconfig

[alias]
      fp = "!f(){ git fetch   && git reset --hard /;};f"

Exécuter votre commande comme

git fp origin master

équivalent à

git fetch origin master
git reset --hard origin/master
9
répondu Venkat Kotra 2016-07-08 13:11:14

exigences:

    "151940920 de" Suivi des modifications locales de sorte que personne ne là jamais les perd.
  1. faire correspondre le dépôt local au dépôt d'origine à distance.

Solution:

  1. Stash les changements locaux.
  2. Fetch avec un propre de fichiers et répertoires ignorant .gitignore et hard reset à origine .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
9
répondu vezenkov 2017-01-14 15:44:53