Как заставить "git pull" перезаписать локальные файлы? - PullRequest
6228 голосов
/ 14 июля 2009

Как принудительно перезаписать локальные файлы на git pull?

Сценарий следующий:

  • Член команды модифицирует шаблоны для веб-сайта, над которым мы работаем
  • Они добавляют некоторые изображения в каталог изображений (но забывают добавить их под контролем исходного кода)
  • Они отправляют изображения по почте, позже, мне
  • Я добавляю изображения под контроль исходного кода и помещаю их в GitHub вместе с другими изменениями
  • Они не могут получать обновления из GitHub, потому что Git не хочет перезаписывать свои файлы.

Это ошибка, которую я получаю:

ошибка: неотслеживаемый рабочий файл дерева public / images / icon.gif будет перезаписан слиянием

Как заставить Git перезаписать их? Этот дизайнер - я обычно разрешаю все конфликты вручную, поэтому на сервере установлена ​​самая последняя версия, которую им просто нужно обновить на своем компьютере.

Ответы [ 39 ]

8678 голосов
/ 17 января 2012

Важно: Если у вас есть какие-либо локальные изменения, они будут потеряны. С или без опции --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
842 голосов
/ 09 мая 2010

Попробуйте это:

git reset --hard HEAD
git pull

Он должен делать то, что вы хотите.

430 голосов
/ 19 марта 2011

ВНИМАНИЕ: 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
...
358 голосов
/ 12 апреля 2012

Как ежик, я думаю, что ответы ужасны. Но хотя ответ Ежика мог бы быть лучше, я не думаю, что он такой элегантный, как мог бы быть. Я нашел способ сделать это с помощью «выборки» и «слияния» с определенной стратегией. Что должно сделать так, чтобы ваши локальные изменения сохранялись до тех пор, пока они не являются одним из файлов, которые вы пытаетесь перезаписать.

Сначала сделайте коммит ваших изменений

 git add *
 git commit -a -m "local file server commit message"

Затем извлечь изменения и перезаписать, если есть конфликт

 git fetch origin master
 git merge -s recursive -X theirs origin/master

"- X" - это имя опции, а "их" - это значение для этой опции. Вы решаете использовать «их» изменения вместо «ваших» изменений, если есть конфликт.

260 голосов
/ 26 апреля 2013

Вместо того, чтобы делать:

git fetch --all
git reset --hard origin/master

Я бы посоветовал сделать следующее:

git fetch origin master
git reset --hard origin/master

Нет необходимости извлекать все пульты и ветки, если вы собираетесь сбросить в исходную / главную ветку, верно?

128 голосов
/ 14 июля 2009

Похоже, лучше всего сначала сделать:

git clean

Чтобы удалить все неотслеживаемые файлы, а затем продолжить с обычного git pull ...

106 голосов
/ 12 февраля 2012

Внимание, это приведет к окончательному удалению ваших файлов, если в вашем файле gitignore есть записи каталога / *.

Некоторые ответы кажутся ужасными. Ужасно в смысле того, что случилось с @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}
91 голосов
/ 05 августа 2010

Эта команда может оказаться полезной для удаления локальных изменений:

git checkout <your-branch> -f

А затем выполните очистку (удаляет неотслеживаемые файлы из рабочего дерева):

git clean -f

Если вы хотите удалить неотслеживаемые каталоги в дополнение к неотслеживаемым файлам:

git clean -fd
84 голосов
/ 22 ноября 2012

Вместо слияния с git pull, попробуйте это:

git fetch --all

с последующим:

git reset --hard origin/master.

57 голосов
/ 06 мая 2011

Единственное, что сработало для меня, было:

git reset --hard HEAD~5

Это вернет вам пять коммитов и затем

git pull

Я нашел это, посмотрев , как отменить слияние Git .

...