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

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

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

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

Ошибки, которые я получаю, следующие:

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

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

4417
задан Jakub Troszok 14 июля '09 в 17:58
источник поделиться
36 ответов
  • 1
  • 2

Важно: если у вас есть локальные изменения, они будут потеряны. С опцией --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. Однако незавершенные изменения (даже поставленные) будут потеряны. Удостоверьтесь в том, что вы будете хранить и совершать все, что вам нужно.

6159
ответ дан RNA 17 янв. '12 в 3:02
источник поделиться

Попробуйте следующее:

git reset --hard HEAD
git pull

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

706
ответ дан Travis R 09 мая '10 в 22:45
источник поделиться

ПРЕДУПРЕЖДЕНИЕ: git clean удаляет все ваши необработанные файлы/каталоги и не может быть отменено.


Иногда просто clean -f не помогает. Если у вас есть необработанные ДИРЕКТОРИИ, необходим также параметр -d:

git reset --hard HEAD
git clean -f -d
git pull

ПРЕДУПРЕЖДЕНИЕ: git clean удаляет все ваши необработанные файлы/каталоги и не может быть отменено.

345
ответ дан David Avsajanishvili 19 марта '11 в 12:10
источник поделиться

Как Ежик, я думаю, что ответы ужасны. Но хотя ответ Hedgehog может быть лучше, я не думаю, что он такой же изящный, как может быть. Способ, которым я нашел это, - использовать "выборку" и "слияние" с определенной стратегией. Это должно сделать так, чтобы ваши локальные изменения сохранялись до тех пор, пока они не являются одним из файлов, которые вы пытаетесь принудительно перезаписать.

Сначала сделайте фиксацию изменений

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

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

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

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

305
ответ дан Richard Kersey 11 апр. '12 в 23:13
источник поделиться

Вместо этого:

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

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

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

Не нужно брать все пульты и ветки, если вы идете на reset в ветку origin/master справа?

218
ответ дан Johanneke 26 апр. '13 в 16:48
источник поделиться

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

git clean

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

117
ответ дан Jakub Troszok 14 июля '09 в 18:16
источник поделиться

