Как заставить "git pull" перезаписать локальные файлы?
Как заставить перезаписать локальные файлы на git pull
?
сценарий следующий:
- член команды изменяет шаблоны для веб-сайта, над которым мы работаем
- они добавляют некоторые изображения в каталог изображений (но забывает добавить их под управлением исходного кода)
- они посылают изображения по почте, позже, мне
- я добавляю изображения под управлением источника и нажимаю их на GitHub вместе с другие изменения
- они не могут извлекать обновления из GitHub, потому что Git не хочет перезаписывать свои файлы.
Это ошибка, которую я получаю:
error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge
Как заставить Git перезаписать их? Человек-дизайнер-обычно я разрешаю все конфликты вручную, поэтому у сервера есть самая последняя версия, которую им просто нужно обновить на своем компьютере.
30 ответов:
важно: если у вас есть какие-либо изменения, они будут утеряны. С или без
--hard
опция, любые локальные коммиты, которые не были нажаты, будут потеряны.[*]если у вас есть какие-либо файлы не отслеживается Git (например, загруженный пользовательский контент), эти файлы не будут затронуты.
я думаю, что это правильно:
git fetch --all
затем, у вас есть два варианта:
git reset --hard origin/master
или если вы находитесь на какая-то другая ветка:
git reset --hard origin/<branch_name>
объяснение:
git fetch
загружает последнюю версию с пульта дистанционного управления, не пытаясь объединить или перебазировать что-либо.тут
git reset
сбрасывает главную ветвь к тому, что вы только что выбрали. Элемент--hard
опция изменяет все файлы в вашем рабочем дереве, чтобы соответствовать файлам вorigin/master
поддерживать текущие локальные коммиты
[*]: стоит отметить, что можно поддерживайте текущие локальные коммиты, создавая ветку из
master
работает:git checkout master git branch new-branch-to-save-current-commits git fetch --all git reset --hard origin/master
после этого, все старые коммиты будут храниться в
new-branch-to-save-current-commits
.незафиксированные изменения
незафиксированные изменения, однако (даже постановочные), будут потеряны. Убедитесь в том, чтобы спрятать и совершить все, что вам нужно. Для этого вы можете запустить следующее:
git stash
а затем применить эти незафиксированные изменения:
git stash pop
предупреждение:
git clean
удалить все неотслеживаемые файлы/директории и не может быть отменено.
иногда просто
clean -f
не помогает. В случае, если у вас есть неотслеженные каталоги, - D опция также необходима:# WARNING: this can't be undone! git reset --hard HEAD git clean -f -d git pull
предупреждение:
git clean
удалить все неотслеживаемые файлы/директории и не может быть отменено.рассмотрите возможность использования
-n
(--dry-run
) первый флаг. Это покажет вам, что будет удалено без На самом деле удаление чего-либо:git clean -n -f -d
пример:
Would remove untracked-file-1.txt Would remove untracked-file-2.txt Would remove untracked/folder ...
как еж я думаю, что ответы ужасны. Но хотя ответ ежика может быть лучше, я не думаю, что это так элегантно, как могло бы быть. Я нашел способ сделать это, используя "fetch" и "merge" с определенной стратегией. Что должно сделать так, чтобы ваши локальные изменения сохранялись до тех пор, пока они не являются одним из файлов, которые вы пытаетесь принудительно перезаписать.
сначала сделайте фиксацию ваших изменений
git add * git commit -a -m "local file server commit message"
затем извлеките изменения и перезаписать, если есть конфликт
git fetch origin master git merge -s recursive -X theirs origin/master
" - X "- это имя опции, а" их " - это значение для этой опции. Вы выбираете использовать" их "изменения, а не" ваши " изменения, если есть конфликт.
вместо:
git fetch --all git reset --hard origin/master
Я бы посоветовал сделать следующее:
git fetch origin master git reset --hard origin/master
нет необходимости извлекать все пульты дистанционного управления и ветви, если вы собираетесь сбросить в исходную/главную ветвь правильно?
похоже, самый лучший способ это сначала сделать:
git clean
чтобы удалить все неотслеженные файлы, а затем продолжить с обычным
git pull
...
некоторые ответы кажутся ужасными. Ужасно в смысле того, что случилось с @Lauri, следуя предложению Давида Авсаджанишвили.
скорее (git > v1.7. 6):
git stash --include-untracked git pull
позже вы можете очистить историю заначку.
вручную, один за другим:
$ git stash list stash@{0}: WIP on <branch>: ... stash@{1}: WIP on <branch>: ... $ git stash drop stash@{0} $ git stash drop stash@{1}
жестоко, все-сразу:
$ git stash clear
конечно, если вы хотите, чтобы вернуться к тому, что вы спрятали:
$ git stash list ... $ git stash apply stash@{5}
вы можете найти эту команду полезной, чтобы выбросить локальные изменения:
git checkout <your-branch> -f
а затем выполните очистку (удаляет неотслеженные файлы из рабочего дерева):
git clean -f
Если вы хотите удалить игнорируемых каталогов в дополнение к неотслеживаемые файлы:
git clean -fd
единственное, что работал для меня было:
git reset --hard HEAD~5
это вернет вам пять коммитов, а затем с
git pull
Я нашел это, посмотрев вверх как отменить слияние Git.
проблема со всеми этими решениями заключается в том, что все они либо слишком сложны, либо, еще большая проблема, заключается в том, что они удаляют все неотслеженные файлы с веб-сервера, чего мы не хотим, поскольку всегда есть необходимые файлы конфигурации, которые находятся на сервере, а не в репозитории Git.
здесь самое чистое решение, которое мы используем:
# 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
первая команда загружает новые данные.
второй команда проверяет, есть ли какие-либо файлы, которые добавляются в репозиторий, и удаляет эти неотслеженные файлы из локального репозитория, которые могут вызвать конфликты.
третья команда проверяет все файлы, которые были изменены локально.
наконец, мы делаем запрос на обновление до последней версии, но на этот раз без каких-либо конфликтов, так как неотслеженные файлы, которые находятся в репо, больше не существуют, и все локально измененные файлы уже то же самое, что и в репозитории.
у меня была та же проблема. Никто не дал мне это решение, но оно сработало для меня.
я решил это с помощью:
- удаление всех файлов. Оставь только свое .каталог git.
git reset --hard HEAD
git pull
git push
Теперь все работает.
прежде всего, попробуйте стандартный способ:
git reset HEAD --hard # Remove all not committed changes
если выше не поможет и вы не заботитесь о свой неотслеживаемый файлы/каталоги (сделайте резервную копию на всякий случай), попробуйте следующие простые шаги:
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
это приведет к удалению всех файлов git (excempt
.git/
dir, где у вас есть все коммиты) и потяните его снова.
почему
git reset HEAD --hard
может потерпеть неудачу в некоторых случаях?
пользовательские правила в
.gitattributes file
С
eol=lf
правило .gitattributes может привести к тому, что git изменит некоторые изменения файла путем преобразования окончаний строк CRLF в LF в некоторых текстовых файлах.если это так, вы должны зафиксировать эти изменения CRLF/LF (просмотрев их в
git status
), или попробовать:git config core.autcrlf false
временно игнорировать их.несовместимость файловой системы
когда вы используете файловую систему, которая не поддерживает атрибутами разрешения. В пример вам есть два репозитория, один на Linux / Mac (
ext3
/hfs+
) и еще один на основе файловой системы FAT32/NTFS.как вы заметили, существует два разных типа файловых систем, поэтому тот, который не поддерживает разрешения Unix, в основном не может сбросить разрешения на файлы в системе, которая не поддерживает такого рода разрешения, поэтому независимо от того, как
--hard
вы пытаетесь, git всегда обнаруживают некоторые "изменения".
я суммировал другие ответы. Вы можете выполнить
git pull
без ошибок:git fetch --all git reset --hard origin/master git reset --hard HEAD git clean -f -d git pull
предупреждение: данный скрипт очень мощный, так что вы можете потерять ваши изменения.
основываясь на моем собственном подобном опыте, решение, предложенное Страхиньей Кустудич выше, безусловно, является лучшим. Как указывали другие, просто выполнение жесткого сброса удалит все неотслеженные файлы, которые могут включать в себя множество вещей, которые вы не хотите удалять, например файлы конфигурации. Что безопаснее, так это удалить только те файлы, которые будут добавлены, и, если на то пошло, вы, вероятно, также захотите проверить любые локально измененные файлы, которые будут усовершенствованный.
что в виду, я обновил сценарий Кустудича, чтобы сделать именно это. Я также исправил опечатку (отсутствует ' в оригинале).
#/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
бонус:
говоря о pull / fetch / merge в предыдущих ответах, я хотел бы поделиться интересным и продуктивным трюком,
git pull --rebase
эта команда выше является самой полезной командой в моей жизни Git, которая сэкономила много времени.
перед тем, как нажимать новую фиксацию на сервер, попробуйте эту команду, и она автоматически синхронизирует последние изменения сервера (с помощью fetch + merge) и разместит вашу фиксацию на сверху в журнале Git. Нет никакой необходимости беспокоиться о ручном вытягивании / слиянии.
найти подробную информацию в что делает "git pull -- rebase"?.
Я считаю, что есть две возможные причины конфликта, которые должны быть решены отдельно, и, насколько я могу судить, ни один из приведенных выше ответов не касается обоих:
локальные файлы, которые не отслеживаются, должны быть удалены вручную (безопаснее) или, как предлагается в других ответах,
git clean -f -d
локальные коммиты, которые не находятся на удаленной ветке, также должны быть удалены. ИМО самый простой способ добиться этого-это:
git reset --hard origin/master
(заменить 'master' по какой бы ветке вы ни работали, и запуститеgit fetch origin
первая)
проще было бы:
git checkout --theirs /path/to/file.extension git pull origin master
это переопределит ваш локальный файл с файлом на git
похоже, что большинство ответов здесь сосредоточены на
master
ветвь; однако бывают случаи, когда я работаю над одной и той же ветвью функции в двух разных местах, и я хочу, чтобы ребаз в одном отражался в другом без большого количества прыжков через обручи.на основе сочетания ответ РНК и ответ торека на аналогичный вопрос, я придумал это, что работает великолепно:
git fetch git reset --hard @{u}
запустите это из ветки и это только сбросит вашу локальную ветвь в вышестоящую версию.
это можно красиво поместить в псевдоним git (
git forcepull
), а также:
git config alias.forcepull "!git fetch ; git reset --hard @{u}"
или в
.gitconfig
file:[alias] forcepull = "!git fetch ; git reset --hard @{u}"
наслаждайтесь!
у меня была такая же проблема и по каким-то причинам, даже
git clean -f -d
не сделал бы этого. Вот почему: по какой-то причине, если ваш файл игнорируется Git (через a .gitignore запись, я полагаю), он все еще беспокоится о перезаписи этого с более поздним тянуть, а очистить не будет удалять его, если вы не добавите-x
.
Я просто решил это сам:
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
где последняя команда дает список того, что локальные изменения были. Продолжайте изменять ветвь "tmp", пока она не станет приемлемой, а затем слейте обратно на master с помощью:
git checkout master && git merge tmp
у меня странная ситуация, что ни
git clean
илиgit reset
строительство. Я должен удалить конфликтующий файл изgit index
используя следующий скрипт для каждого неотслеживаемого файла:git rm [file]
тогда я могу тянуть просто замечательно.
эти четыре команды работают для меня.
git reset --hard HEAD git checkout origin/master git branch -D master git checkout -b master
чтобы проверить/подтянуть после выполнения этих команд
git pull origin master
Я много пробовал, но в конце концов добился успеха с этими командами.
несмотря на исходный вопрос, верхние ответы могут вызвать проблемы для людей, которые имеют аналогичную проблему, но не хотят терять свои локальные файлы. Например, см. комментарии Al-Punk и crizCraig.
следующая версия нарушает ваши локальные изменения во временную ветку (
tmp
), проверяет исходную ветвь (которую я предполагаюmaster
) и объединяет обновления. Вы могли бы сделать это сstash
, но я обнаружил, что обычно проще просто использовать ветку / слияние подход.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
где мы предполагаем другой хранилище и
origin master
.
просто делать
git fetch origin branchname git checkout -f origin/branchname // This will overwrite ONLY new included files git checkout branchname git merge origin/branchname
таким образом, вы избегаете всех нежелательных побочных эффектов, таких как удаление файлов или каталогов, которые вы хотели сохранить, и т. д.
Я знаю гораздо более простой и менее болезненный метод:
$ git branch -m [branch_to_force_pull] tmp $ git fetch $ git checkout [branch_to_force_pull] $ git branch -D tmp
вот именно!
Я прочитал все ответы, но я искал одну команду, чтобы сделать это. Вот что я сделал. Добавлен псевдоним git .gitconfig
[alias] fp = "!f(){ git fetch && git reset --hard /;};f"
выполните команду как
git fp origin master
эквивалентно
git fetch origin master git reset --hard origin/master
требования:
- отслеживать локальные изменения, так что никто здесь не теряет их.
- сделайте локальный репозиторий соответствующим удаленному исходному репозиторию.
устранение:
- притон локальные изменения.
Fetch С очистить на файлы и каталоги игнорировать .gitignore и перезагрузка к происхождения.
git stash --include-untracked git fetch --all git clean -fdx git reset --hard origin/master