git - échoué - veuillez valider ou remiser vos modifications avant la fusion.




Comment forcer "git pull" à écraser les fichiers locaux? (20)

Comment forcer un écrasement de 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 code source)
  • Ils envoient les images par courrier, plus tard, à moi
  • J'ajoute les images sous le contrôle de code source et les envoie à GitHub avec d'autres modifications
  • Ils ne peuvent pas extraire les mises à jour de GitHub car 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 puis-je forcer Git à les écraser? La personne est un concepteur. En règle générale, je résous tous les conflits à la main. Le serveur dispose donc de la version la plus récente qu'il ne lui reste plus qu'à mettre à jour sur son ordinateur.


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

Si certains fichiers ne font pas l'objet d'un suivi 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, la git reset réinitialise la branche principale sur ce que vous venez de récupérer. L'option --hard change tous les fichiers de votre arbre de travail pour qu'ils correspondent aux fichiers d' origin/master

Maintenir les commits locaux actuels

[*] : Il est intéressant de noter qu'il est possible de conserver les commits locaux actuels en créant une branche à partir du 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 anciens commits seront conservés dans les commits new-branch-to-save-current-commits .

Changements non validés

Les modifications non validées, cependant (même par étapes), seront perdues. Assurez-vous de cacher et de commettre tout ce dont vous avez besoin. Pour cela, vous pouvez exécuter les tâches suivantes:

git stash

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

git stash pop

Prime:

En parlant de pull / fetch / fusion dans les réponses précédentes, je voudrais partager un tour intéressant et productif,

git pull --rebase

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

Avant d’appliquer votre nouveau commit sur le serveur, essayez cette commande. Elle synchronisera automatiquement les dernières modifications du serveur (avec une extraction + une fusion) et placera votre commit en haut du journal Git. Il n'y a pas besoin de s'inquiéter de l'extraction / fusion manuelle.

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


Au lieu de fusionner avec git pull , essayez ceci:

git fetch --all

suivi par:

git reset --hard origin/master .


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 / extraire 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.


Essaye ça:

git reset --hard HEAD
git pull

Il faut faire ce que tu veux.


Exigences:

  1. Suivez les changements locaux pour que personne ici ne les perde jamais.
  2. Faites en sorte que le référentiel local corresponde 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 une réinitialisation matérielle à l' origine .

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    

Il semble que le meilleur moyen consiste à faire d'abord:

git clean

Pour supprimer tous les fichiers non suivis, puis continuez avec le git pull habituel de git pull ...


Il suffit de faire

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

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


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. Ne laissez que le répertoire .git.
  2. git reset --hard HEAD
  3. git pull
  4. git push

Maintenant ça marche.


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

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

Exécuter votre commande en tant que

git fp origin master

équivalent à

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

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

git rm [file]

Ensuite, je peux bien tirer.


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

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

Je crois 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, soit manuellement (plus sûr), soit comme suggéré dans d'autres réponses, par git clean -f -d

  • Les commits locaux qui ne se trouvent pas sur la branche distante doivent également être supprimés. Le moyen le plus simple d'y parvenir est avec: git reset --hard origin/master (remplacez 'master' par la branche sur laquelle vous travaillez et lancez d'abord une git fetch origin )


Je viens de résoudre ce problème 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 de vos changements locaux. Continuez à modifier la branche "tmp" jusqu'à ce qu'elle soit acceptable, puis rejoignez Master avec:

git checkout master && git merge tmp

Pour la prochaine fois, vous pouvez probablement gérer cela de manière plus propre en recherchant "git stash branch", bien que stash risque de vous causer des problèmes lors des premiers essais. Faites donc votre première expérience sur un projet non critique ...


Le problème de toutes ces solutions est qu’elles sont toutes trop complexes ou, bien plus, qu’elles suppriment tous les fichiers non suivis du serveur Web, ce que nous ne souhaitons pas, car nous avons toujours besoin des fichiers de configuration en cours. 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 si des fichiers sont ajoutés au référentiel et supprime les fichiers non suivis du référentiel local, ce qui provoquerait des conflits.

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

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


Malgré la question initiale, les réponses les plus fréquentes peuvent poser problème aux personnes confrontées à un problème similaire, mais ne veulent pas perdre leurs fichiers locaux. Par exemple, voir les commentaires de Al-Punk et crizCraig.

La version suivante enregistre vos modifications locales dans une branche temporaire ( tmp ), extrait la branche d'origine (ce qui, je suppose, est la master ) et fusionne les mises à jour. Vous pouvez le faire avec stash , mais j’ai trouvé qu’il était généralement plus simple 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 .


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, une simple réinitialisation matérielle supprime tous les fichiers non suivis, qui peuvent contenir 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 sur le point d’être ajoutés. En outre, vous voudrez probablement également extraire 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 aussi corrigé une faute de frappe (un 'manquant 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

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

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

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 va supprimer tous les fichiers git (excempt .git/ dir, où vous avez tous les commits) et les extraire à nouveau.

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

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

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

    Si c'est le cas, vous devez valider ces modifications CRLF / LF (en les examinant dans le git status ), ou essayez: git config core.autcrlf false pour les ignorer temporairement.

  2. Incompatibilité 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 le système de fichiers basé sur FAT32 / NTFS.

    Comme vous le constatez, il existe deux types de systèmes de fichiers différents. Ainsi, celui qui ne prend pas en charge les autorisations Unix ne peut pas en principe réinitialiser les autorisations de fichiers sur un système ne --hard pas en charge ce type d'autorisations. essayez, git détecte toujours certains "changements".


Vous pouvez trouver cette commande utile pour éliminer les modifications locales:

git checkout <your-branch> -f

Et effectuez ensuite un nettoyage (supprime les fichiers non suivis de l’arbre de travail):

git clean -f

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

git clean -fd

Attention, ceci effacera définitivement vos fichiers si vous avez des entrées directory / * dans votre fichier gitignore.

Certaines réponses semblent être 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 pourrez nettoyer l'historique des cachettes.

Manuellement, un par un:

$ git stash list
[email protected]{0}: WIP on <branch>: ...
[email protected]{1}: WIP on <branch>: ...

$ git stash drop [email protected]{0}
$ git stash drop [email protected]{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 [email protected]{5}




git-fetch