Предупреждение. Выполнение этого будет навсегда удалять ваши файлы, если у вас есть какие-либо записи каталога /* в файле 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}
88
ответ дан Hedgehog 12 февр. '12 в 2:00
источник поделиться

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

git checkout <your-branch> -f

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

git clean -f

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

git clean -fd
84
ответ дан Vishal 05 авг. '10 в 21:06
источник поделиться

Вместо слияния с помощью git pull попробуйте git fetch --all, а затем git reset --hard origin/master.

57
ответ дан Lloyd Moore 22 нояб. '12 в 13:56
источник поделиться

Проблема со всеми этими решениями заключается в том, что они все либо слишком сложны, либо еще более серьезная проблема заключается в том, что они удаляют все необработанные файлы с веб-сервера, чего мы не хотим, поскольку всегда требуются файлы конфигурации которые находятся на сервере, а не в репозитории 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 $2}'`
do
    rm -f -- "$file"
done

# Checkout all files which were locally modified
for file in `git diff --name-status | awk '/^[CDMRTUX]/ {print $2}'`
do
    git checkout -- "$file"
done

# Finally pull all the changes
# (you could merge as well e.g. 'merge origin/master')
git pull
  • Первая команда извлекает новейшие данные.

  • Вторая команда проверяет, есть ли какие-либо файлы, которые добавляются в репозиторий, и удаляет эти невоспроизводимые файлы из локального репозитория, что может вызвать конфликты.

  • Третья команда проверяет все файлы, которые были локально изменены.

  • Наконец, мы делаем попытку обновиться до самой новой версии, но на этот раз без каких-либо конфликтов, так как ненужные файлы, которые находятся в репо, больше не существуют, и все файлы с локальным изменением уже такие же, как в репозиторий.

47
ответ дан Strahinja Kustudic 06 нояб. '12 в 2:32
источник поделиться

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

git reset --hard HEAD~5

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

git pull

Я обнаружил, что, посмотрев как отменить Git merge.

45
ответ дан Chris BIllante 06 мая '11 в 0:53
источник поделиться

У меня была та же проблема. Никто не дал мне это решение, но это сработало для меня.

Я решил это:

  • Удаление всех файлов. Оставьте только каталог .git.
  • git reset --hard HEAD
  • git pull
  • git push

Теперь он работает.

34
ответ дан John John Pichler 13 янв. '11 в 2:58
источник поделиться

Прежде всего, попробуйте стандартный способ:

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, в принципе не может reset разрешать файлы в системе, которые не поддерживают такие разрешения, поэтому не важно как --hard вы пытаетесь, git всегда обнаруживают некоторые "изменения".

30
ответ дан kenorb 26 окт. '12 в 12:17
источник поделиться

У меня была аналогичная проблема. Я должен был сделать это:

git reset --hard HEAD
git clean -f
git pull
24
ответ дан Ryan 14 янв. '11 в 18:18
источник поделиться

Я обобщил другие ответы. Вы можете выполнить git pull без ошибок:

git fetch --all
git reset --hard origin/master
git reset --hard HEAD
git clean -f -d
git pull

Предупреждение. Этот script очень мощный, поэтому вы можете потерять свои изменения.

23
ответ дан Robert Moon 07 авг. '15 в 6:03
источник поделиться

Основываясь на моих собственных подобных опытах, решение, предлагаемое Strahinja Kustudic выше, является безусловно лучшим. Как отмечали другие, просто выполнение жесткого reset удалит все не проверенные файлы, которые могут включать в себя множество вещей, которые вы не хотите удалять, например, файлы конфигурации. Что более безопасно, нужно удалить только файлы, которые должны быть добавлены, и, в этом отношении, вы, вероятно, также захотите проверить любые локально модифицированные файлы, которые должны быть обновлены.

Именно поэтому я обновил Kustudic script, чтобы сделать именно это. Я также исправил опечатку (отсутствует в оригинале).

#/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 $2}'`
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 $2}'`
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
23
ответ дан Rolf Kaiser 27 февр. '13 в 17:43
источник поделиться

Я считаю, что есть две возможные причины конфликта, которые нужно решать отдельно, и насколько я могу судить, ни один из вышеперечисленных ответов не имеет отношения к обоим:

  • Локальные файлы, которые не отслеживаются, должны быть удалены вручную (безопаснее) или, как предложено в других ответах, на git clean -f -d

  • Локальные коммиты, которые не находятся в удаленной ветке, также должны быть удалены. ИМО - самый простой способ добиться этого: git reset --hard origin/master (замените "мастер" любой веткой, над которой вы работаете, и сначала запустите git fetch origin)

19
ответ дан tiho 12 дек. '11 в 22:54
источник поделиться

Более простой способ:

git checkout --theirs /path/to/file.extension
git pull origin master

Это переопределит ваш локальный файл с файлом на git

18
ответ дан maximus 69 05 мая '15 в 11:03
источник поделиться

Бонус:

Говоря о pull/fetch/merge в приведенных выше ответах, я хотел бы поделиться интересным и продуктивным трюком,

git pull --rebase

Эта вышеприведенная команда является самой полезной командой в моей жизни git, которая сэкономила много времени.

Прежде чем нажимать новую фиксацию на сервер, попробуйте эту команду, и она автоматически синхронизирует последние изменения сервера (с помощью слияния + слияние) и поместит вашу фиксацию вверху в журнал git. Не нужно беспокоиться о ручном вытягивании/слиянии.

Найти информацию по адресу: http://gitolite.com/git-pull--rebase

15
ответ дан Sazzad Hissain Khan 23 дек. '15 в 18:41
источник поделиться

У меня была такая же проблема, и по какой-то причине даже git clean -f -d не сделал бы этого. Вот почему: По какой-то причине, если ваш файл игнорируется Git (через запись .gitignore, я предполагаю), он по-прежнему беспокоится о том, чтобы перезаписать это с последующим отключением, но чистый не удалит его, если только вы добавьте -x.

15
ответ дан Tierlieb 03 авг. '11 в 12:23
источник поделиться

Кажется, что большинство ответов здесь сосредоточено на ветке master; однако иногда бывают случаи, когда я работаю над одной и той же ветвью функций в двух разных местах, и я хочу, чтобы в одной из них одна из них отражалась в другой, без большого количества прыжков через обручи.

Основываясь на сочетании ответа РНК и ответ torek на аналогичный вопрос, я пришел с великолепной работой:

git fetch
git reset --hard @{u}

Запустите это из ветки, и она будет только reset вашей локальной ветвью в восходящую версию.

Это может быть удобно помещено в псевдоним git (git forcepull):

git config alias.forcepull "!git fetch ; git reset --hard @{u}"

Или в файле .gitconfig:

[alias]
  forcepull = "!git fetch ; git reset --hard @{u}"

Наслаждайтесь!

14
ответ дан JacobEvelyn 25 февр. '14 в 20:19
источник поделиться

Я просто решил это сам:

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

В следующий раз вы можете обработать это более чистым способом, просмотрев "ветвь wash" git, хотя при первой попытке может возникнуть проблема, так что сначала эксперимент по некритическому проекту...

13
ответ дан Simon B. 03 дек. '10 в 18:00
источник поделиться

Эти четыре команды работают для меня.

git reset --hard HEAD
git checkout origin/master
git branch -D master
git checkout -b master

Чтобы проверить/вытащить после выполнения этих команд

git pull origin master

Я много пробовал, но, наконец, добился успеха в этих командах.

11
ответ дан vishesh chandra 20 марта '14 в 7:24
источник поделиться

У меня странная ситуация, когда работает git clean или git reset. Мне нужно удалить конфликтующий файл из git index на

git rm [file]

Тогда я могу потянуть просто отлично.

10
ответ дан Chen Zhang 19 сент. '11 в 17:18
источник поделиться

Несмотря на исходный вопрос, верхние ответы могут вызвать проблемы для людей, у которых есть аналогичная проблема, но не хотят потерять свои локальные файлы. Например, см. Комментарии Al-Punk и crizCraig.

Следующая версия фиксирует ваши локальные изменения во временной ветке (tmp), проверяет исходную ветвь (которая, как я предполагаю, master), и объединяет обновления. Вы можете сделать это с помощью stash, но я нашел, что обычно проще просто использовать подход branch/merge.

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.

10
ответ дан Snowcrash 22 окт. '14 в 20:31
источник поделиться

Просто сделай

git fetch origin branchname
git checkout -f origin/branchname // This will overwrite ONLY new included files
git checkout branchname
git merge origin/branchname

Таким образом, вы избегаете всех нежелательных побочных эффектов, таких как удаление файлов или каталогов, которые вы хотели сохранить, и т.д.

10
ответ дан user2696128 19 окт. '15 в 12:54
источник поделиться

Reset указатель и head на origin/master, но не reset рабочее дерево:

git reset origin/master
9
ответ дан user811773 15 февр. '13 в 16:41
источник поделиться

Требования:

  • Отслеживайте локальные изменения, поэтому никто не теряет их.
  • Сделать локальный репозиторий совместимым с репозиторием удаленного источника.

Решение:

  • Скрыть локальные изменения.
  • Получить с чистой файлами и , игнорируя .gitignore и жесткий reset в происхождение.

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    
7
ответ дан vezenkov 02 сент. '15 в 2:00
источник поделиться

Я прочитал все ответы, но я искал одну команду для этого. Вот что я сделал. Добавлен псевдоним git в .gitconfig

[alias]
      fp = "!f(){ git fetch ${1} ${2} && git reset --hard ${1}/${2};};f"

Запустите команду

git fp origin master

эквивалентно

git fetch origin master
git reset --hard origin/master
7
ответ дан Venkat Kotra 08 июля '16 в 16:11
источник поделиться

Я знаю гораздо более легкий и менее болезненный метод:

$ git branch -m [branch_to_force_pull] tmp
$ git fetch
$ git checkout [branch_to_force_pull]
$ git branch -D tmp

Что это!

7
ответ дан ddmytrenko 05 сент. '15 в 21:23
источник поделиться
  • 1
  • 2

Другие вопросы по меткам