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

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

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

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

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

 error: Untracked working tree file 'public/images/icon.gif' would be overwritten by merge
 

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

вопрос задан 14.07.2009
Jakub Troszok
30078 репутация

37 ответов


  • 7493 рейтинг

    Важно: если у вас есть локальные изменения, они будут потеряны. С опцией --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
     
    ответ дан RNA, с репутацией 80797, 17.01.2012
  • 771 рейтинг

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

     git reset --hard HEAD
    git pull
     

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

    ответ дан Travis Reeder, с репутацией 21576, 9.05.2010
  • 387 рейтинг

    ВНИМАНИЕ: 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
    ...
     
    ответ дан David Avsajanishvili, с репутацией 5089, 19.03.2011
  • 338 рейтинг

    Как Ежик, я думаю, что ответы ужасны. Но хотя ответ 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» - это имя опции, а «их» - значение для этой опции. Вы решили использовать «свои» изменения вместо «ваших» изменений, если есть конфликт.

    ответ дан Richard Kersey, с репутацией 3603, 11.04.2012
  • 241 рейтинг

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

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

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

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

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

    ответ дан Johanneke, с репутацией 3102, 26.04.2013
  • 124 рейтинг

    Похоже, что лучший способ - сначала сделать:

     git clean
     

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

    ответ дан Jakub Troszok, с репутацией 30078, 14.07.2009
  • 99 рейтинг

    Предупреждение. Выполнение этого будет навсегда удалять ваши файлы, если у вас есть записи каталога /* в файле 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}
     
    ответ дан Hedgehog, с репутацией 3287, 11.02.2012
  • 86 рейтинг

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

     git checkout <your-branch> -f
     

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

     git clean -f
     

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

     git clean -fd
     
    ответ дан Vishal, с репутацией 10416, 5.08.2010
  • 75 рейтинг

    Вместо слияния с git pull попробуйте следующее:

    git fetch --all

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

    git reset --hard origin/master .

    ответ дан Lloyd Moore, с репутацией 2472, 22.11.2012
  • 52 рейтинг

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

     git reset --hard HEAD~5
     

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

     git pull
     

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

    ответ дан Chris BIllante, с репутацией 553, 5.05.2011
  • 50 рейтинг

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

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

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

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

    ответ дан Strahinja Kustudic, с репутацией 2267, 5.11.2012
  • 38 рейтинг

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

    Я решил это:

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

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

    ответ дан John John Pichler, с репутацией 2423, 12.01.2011
  • 32 рейтинг

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

     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 может потерпеть неудачу в некоторых случаях?

    1. Пользовательские правила в .gitattributes file

      Наличие eol=lf правил в .gitattributes может привести к тому, что git может изменить некоторые изменения файла, преобразовывая строки CRLF в LF в некоторые текстовые файлы.

      Если это так, вы должны зафиксировать эти изменения CRLF /LF (просмотрев их в git status ) или попробуйте: git config core.autcrlf false временно игнорировать их.

    2. Невозможность файловой системы

      Когда вы используете файловую систему, которая не поддерживает атрибуты разрешений. В примере у вас есть два хранилища, один на Linux /Mac ( ext3 /hfs+ ) и еще один на FAT32 /NTFS на основе файловой системы.

      Как вы заметили, есть два различных вида файловых систем, так что один , который не поддерживает разрешения Unix в принципе не может восстановить права доступа к файлам на системе , которая не поддерживает такого рода разрешений, поэтому независимо от того , как --hard вы пытаетесь, git всегда обнаруживает некоторые «изменения».

    ответ дан kenorb, с репутацией 59530, 26.10.2012
  • 27 рейтинг

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

     git reset --hard HEAD
    git clean -f
    git pull
     
    ответ дан Ryan, с репутацией 311, 14.01.2011
  • 26 рейтинг

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

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

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

    ответ дан Robert Moon, с репутацией 742, 7.08.2015
  • 25 рейтинг

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

    В этой связи я обновил сценарий Kustudic, чтобы сделать именно это. Я также исправил опечатку (отсутствующую в оригинале).

     #/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
     
    ответ дан Rolf Kaiser, с репутацией 439, 27.02.2013
  • 25 рейтинг

    Бонус:

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

    git pull --rebase

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

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

    Найти подробности в разделе Что такое «git pull --rebase»? ,

    ответ дан Sazzad Hissain Khan, с репутацией 13530, 23.12.2015
  • 22 рейтинг

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

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

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

    ответ дан tiho, с репутацией 4167, 12.12.2011
  • 20 рейтинг

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

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

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

    ответ дан maximus 69, с репутацией 849, 5.05.2015
  • 19 рейтинг

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

    Основываясь на сочетании ответа РНК и ответа Торека на аналогичный вопрос , я придумал это, которое прекрасно работает:

     git fetch
    git reset --hard @{u}
     

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

    Это может быть хорошо добавлено в псевдоним git ( git forcepull ):

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

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

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

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

    ответ дан JacobEvelyn, с репутацией 2314, 25.02.2014
  • 18 рейтинг

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

    ответ дан Tierlieb, с репутацией 227, 3.08.2011
  • 17 рейтинг

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

     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» до тех пор, пока она не будет приемлемой, а затем снова сольется с мастером:

     git checkout master && git merge tmp
     

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

    ответ дан Simon B., с репутацией 1230, 3.12.2010
  • 15 рейтинг

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

     git rm [file]
     

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

    ответ дан Chen Zhang, с репутацией 167, 19.09.2011
  • 13 рейтинг

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

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

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

     git pull origin master
     

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

    ответ дан vishesh chandra, с репутацией 5465, 20.03.2014
  • 12 рейтинг

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

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

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

    ответ дан user2696128, с репутацией 141, 19.10.2015
  • 12 рейтинг

    Несмотря на исходный вопрос, верхние ответы могут вызвать проблемы для людей, у которых есть аналогичная проблема, но не хотят потерять свои локальные файлы. Например, см. Комментарии 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 .

    ответ дан Snowcrash, с репутацией 35788, 22.10.2014
  • 11 рейтинг

    Сбросьте индекс и голову на origin/master , но не сбрасывайте рабочее дерево:

     git reset origin/master
     
    ответ дан does_not_exist, с репутацией , 15.02.2013
  • 10 рейтинг

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

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

    Это оно!

    ответ дан ddmytrenko, с репутацией 628, 5.09.2015
  • 9 рейтинг

    Требования:

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

    Решение:

    1. Замените локальные изменения.
    2. Принесите с чистыми файлами и каталогов , игнорирующих .gitignore и жесткий сброс к происхождению.

       git stash --include-untracked
      git fetch --all
      git clean -fdx
      git reset --hard origin/master
       
    ответ дан vezenkov, с репутацией 2122, 1.09.2015
  • 9 рейтинг

    Я прочитал все ответы, но я искал одну команду для этого. Вот что я сделал. Добавлен псевдоним 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
     
    ответ дан Venkat Kotra, с репутацией 6893, 8.07.2016
  • 6 рейтинг

    Не используйте git reset --hard . Это уничтожит их изменения, которые вполне могут быть совершенно нежелательными. Вместо:

     git pull
    git reset origin/master
    git checkout <file1> <file2> ...
     

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

    Итак, что происходит здесь, так это то, что git pull обновляет исходную /основную ссылку ; git reset обновляет ссылку на локальную ветку, чтобы она была такой же, как исходная /ведущая, без обновления каких-либо файлов, поэтому ваше состояние выписки не изменилось; то git checkout восстанавливает файлы в локальное состояние индекса ветвления . В тех случаях, когда точно такой же файл был добавлен в режиме реального времени и на ведущем сервере, индекс уже соответствует файлу после сброса, поэтому в общем случае вам не нужно делать git checkout вообще.

    Если ветвь вверх по течению также содержит коммиты, которые вы хотите применить автоматически, вы можете следовать тонкой вариации процесса:

     git pull
    git merge <commit before problem commit>
    git reset <problem commit>
    git checkout <file1> <file2> ...
    git pull
     
    ответ дан Jim Driscoll, с репутацией 670, 28.11.2017
  • 6 рейтинг

    Это лучшая практика для исправления изменений:

    • git commit Завершите свои поэтапные изменения, чтобы они были сохранены в рефлоге (см. Ниже)
    • git fetch Выполните последние изменения восходящего потока
    • git reset --hard origin/master Жесткий возврат к исходной ветви оригинала

    Reflog записывает ветви и другие ссылки, обновляемые в локальном репозитории . Или просто поставить - reflog - это история ваших изменений .

    Так что это всегда отличная практика для совершения. Записи добавляются в reflog, который гарантирует, что у вас всегда будет возможность получить удаленный код.

    ответ дан Jordan Georgiev, с репутацией 200, 12.08.2016
  • 5 рейтинг

    Я использовал эту команду, чтобы избавиться от локальных файлов, мешающих мне делать pull /merge. Но будь осторожен! Сначала запустите git merge … чтобы увидеть, есть ли только те файлы, которые вы действительно хотите удалить.

     git merge origin/master 2>&1 >/dev/null | grep ^[[:space:]] | sed s/^[[:space:]]//g | xargs -L1 rm
     
    • git merge перечисляет среди прочего все эти файлы. Они добавляются в какое-то белое пространство.
    • 2>&1 >/dev/null перенаправляет вывод ошибки на стандартный, поэтому он подбирается на grep .
    • grep ^[[:space:]] фильтрует только строки с именами файлов.
    • sed s/^[[:space:]]//g обрезает белое пространство с самого начала.
    • xargs -L1 rm вызывает rm в каждом из этих файлов, удаляя их.

    Обращайтесь с осторожностью: независимо от того, какие git merge выходов, rm будет вызываться для каждой линии, начинающейся с белого пространства.

    ответ дан Glutexo, с репутацией 323, 7.10.2015
  • 5 рейтинг

    Я пытался использовать ветвь Material2 на Angular2-Webpack-Starter и имел чертовски время. Это был единственный способ загрузить и использовать эту ветку.

     git clone --depth 1 https://github.com/angularclass/angular2-webpack-starter.git
    
    cd angular2-webpack-starter/
    
    git checkout -b material2
     

    Откройте папку проекта и удалите все не скрытые файлы и папки. Оставь все скрытые.

     git add .
    
    git commit -m "pokemon go"
    
    git reset --hard
    
    git pull origin material2
     

    (Когда редактор появится, нажмите ': wq', а затем нажмите Enter )

    Теперь вы готовы.

    ответ дан Helzgate, с репутацией 4540, 27.07.2016
  • 3 рейтинг

    Вы можете игнорировать этот файл с файлом в папке с базой проектов:

    .gitignore

     public/images/*
     

    Затем вытащите изменения, а затем удалите эту строку из файла gitignore.

    ответ дан Daniel Gaytán, с репутацией 178, 9.11.2010
  • 1 рейтинг

    В Windows выполните одну команду:

     git fetch --all & git reset --hard origin/master
     
    ответ дан Luca C., с репутацией 2885, 10.04.2018
  • 0 рейтинг

    если вы хотите сбросить на удаленную ветку отслеживания общим способом, используйте:

     git fetch
    git reset --keep origin/$(git rev-parse --abbrev-ref HEAD)
     

    если вы хотите также изменить свои локальные изменения:

     git fetch
    git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)
     
    ответ дан warch, с репутацией 771, 25.05.2018