Comment forcer un écrasement de fichiers locaux sur un git pull
?
Le scénario est le suivant:
C'est l'erreur que j'obtiens:
erreur: le fichier d'arbre de travail non suivi 'public/images/icon.gif' serait écrasé par la fusion
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 dont ils ont juste besoin pour mettre à jour leur ordinateur.
--hard
, tous les commits locaux qui n'ont pas été poussés seront perdus.[*]Si vous avez des fichiers qui sont non 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>
git fetch
télécharge le dernier depuis la télécommande sans essayer de fusionner ou de rebaser quoi que ce soit.
Ensuite, 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 arbre de travail afin qu'ils correspondent aux fichiers de Origin/master
[*]: Il est intéressant de noter qu’il est possible de maintenir les commits locaux actuels 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 anciens commits seront conservés dans new-branch-to-save-current-commits
.
Les modifications non engagées, cependant (même programmées), 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 ensuite, pour réappliquer ces modifications non validées:
git stash pop
Essaye ça:
git reset --hard HEAD
git pull
Il faut faire ce que tu veux.
AVERTISSEMENT: git clean
supprime tous vos fichiers/répertoires non suivis et ne peut pas être annulé.
Parfois, seul clean -f
n'aide pas. Si vous avez des répertoires non suivis, l'option -d est également requise:
# 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 suivis et ne peut pas être annulé.
Pensez à utiliser le drapeau -n
(--dry-run
) en premier. Cela vous montrera ce qui sera supprimé sans rien supprimer:
git clean -n -f -d
Exemple de sortie:
Would remove untracked-file-1.txt
Would remove untracked-file-2.txt
Would remove untracked/folder
...
Comme Hérisson, je pense que les réponses sont terribles. Mais bien que la réponse de Hedgehog soit peut-être meilleure, je ne pense pas qu'elle soit aussi élégante qu'elle pourrait l'être. Pour ce faire, j'ai utilisé "fetch" et "fusion" 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 un remplacement.
git add *
git commit -a -m "local file server commit message"
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.
Au lieu de faire:
git fetch --all
git reset --hard Origin/master
Je conseillerais de faire ce qui suit:
git fetch Origin master
git reset --hard Origin/master
Pas besoin d'aller chercher toutes les télécommandes et les branches si vous allez réinitialiser à l'origine/branche principale non?
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
...
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
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}
Vous pouvez trouver cette commande utile pour éliminer les modifications locales:
git checkout <your-branch> -f
Et puis faites 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
Au lieu de fusionner avec git pull
, essayez ceci:
git fetch --all
suivi par:
git reset --hard Origin/master
.
La seule chose qui a fonctionné pour moi a été:
git reset --hard HEAD~5
Cela vous ramènera cinq commits et ensuite avec
git pull
J'ai trouvé qu'en regardant comment annuler une fusion Git .
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 qui sont stockés. 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 tous les fichiers localement modifiés sont déjà les mêmes que dans le référentiel.
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!
Avertissement: 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, faites d'abord la sauvegarde de l'intégralité de votre dossier de référentiel.
Puis tirez à nouveau.
Si ci-dessus ne vous aide pas et que vous ne vous souciez pas de vos fichiers/répertoires non suivis (effectuez la sauvegarde en premier lieu 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 le tirer à nouveau.
Pourquoi git reset HEAD --hard
pourrait échouer dans certains cas?
Règles personnalisées dans .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 git status
), ou essayez: git config core.autcrlf false
de les ignorer temporairement.
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 sous Linux/Mac (ext3
/hfs+
) et un autre sur le système de fichiers 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 réinitialiser les autorisations de fichiers sur un système ne prenant pas en charge ce type d'autorisations. Par conséquent, --hard
vous essayez, git détecte toujours des "modifications".
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:
.git
.git reset --hard HEAD
git pull
git Push
Maintenant ça marche.
J'avais un problème similaire. Je devais faire ceci:
git reset --hard HEAD
git clean -f
git pull
J'ai résumé d'autres réponses. Vous pouvez exécuter git pull
sans erreur:
git fetch --all
git reset --hard Origin/master
git reset --hard HEAD
git clean -f -d
git pull
Attention : Ce script est très puissant, vous risquez donc de perdre vos modifications.
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
Je crois qu'il existe 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 validations locales qui ne se trouvent pas sur la branche distante doivent également être supprimées. Le moyen le plus simple d'y parvenir est d'utiliser: git reset --hard Origin/master
(remplacez 'maître' par la branche sur laquelle vous travaillez et exécutez d'abord un git fetch Origin
)
Un moyen plus simple serait de:
git checkout --theirs /path/to/file.extension
git pull Origin master
Cela remplacera votre fichier local avec le fichier sur git
Il semble que la plupart des réponses ici se concentrent sur la branche master
; Cependant, il arrive que je travaille sur la même branche dans deux endroits différents et que je souhaite qu'un rebase dans l'un se répercute sur l'autre sans trop de sauts.
Sur la base d'une combinaison de la réponse de l'ARN et de la réponse de torek à une question similaire , j'ai trouvé ceci qui fonctionne à merveille:
git fetch
git reset --hard @{u}
Exécutez ceci depuis une branche et cela ne réinitialisera votre branche locale que vers la version en amont.
Cela peut également être mis dans un alias de git (git forcepull
):
git config alias.forcepull "!git fetch ; git reset --hard @{u}"
Ou, dans votre fichier .gitconfig
:
[alias]
forcepull = "!git fetch ; git reset --hard @{u}"
Prendre plaisir!
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 une entrée .gitignore, je suppose), il est toujours dérangeant de remplacer cela par un pull , mais un clean ne sera pas supprimez-le, sauf si vous ajoutez -x
.
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 "branche git stash", 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 ...
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]
Ensuite, je peux bien tirer.
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 tout!
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.
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, comme la suppression de fichiers ou de répertoires que vous souhaitez conserver, etc.
Malgré la question initiale, les réponses les plus fréquentes peuvent poser problème aux personnes confrontées au même problème mais ne voulant pas perdre leurs fichiers locaux. Par exemple, voir les commentaires de Al-Punk et crizCraig.
La version suivante valide vos modifications locales dans une branche temporaire (tmp
), extrait la branche d'origine (qui, je suppose, est 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 la méthode 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 référentiel est Origin master
.
Réinitialisez l'index et la tête à Origin/master
, mais ne réinitialisez pas l'arbre de travail:
git reset Origin/master
Exigences:
Solution:
Récupérer avec un nettoyer de fichiers et répertoires ignoring .gitignore et réinitialisation matérielle à Origine .
git stash --include-untracked
git fetch --all
git clean -fdx
git reset --hard Origin/master
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
N'utilisez pas git reset --hard
. Cela effacera leurs modifications qui pourraient bien être totalement indésirables. Au lieu:
git pull
git reset Origin/master
git checkout <file1> <file2> ...
Vous pouvez bien sûr utiliser git fetch
au lieu de git pull
puisqu'il ne va clairement pas fusionner, mais si vous tirez, il est logique de continuer à tirer ici.
Donc, ce qui se passe ici, c'est que git pull
met à jour votre référence d'origine/maître ; git reset
met à jour votre référence de branche locale on pour qu'elle soit identique à Origin/master sans mettre à jour aucun fichier, votre état d'extraction n'est donc pas modifié; alors git checkout
rétablit les fichiers dans l'état d'index de votre branche locale selon les besoins. Dans les cas où exactement le même fichier a été ajouté sur le maître en direct et en amont, l'index correspond déjà au fichier après la réinitialisation. Ainsi, dans le cas habituel, vous n'avez pas besoin de faire git checkout
du tout.
Si la branche en amont contient également des commits que vous souhaitez appliquer automatiquement, vous pouvez suivre une variation subtile du processus:
git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
C’est la meilleure pratique pour annuler des modifications:
git commit
Validez vos modifications par étapes afin qu’elles soient sauvegardées dans le reflog (voir ci-dessous).git fetch
Récupère les dernières modifications en amontgit reset --hard Origin/master
Réinitialisation matérielle à la branche maître d'origineLe reflogbranches d’enregistrements et autres références en cours de mise à jour dans le référentiel local. Ou simplement - le reflog est le historique de vos modifications.
C'est donc toujours une bonne pratique de s'engager. Les commits sont ajoutés au refog, ce qui garantit que vous aurez toujours le moyen de récupérer le code supprimé.
J'ai utilisé cette commande pour supprimer les fichiers locaux m'empêchant d'effectuer une extraction/fusion. Mais fais attention! Exécutez d'abord git merge …
pour voir s'il n'y a que les fichiers que vous voulez vraiment supprimer.
git merge Origin/master 2>&1 >/dev/null | grep ^[[:space:]] | sed s/^[[:space:]]//g | xargs -L1 rm
git merge
liste entre autres tous ces fichiers. Ils sont précédés par des espaces blancs.2>&1 >/dev/null
redirige la sortie d'erreur vers la sortie standard afin qu'elle soit récupérée par grep
.grep ^[[:space:]]
ne filtre que les lignes portant des noms de fichier.sed s/^[[:space:]]//g
coupe l'espace blanc depuis le début.xargs -L1 rm
appelle rm
sur chacun de ces fichiers, en les supprimant.Manipuler avec précaution: Quel que soit le résultat de git merge
, la rm
sera appelée pour chaque ligne commençant par un espace.
J'essayais d'utiliser la branche Material2 sur Angular2-Webpack-Starter et j'ai passé un sacré bout de temps. C’est la seule façon pour moi de télécharger et d’utiliser cette branche.
git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git
cd angular2-webpack-starter/
git checkout -b material2
Ouvrez le dossier du projet et supprimez tous les fichiers et dossiers non cachés. Laissez tous les cachés.
git add .
git commit -m "pokemon go"
git reset --hard
git pull Origin material2
(Lorsque l'éditeur apparaît, appuyez sur ': wq', puis appuyez sur Enter)
Maintenant tu es prêt.
Sous Windows, effectuez cette commande unique:
git fetch --all & git reset --hard Origin/master
Vous pouvez ignorer ce fichier avec un fichier dans le dossier de base de votre projet:
.gitignore
public/images/*
Extrayez ensuite les modifications puis supprimez cette ligne de votre fichier gitignore.
git fetch --all && git reset --hard Origin/master && git pull
1: réinitialiser un commit précédent
git reset --hard HEAD
2: Supprimer les fichiers non suivis
git clean -f
3: tire les commits
git pull
Sources:
Tu pourrais essayer
git pull --force
si vous voulez écraser tous les fichiers locaux
git fetch --all
alors si vous êtes sur la branche principale
git reset --hard Origin/master
else
git reset --hard Origin/master<branch_name>
si vous souhaitez réinitialiser la branche de suivi à distance de manière générique, utilisez:
git fetch
git reset --keep Origin/$(git rev-parse --abbrev-ref HEAD)
si vous souhaitez également réinitialiser vos modifications locales:
git fetch
git reset --hard Origin/$(git rev-parse --abbrev-ref HEAD)