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.
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
essayez ceci:
git reset --hard HEAD
git pull
il devrait faire ce que vous voulez.
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
...
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.
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?
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
...
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}
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
au lieu de fusionner avec git pull
, essayez ceci:
git fetch --all
suivi de:
git reset --hard origin/master
.
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 .
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.
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:
- suppression de tous les fichiers. Laissez juste le .répertoire git.
-
git reset --hard HEAD
-
git pull
-
git push
maintenant ça marche.
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?
-
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. -
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".
j'ai eu 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 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.
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
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"? .
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 ungit fetch origin
d'abord)
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
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!
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
.
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...
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.
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.
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
.
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.
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!
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
exigences:
- "151940920 de" Suivi des modifications locales de sorte que personne ne là jamais les perd.
- faire correspondre le dépôt local au dépôt d'origine à distance.
Solution:
- Stash les changements locaux.
-
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