Как заставить "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
сбрасывает главную ветку на то, что вы только что получили. The --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
...
предупреждение, это навсегда удалить ваши файлы, если у вас есть каталог/* записи в файла.gitignore
некоторые ответы кажутся ужасными. Страшная, в смысле, что случилось с @Лаури по следующим Дэвид предложение Avsajanishvili.
скорее (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
первая команда загружает новые данные.
второй команда проверяет наличие файлов, добавляемых в репозиторий, и удаляет из локального репозитория непрослеженные файлы, которые могут вызвать конфликты.
третья команда проверяет все файлы, которые были изменены локально.
наконец, мы делаем 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
временно игнорировать их. -
incompability файловой системы
когда вы используете файловую систему, которая не поддерживает атрибутами разрешения. В примере вы есть два репозитория, один на 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
локальные коммиты, которые не находятся в удаленной ветви, также должны быть удалены. IMO самый простой способ достичь этого-с помощью:
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}
запустите это из ветки и это только сбросит вашу локальную ветвь до версии upstream.
это можно красиво поместить в псевдоним git (git forcepull
), а также:
git config alias.forcepull "!git fetch ; git reset --hard @{u}"
или в :
[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 stash", хотя stash, вероятно, вызовет у вас проблемы с первых нескольких попыток, поэтому сделайте первый эксперимент над некритическим проектом...
у меня странная ситуация, что ни 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
где мы предполагаем другой хранилище is 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
таким образом, вы избегаете всех нежелательных побочных эффектов, таких как удаление файлов или каталогов, которые вы хотели сохранить, и т. д.
сбросить индекс и голову до origin/master
, но не сбрасывайте рабочее дерево:
git reset origin/master
Я знаю гораздо более простой и менее болезненный метод:
$ 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
требования:
- отслеживание локальных изменений, так что никто здесь никогда не теряет их.
- сделать локальный репозиторий соответствующим удаленному репозиторию origin.
устранение:
- притон локальные изменения.
-
Fetch С очистить of файлы и каталоги игнорировать .gitignore и перезагрузка к происхождения.
git stash --include-untracked git fetch --all git clean -fdx git reset --hard origin/master