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.
git reset --hard origin/branch_to_overwrite
git branch <branch> -D
2. Réinitialiser à un commit avant le conflit:git reset <commit> --hard
3. 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`git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .
Réponses:
Important: Si vous avez des modifications locales, elles seront perdues. Avec ou sans
--hard
option, 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:
Ensuite, vous avez deux options:
OU Si vous êtes sur une autre branche:
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 reset
réinitialise la branche principale à ce que vous venez de récupérer. L'--hard
option 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
master
avant de réinitialiser: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:
Et puis pour réappliquer ces modifications non validées:
la source
git reset --hard origin/branch-name
git pull -f
git reflog
, qui répertorie toutes les validations, y compris celles sans base. Jusqu'à ce que vous nettoyiez votre copie locale en utilisantgit gc
, alors tout est perduEssaye ça:
Il devrait faire ce que vous voulez.
la source
AVERTISSEMENT:
git clean
supprime 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:ATTENTION:
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 supprimer quoi que ce soit:Exemple de sortie:
la source
.gitignore
git clean -dfx
. Le-x
ignore .gitignore. Généralement, vos produits de build seront en .gitignore.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
Récupérez ensuite les modifications et remplacez-les en cas de conflit
"-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.
la source
get fetch other-repo
; 2)git merge -s recursive -X theirs other-repo/master
git merge -X theirs origin/master
Au lieu de faire:
Je vous conseille de faire ce qui suit:
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?
la source
git add .
abord, avantgit reset --hard
Il semble que la meilleure façon est de faire d'abord:
Pour supprimer tous les fichiers non suivis, puis continuer avec la procédure habituelle
git pull
...la source
git fetch origin && git reset --hard origin/master
git clean
la 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.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):
Plus tard, vous pouvez nettoyer l'historique de la cachette.
Manuellement, un par un:
Brutalement, tout à la fois:
Bien sûr, si vous voulez revenir à ce que vous avez caché:
la source
--include-untracked
simplement en temporairement temporairementgit add
l'intégralité de votre dépôt, puis en le cachant immédiatement.git stash apply
a 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.git stash -u
.Vous pourriez trouver cette commande utile pour supprimer les modifications locales:
Et puis faites un nettoyage (supprime les fichiers non suivis de l'arborescence de travail):
Si vous souhaitez supprimer des répertoires non suivis en plus des fichiers non suivis:
la source
Au lieu de fusionner avec
git pull
, essayez ceci:git fetch --all
suivi par:
git reset --hard origin/master
.la source
La seule chose qui a fonctionné pour moi était:
Cela vous ramènera cinq commits, puis avec
J'ai trouvé cela en recherchant comment annuler une fusion Git .
la source
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.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:
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.
la source
git merge origin/master
sera 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 metspull
est 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..gitignore
.Tout d'abord, essayez la méthode standard:
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:
Cela supprimera tous les fichiers git (excempt
.git/
dir, où vous avez tous les commits) et le tirera à nouveau.Pourquoi
git reset HEAD --hard
pourrait échouer dans certains cas?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 false
de les ignorer temporairement.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
--hard
vous essayez, git toujours détecter certains "changements".la source
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:
.git
répertoire.git reset --hard HEAD
git pull
git push
Maintenant ça marche.
la source
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"? .
la source
git pull -r
.J'avais un problème similaire. Je devais faire ça:
la source
git clean
avec prudenceJ'ai résumé d'autres réponses. Vous pouvez exécuter
git pull
sans erreurs:Avertissement : ce script est très puissant, vous pouvez donc perdre vos modifications.
la source
git reset --hard HEAD
peut être redondante; ma page de manuel locale (2.6.3) dit qu'àreset
la deuxième lignegit reset --hard origin/master
"par défaut HEAD sous toutes ses formes".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).
la source
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 unegit fetch origin
première)la source
Un moyen plus simple serait de:
Cela remplacera votre fichier local par le fichier sur git
la source
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:
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
.gitconfig
dossier:Prendre plaisir!
la source
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), 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
.la source
Je connais une méthode beaucoup plus facile et moins douloureuse:
C'est ça!
la source
Je viens de résoudre cela moi-même en:
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:
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 ...
la source
J'ai une situation étrange que ni l'un
git clean
ni l' autre negit reset
fonctionne. Je dois supprimer le fichier en conflitgit index
à l'aide du script suivant sur chaque fichier non suivi:Ensuite, je suis capable de tirer très bien.
la source
git fetch --all && git reset --hard origin/master && git pull
la source
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 supposemaster
) et fusionne les mises à jour. Vous pouvez le faire avecstash
, mais j'ai trouvé qu'il est généralement plus facile d'utiliser simplement l'approche branche / fusion.où nous supposons que l' autre référentiel est
origin master
.la source
Ces quatre commandes fonctionnent pour moi.
Pour vérifier / tirer après avoir exécuté ces commandes
J'ai beaucoup essayé mais j'ai finalement réussi avec ces commandes.
la source
Fais juste
Vous évitez ainsi tous les effets secondaires indésirables, comme la suppression de fichiers ou de répertoires que vous souhaitez conserver, etc.
la source
Réinitialisez l'index et la tête
origin/master
, mais ne réinitialisez pas l'arborescence de travail:la source
Exigences:
Solution:
Récupérez avec un nettoyage des fichiers et des répertoires en ignorant .gitignore et réinitialisation matérielle à l' origine .
la source