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

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

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

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

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

Я получаю следующее сообщение об ошибке:

<цитата>

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

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

Показать лучший ответ

любой, кто читает это и думает, что может потерять файлы, я был в этом положении и обнаружил, что буфер Sublime Text спас меня - если я над чем-то работаю, то случайно удалите все, пытаясь решить аналогичную проблему или используя ответ на этот вопрос и если файлы были открыты в Sublime (что есть хороший шанс), тогда файлы все еще будут там Sublime, либо просто там, либо в истории отмены

git reset --hard origin/branch_to_overwrite

в основном, извлекайте из develop только после первоначальной проверки -b. сделай свою работу, а затем вернись.

Краткий ответ: удалить и заново создать ветку. 1. Удалить ветку: git branch <branch> -D 2. Сбросить до фиксации перед конфликтом: git reset <commit> --hard 3. Повторно создать ветвь: git branch <branch> 4. Установить отслеживание для сервер: git --set-upstream-to=origin/<branch> <branch> 5. Pull: git pull`

Чтобы изменить все окончания CRLF на LF, (начните с чистого листа) git config core.autocrlf false; git ls-files -z | xargs -0 rm; git checkout .

Вместо этого вы можете искать этот вопрос: вместо этого stackoverflow.com/q/1628088/1148030 "Сбросить ветку локального репозитория в точно так же, как HEAD удаленного репозитория "Например, если пульт был принудительно нажат, и вы хотите вытащить его и отбросить предыдущее воплощение ветки, которая у вас есть. (Некоторые другие вопросы указывают на этот вопрос как на их дубликат, но я думаю, что им следует указать на этот другой вопрос.)

Вручную удалите все файлы и папки из локального репозитория. Затем запустите git checkout <branch> && git add -A . && git reset --hard origin/<branch> && git pull . См. stackoverflow.com/a/65239330 .

На это однозначно есть ответ, потому что я сделал это случайно. Сейчас много недель работы ушло :(

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

git clean
 

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

Я попытался использовать "git clean" для решения той же проблемы, но это не помогло. git status говорит: «Ваша ветка и 'origin / master' разошлись, # и имеют 2 и 9 разных фиксаций соответственно». и git pull говорит что-то похожее на то, что у вас выше.

не нужно ли ему переходить на основную ветку, а затем делать git clean, чтобы она работала? Затем он может вернуться к той ветке разработки, в которой он работал.

@slacy: Затем вам нужно объединить две ветки.

git clean - довольно грубый инструмент, и он может выбросить много вещей, которые вы, возможно, захотите оставить. Лучше удалить или переименовать файлы, на которые git жалуется, пока извлечение не завершится успешно.

Я не думаю, что это вообще работает. Разве нет способа сделать в основном удаленное клонирование git с помощью принудительного git pull?

@mathick: git fetch origin && git reset --hard origin/master

Мне нужно было добавить -x к этому git clean , чтобы заставить его работать для меня по какой-то причине (-d не удалял .ideas по какой-то причине), но это определенно устранило мою проблему.

избегать внезапной остановки сердца: сначала используйте git clean -n

git clean - лучший ответ здесь? Похоже, удаление файлов - это не обязательно то, что хочет OP. Они просили «перезапись локальных файлов», а не удаление.

Сам по себе git clean , похоже, не помогает, решение @Arrowmaster ближе, но в следующем ответе будет лучшее решение Ллойда Мура.

Никогда не делайте ничего "git" (или даже не создавайте папку .git), кроме как в копии вашей реальной рабочей папки, и избегайте любого сердечного стресса. Не давайте git и его тупому синтаксису / методам возможность разрушить вас в первую очередь.

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

git reset --hard HEAD
git pull
 

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

Я сделал это, и некоторые локальные файлы, которых больше не было в репо, остались на диске.

Не думаю, что это правильно. приведенное выше будет выполнять слияние, а не перезапись, как это было запрошено в вопросе: «Как заставить git перезаписать их?» У меня нет ответа, я сейчас ищу его ... в данный момент я переключаюсь на ветку с кодом, который хочу сохранить, «git checkout BranchWithCodeToKeep», затем выполняю «git branch -D BranchToOverwrite» и, наконец, "git checkout -b BranchToOverwrite". теперь у вас будет точный код из BranchWithCodeToKeep в ветке BranchToOverwrite без необходимости выполнять слияние.

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

Предложение Ллойда Мура правильное, но имейте в виду, что оно может удалить локальные неопубликованные коммиты из вашей ветки.

да, решение @lloydmoore сработало для меня. Может быть, это ответ, а не просто комментарий.

Это приведет к сбросу текущих изменений обратно к последней извлеченной фиксации ветки. Затем git pull объединяет изменения из последней ветки. Это сделало именно то, что я хотел ... Спасибо!

Это испортит пульт?

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

@Travis R, не могли бы вы объяснить цель git rest --hard HEAD?

git reset --hard HEAD в некоторых случаях не сбрасывает все

Это в основном то, о чем я думаю, когда думаю о форсировании тяги. В основном после того, как я попробовал некоторые настройки

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

git checkout <your-branch> -f
 

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

git clean -f
 

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

git clean -fd
 

Я думаю, что описание сценария дает понять, что на самом деле он не хочет выбрасывать контент. Скорее он хочет, чтобы git отказывался от перезаписи файлов. Смотрите мое предложение.

Хотя этот ответ может не совсем соответствовать описанию, он все же спас меня от разочарования, связанного с git, который возился с возвратами каретки (событие с autocrlf false). Когда git reset --hard HEAD не оставляет вам измененных файлов «no», эти флаги «-f» очень полезны. Огромное спасибо.

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

.gitignore

public/images/*
 

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

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

 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 branch», хотя stash может вызвать у вас проблемы с первых нескольких попыток, поэтому сначала поэкспериментируйте с некритичным проектом. .

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

Я решил это:

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

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

То же самое. Иногда работает только очень сложное решение, часто бывает, что одного сброса и очистки как-то не хватает ...

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

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

используйте git clean с осторожностью

ВНИМАНИЕ: 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
...
 

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

Я думаю, что описание сценария дает понять, что на самом деле он не хочет выбрасывать контент. Скорее он хочет, чтобы git отказывался от перезаписи файлов. @ Лаури, этого не должно было случиться с тобой. К сожалению, люди, кажется, неправильно поняли суть описания сценария - см. Мое предложение.

НАКОНЕЦ . git clean -f -d удобен, когда make clean не может очистить все.

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

@crizCraig, если они не добавлены в .gitignore

@BleedingFingers Затем добавьте -x . Но существующие файлы, охватываемые .gitignore , не должны быть проблемой: предполагая, что другие участники этого репо используют тот же файл .gitignore , пул не получит никаких коммитов, которые добавляют конфликтующие файлы.

@earthmeLon, для этого вам может понадобиться git clean -dfx . -x игнорирует .gitignore. Обычно ваши продукты сборки будут в .gitignore.

Может быть хорошо сначала запустить git clean -nfd , который только показывает то, что будет удалено , прежде чем это будет сделано, то есть до того, как вы столкнетесь с проблемами. :-)

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

git reset --hard HEAD~5
 

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

git pull
 

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

Это было то, что в конечном итоге сработало для меня, поскольку я принудительно подтолкнул свою ветку к исходному репо и продолжал получать конфликты слияния при попытке вытащить его на мое удаленное репо ..

Привет, на самом деле это уловка для work around , но действительно эффективная. Поскольку некоторые конфликты могут возникнуть всего за несколько коммитов, возврат 5 коммитов гарантирует отсутствие конфликтов с удаленным кодом.

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

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

git rm [file]
 

Тогда я могу нормально тянуть.

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

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

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

Аватар RNA
Принятый ответ

⚠ Важно: если у вас есть какие-либо локальные изменения, они будут потеряны. С параметром --hard или без него любые локальные коммиты, которые не были отправлены, будут потеряны. [*]

Если у вас есть файлы, которые не отслеживаются Git (например, загруженный пользовательский контент), эти файлы не будут затронуты.

<час/>

Сначала запустите выборку, чтобы обновить все ссылки origin/<branch> до последней версии:

git fetch --all
 

Сделайте резервную копию текущей ветки:

git checkout -b backup-master
 

Тогда у вас есть два варианта:

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
 

Осторожно! Если у вас есть локальные неопубликованные коммиты, они будут удалены из вашей ветки! Это решение сохраняет неотслеживаемые файлы не в репозитории, а перезаписывает все остальное.

Аватар Red

Это популярный вопрос, поэтому я хотел бы уточнить верхний комментарий здесь. Я только что выполнил команды, описанные в этом ответе, и не удалил ВСЕ локальные файлы. Были перезаписаны только удаленно отслеживаемые файлы, и каждый локальный файл, который был здесь, остался нетронутым.

Я потерял все локальные коммиты, которых не было в дереве origin/master после перебазирования. Здесь очень возможно прострелить себе ногу.

Вы также можете сделать это для ветки отслеживания, если у вас одна и та же ветка в источнике и локально, просто измените git reset --hard origin / master на git reset --hard origin / (ветка)

если вы используете репо, имя удаленной ветки которого отличается от "master", используйте git reset --hard origin/branch-name

Это должен быть принятый ответ. У меня отлично работает. Я предполагаю, что здесь предполагается, что у вас нет локальных коммитов, что в моем случае хорошо, поскольку «локальный» имеет только ключ развертывания.

Аватар mcv

Разве это не отбросит мои локальные коммиты? Я хочу сохранить свои коммиты и перезаписать только неотслеживаемые / незафиксированные изменения.

Я просто использую «git fetch», чтобы получить ветку восходящего потока, а затем сбрасываю, когда мне нужно исправить кучу файлов. Вы можете получить восходящую ветку с помощью "git branch -vv"

@mcv Чтобы сохранить ваши локальные коммиты, вам нужен git reset --hard HEAD , за которым вы могли бы следовать с помощью git merge origin/master .

Учитывая количество положительных отзывов на этот вопрос и ответ, я думаю, что git должен включать такую ​​команду, как git pull -f

Коммиты, которые не были отправлены до аппаратного сброса, могут быть восстановлены с помощью git reflog , в котором перечислены все коммиты, в том числе без базы. Пока вы не очистите локальную копию с помощью git gc , все потеряно

Удалит ли это файлы, которые у меня есть .gitignore'd?

@FelipeSchenone На самом деле существует git pull -f , но он не делает того, что мы все хотим от него.

Чтобы быть правильным, незавершенные изменения теряются, но старые коммиты болтаются, ожидая сборки мусора. Вы все еще можете увидеть их в git reflog и переместить свой HEAD обратно с помощью git reset --hard HEAD@{1} .

Хочу указать здесь, что он также удалит любые изменения, сделанные в любой другой ветке, которая не отслеживается удаленно. Я потерял свою, надеюсь, другие будут осторожны.

Сделайте резервную копию папки с вашими локальными файлами, включая папку .git в ней. Теперь вы не можете ничего «потерять», если это исправление не сработает для вас; вы можете сделать еще одну копию и попробовать что-нибудь еще. Не работайте из одной папки и доверяйте git, как если бы это был 100% надежный инструмент резервного копирования. Одна опечатка, особенно в стране веток, может обернуться кошмаром. Я предлагаю сделать резервную копию старой школы для папок tar.gz, а затем запустить git из последней копии.

@Red Да, если вы хотите удалить все неотслеживаемое, даже проигнорированное, используйте git clean -dxf после жесткого сброса.

Я сделал это, и мои локальные изменения НЕ были отброшены - что прискорбно, потому что я надеялся, что они будут! Кто-нибудь знает, как это сделать, но также заставит git отменить любые изменения локали, которых нет в удаленной ветке? По сути, мне нужно ТОЧНОЕ, однозначное соответствие с удаленной веткой.

Малоизвестный факт - вы можете создать резервную копию всего репозитория git с помощью старого доброго tar -czf myrepodir.tar.gz myrepodir/. . Если ваше репо испортилось из-за странностей git, удалите его и восстановите из файла tar.gz , чтобы ДЕЙСТВИТЕЛЬНО вернуться туда, где вы были до того, как попробовали этот злополучный эксперимент. Просто убедитесь, что у вас есть . после myrepodir/ , иначе ваш .git и другие скрытые файлы не будут сохранены!

может ли этот метод работать с отдельными файлами? например, -- index.php helpers.js ect. вместо --all ?

у меня не сработало. пробовал это решение, пробовал git clean -dfx . попробовал git pull -f . все еще есть то же сообщение об ошибке.

Обратите внимание, что вы можете сократить имя ветки до @{u} , что намного короче.

@GershomMaes git clean -dfx после аппаратного сброса, как упоминалось выше IceGlow ?

не проще ли просто rm -rf / folder и снова выполнить git clone, если вы хотите отменить все свои локальные изменения?

При использовании git clean -dffx обязательно запускайте его из каталога верхнего уровня проекта git . Рекомендуется сначала запустить git clean -ndffx , чтобы перечислить файлы перед их удалением, поскольку -x удаляет файлы, которые имеют .gitignored и не отображаются git status

Аватар Sz.

@JonB: "Не проще ли просто создать rm -rf / folder и снова сделать git clone ...?" Сюда меня привело (даже не слишком) большое репо + низкая пропускная способность. Я бы хотел просто клонировать снова, но в первый раз это было достаточно болезненно, поэтому я один из тех, кто ищет более быстрое решение.

работал у меня, когда исходная ветка содержала обновления, такие как переименование файлов с «общего» на «общее». В Windows это не имеет значения, поэтому такой подход меня разблокировал.

У Mercurial есть hg update , но в git нет эквивалента ...

Было бы более последовательным, если бы вы могли использовать git pull --force , и он просто перезаписал бы вашу локальную ветвь. Увидев, что вы можете сделать обратное, перезаписав пульт с помощью git push --force

Потерял все мои локальные коммиты с вашими предложенными командами.

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

Извините. Слишком сложно. Вместо этого просто удалите и снова клонируйте ...

Если вы запустите git checkout -b backup-master, вы должны вернуться в свою ветку (master в примере) перед запуском git reset. В противном случае вы можете использовать git branch backup-master вместо этого, чтобы создать резервную ветку, но остаться в master.

Предупреждение, это приведет к безвозвратному удалению ваших файлов, если в вашем файле 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}
 

Разве вы не предполагаете, что фиксация никогда не выполнялась? В моем случае я сделал несколько коммитов в свою локальную ветку, но хотел «сбросить» все обратно в удаленную ветку.

Нет, я так не думаю. Stash просто удаляет незафиксированные файлы. Вышеупомянутое также перемещает (сохраняет) файлы, которые git не отслеживает. Это предотвращает удаление файлов, которые были добавлены на пульт, но которые еще не были загружены на ваш компьютер, но которые вы создали (!). И все это без разрушения незавершенной работы. Надеюсь, это имеет смысл?

Если у вас нет версии 1.7.6, вы можете имитировать --include-untracked , просто временно git add скопировав все свое репо, а затем немедленно спрятав его.

Я согласен с Ежиком. Если вы ответите на популярные здесь ответы, вы, скорее всего, обнаружите, что случайно убили много вещей, которые на самом деле не хотели терять.

У меня были и другие неотслеживаемые файлы - помимо того, который нужно было перезаписать при слиянии / извлечении, поэтому это решение сработало лучше всего. git stash apply вернул все мои неотслеживаемые файлы, за исключением (справедливо) тех, которые уже были созданы слиянием: «уже существует, без проверки». Сработало отлично.

Это может быть самый простой способ непреднамеренно заблокировать репо, как и в случае с @Lauri, но хуже, потому что вы думаете, что защищаете файлы от удаления. Если у вас есть одно правило .gitignore , в котором есть подстановочный знак, поцелуйте их на прощание. Объяснение.

Это самый чистый ответ, и он должен быть принятым. Чтобы сэкономить время на вводе текста, вы можете использовать короткую форму: git stash -u .

Ссылка на git stash --include-untracked уничтожающие папки, которые gitignored, мертва - давайте найдем замену. Тем временем за комментарий @Waif о том, как этот ответ может уничтожить папки gitignore'd , следует проголосовать и, желательно, преобразовать его в новый ответ. GitLab у вас есть подробности. Я часто использую git stash и был очень удивлен, узнав, что он может уничтожать файлы.

Как Ежик, я думаю, что ответы ужасны. Но хотя ответ Ежика мог бы быть лучше, я не думаю, что он настолько элегантен, насколько мог бы быть. Я нашел способ сделать это, используя 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 - это имя параметра, а theirs - значение для этого параметра. Вы решили использовать their changes (другой вариант - ours changes) в случае конфликта.

Это лучший ответ, который я когда-либо видел. Я не пробовал, но, в отличие от других ответов, он не пытается уничтожить все ваши неотслеживаемые файлы, что очень опасно по очевидным причинам.

То же самое - это сработало для меня при выполнении очень большого слияния (запрос на вытягивание GitHub), когда я просто хотел принять все это поверх того, что у меня было. Хороший ответ! В моем случае последние две команды были: 1) get fetch other-repo ; 2) git merge -s recursive -X theirs other-repo/master

Это перезапишет любые конфликты с файлами репозиториев, а не с вашими локальными, верно?

Лучший ответ. Самый высокий принятый ответ оставил меня в моем случае оторванной головой. Я снова переключился на локальную главную ветку и запустил git merge -X theirs origin/master

Пробовал это - затем добавлял / фиксировал мои новые измененные файлы, но все же сказал, что моя ветка находилась за удаленным, когда я пытался нажать. Огромное количество потраченного времени, потому что "git pull" не спрашивает "Перезаписать локальный? Y / n / all".

Подождите ... не имеет git add * и git commit -a <more-options-here> имеет одинаковый эффект? Зачем вам и то, и другое?

@ MarcelStör, вам не нужны оба, но они не делают одно и то же. git commit -a влияет только на файлы, которые уже отслеживаются; git add * добавит файлы, которые не отслеживаются. Поэтому, если вы сделаете git commit -a , он не будет ловить новые файлы, тогда вам может потребоваться выполнить git add позже, но если вы сделаете git add * , вы не будете требуется -a для фиксации.

Проблема с этим (отличным) ответом заключается в том, что он добавляет все локальные файлы, которые иногда могут быть не такими, как вы хотите. Вы можете просто добавить определенные файлы, которые были пропущены. Но самое лучшее в этом то, что он заставляет его делать то, что он должен был сделать, - добавлять их локально. Вероятно, вам не понадобится их стратегия -X, поскольку это один и тот же образ. Фактически, я бы посоветовал сначала оставить его, просто чтобы узнать, есть ли какие-либо аномалии, и добавить их, если они есть, после проверки того, что «их» всегда является правильным выбором. Но тогда я параноик.

Я просто хотел долбанного мерзавца, чтобы перезаписать все и заткнуться. в конце концов, я просто использую его между моим рабочим компьютером и некоторыми системами Raspberry Pi. Желая иметь возможность принудительной перезаписи, по крайней мере, для руководителя проекта

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

хммм ... может, сначала попробуй git add .

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

git reset HEAD --hard # To remove all not committed changes!
git clean -fd         # To remove all untracked (non-git) files and folders!
 

Предупреждение : указанные выше команды могут привести к потере данных / файлов только в том случае, если вы их не зафиксировали! Если вы не уверены, сначала сделайте резервную копию всей папки репозитория.

Затем снова потяните.

Если описанное выше не поможет и вас не волнуют неотслеживаемые файлы / каталоги (на всякий случай сделайте резервную копию), попробуйте выполнить следующие простые шаги:

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 (исключение .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 всегда обнаруживает некоторые "изменения".

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

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

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

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

Использование «git merge origin / master» в качестве последней строки (как вы говорите в своей заметке) вместо «git pull» будет быстрее, поскольку вы уже удалили любые изменения из репозитория git.

Да, конечно, git merge origin/master будет быстрее и, возможно, даже безопаснее. Поскольку, если кто-то внес новые изменения во время удаления файлов этого сценария (что маловероятно, но возможно), все извлечение может потерпеть неудачу. Единственная причина, по которой я поместил туда pull , заключается в том, что кто-то может работать не над основной веткой, а над какой-то другой веткой, и я хотел, чтобы сценарий был универсальным.

Если у вас есть локально созданные файлы, такие как файлы параметров, поместите их в .gitignore .

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

git fetch --all

, за которым следует:

git reset --hard origin/master .

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

git reset origin/master
 

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

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

Помня об этом, я обновил скрипт Кустудича именно для этого. Я также исправил опечатку (пропущенное 'в оригинале).

 #/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
  

Использование «git merge origin / master» в качестве последней строки (как вы говорите в своей заметке) вместо «git pull» будет быстрее, поскольку вы уже удалили любые изменения из репозитория git.

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

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

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

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

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

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

Ваш ответ - именно то, что вам нужно для вашей репутации. Я должен спросить, удаляются ли также все неотслеживаемые файлы?

Да, большая часть моего представителя приходит отсюда :) Это также удалит все неотслеживаемые файлы. То, что я забыл и о чем болезненно вспомнил всего 2 дня назад ...

См. Комментарии к этому другому ответу: stackoverflow.com/a/8888015/2151700

Это не удалило мои неотслеживаемые файлы; что на самом деле то, что я ожидал. Есть ли причина, по которой это может быть для одних людей, а для других - нет?

На неотслеживаемые файлы git reset не влияет. Если вы хотите, чтобы они также были удалены, сделайте сначала git add . , а затем git reset --hard

Это именно то, что мне было нужно: что-то, что перезаписывает неотслеживаемые файлы, существующие на пульте дистанционного управления, и оставляет все остальное нетронутым.

Похоже, что большинство ответов здесь сосредоточено на ветке 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}"
 

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

Этот ответ хорош еще и потому, что он работает независимо от того, в какой ветке вы находитесь!

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

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

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

git pull origin master
 

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

"git branch -D master" удалить ветку. так что будьте осторожны с этим. Я предпочитаю использовать "git checkout origin / master -b ", который создает новую ветку с новым именем, а вам нужно 3,4 строки. Также рекомендуется использовать "git clean -f".

Несмотря на исходный вопрос, основные ответы могут вызвать проблемы у людей, у которых есть аналогичная проблема, но которые не хотят терять свои локальные файлы. Например, см. Комментарии 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 checkout --theirs /path/to/file.extension
git pull origin master
 

Это заменит ваш локальный файл файлом на git

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

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

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

Это перезапишет измененные файлы (файлы, которые были ранее отмечены) и удалит неотслеживаемые файлы (файлы, которые никогда не были возвращены). Именно то, что я искал, спасибо!

Я подозреваю, что третья строка git reset --hard HEAD может быть избыточной; моя локальная страница руководства (2.6.3) говорит, что reset во второй строке git reset --hard origin/master «по умолчанию - HEAD во всех формах».

@arichards Я думаю, что ваш подозреваемый прав, но если вторая строка не будет работать (по какой-либо причине), третья строка будет хорошо сброшена. Это решение не требует оптимизации. Я просто обобщил другие ответы. Вот и все. Спасибо за ваш комментарий. :)

Спасибо за резюме. Эти шаги действительно мощные :)

Требования:

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

Решение:

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

    git stash --include-untracked
    git fetch --all
    git clean -fdx
    git reset --hard origin/master
    

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

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

Вот и все!

Я пробовал делать, как было предложено в этом ответе. ВООБЩЕ НИКАКИЕ ФАЙЛЫ не были извлечены из удаленного репозитория. На самом деле это не очень удивительно, если подумать - в конце концов, здесь вообще нет ссылки на origin/<branch_to_force_pull> .

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

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

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

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

Отлично. Первое использование checkout -f в ветке, из которой я хотел выполнить слияние, позволило избавиться от всех проблемных неотслеживаемых файлов. Затем я мог снова проверить свой пункт назначения и, наконец, без проблем слиться.

Бонус:

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

git pull --rebase

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

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

Подробную информацию см. в Что делает "git pull --rebase"? .

Вкратце: git pull -r .

В моем случае, прежде чем это сделать, мне нужно было 1) git add -A , 2) git commit -m 3) и, наконец, git pull rebase . Спасибо.

Я прочитал все ответы, но искал единственную команду для этого. Вот что я сделал. Добавлен псевдоним 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
 

Я пытался использовать ветку 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 )

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

Это лучший способ отменить изменения:

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

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

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

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

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

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

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

Если ветвь восходящего потока также содержит коммиты, которые вы хотите применить автоматически, вы можете проследить за тонким вариантом процесса:

git pull
git merge <commit before problem commit>
git reset <problem commit>
git checkout <file1> <file2> ...
git pull
 

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

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

Почему это должно быть иначе, чем, например, в Linux? Какую конкретную реализацию / пакет git вы используете? И / или в какой среде (например, MinGW)?

Я не уверен, только уверен, что это работает в окнах. В linux какой разделитель объединяет две команды в одну строку? (не канал, просто объедините без передачи вывода)

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

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

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

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

Если вы обнаружите, что часто используете это, добавьте ярлык bash alias gplf='git fetch && echo "HEAD was at $(git rev-parse --short HEAD)" && git reset --hard origin/$(git rev-parse --abbrev-ref HEAD)'

Блестяще. Спасибо! При ответе люди не принимают во внимание автоматические скрипты. Это очень элегантно, если вы просто не можете передать имя ветки.

1: возврат к предыдущей фиксации

git reset --hard HEAD
 

2: Удалить файлы без отслеживания

git clean -f
 

3. Подтяните коммиты

git pull
 

Источники:

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

git fetch --all
 

тогда, если вы находитесь в главной ветке

git reset --hard origin/master
 

еще

git reset --hard origin/master<branch_name>
 

Последний фрагмент должен быть origin/<branch_name> , а не origin/master<branch_name> .

вы можете попробовать git pull --force или, возможно, спрятать свои коммиты, используя git stash , а затем запустив git pull

Это не работает. fatal: refusing to merge unrelated histories

Automatic merge failed; fix conflicts and then commit the result.

Нет: error: The following untracked working tree files would be overwritten by merge: - эти файлы меня не интересуют. Если бы их было всего два или три, я бы просто удалил их. Но их так много.

Я сделал это, чтобы заставить его работать:

На компьютере, на котором я создал новую ветку:

git push --all
 

На компьютере, на котором я хотел показать новую ветку:

git fetch --all
 

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

for /f "tokens=1* delims= " %a in ('git branch^|findstr /b "*"') do @git reset --hard origin/%b
 

После выполнения git pull вы получите список файлов, которые не совпадают. Если количество файлов невелико, вы можете проверить эти файлы, это действие перезапишет эти файлы.

git checkout -

Обычно я делаю это, если для быстрой проверки изменяю локальные файлы на сервере (нет рекомендуемых и вероятных причин, по которым у вас возникла эта проблема: D), я проверяю измененные файлы после нахождения решения.

Несмотря на то, что на этот вопрос уже есть много ответов, исходный вопрос состоит в том, чтобы решить этот вопрос

<цитата>

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

Поскольку двоичные файлы нельзя объединить, простой ответ:

git checkout public/images/icon.gif
 

При этом файл восстановит свое предыдущее состояние в этой ветке.

Обычно я делаю git stash , если не хочу потерять свои изменения, или что-то вроде git checkout . , если меня не интересуют локально измененные файлы. IMO намного проще, чем reset --hard , clean ... и все это больше подходит для выхода из ветки, как в удаленном, включая коммиты, неотслеживаемые файлы, а не просто решение локально измененного файл.

Я думаю, вы также можете принудительно использовать git push -f / git push --force

вопрос касается вытягивания, а не выталкивания.

Я перепробовал почти все, что смог найти здесь, в моем случае ничего не помогло.

Что сработало, так это git merge -X theirs

Шаг 1 . (необязательно)
Из корня вашего локального репозитория сохраните резервную копию и очистить текущую папку :

mkdir -p ../<branch>-bkp && mv --backup=t * ../<branch>-bkp
 

Шаг 2 . Загрузите все файлы и папки ветки из удаленного репозитория:

git checkout <branch> && git add -A . && git reset --hard origin/<branch> && git pull
 

где вы должны заменить <branch> на название ветки вы хотите перезаписать.

<▪Comments:

  • Вы можете предпочесть вручную резервное копирование и удаление текущих файлов и папки вместо шага 1 .
    Фактически, я рекомендую делать это с помощью файлового обработчика в графическом интерфейсе ваша операционная система.
  • Если вы пропустите шаг 1 , будьте осторожны: вы потеряете всю работу в локальном репозиторий!
  • <мениВажно : если вы пропустите git pull на шаге 2 ,
    вы рискуете не получить последнюю версию из удаленного репозитория !
    Согласно второй ссылке ниже, git reset --hard будет
    сбросить промежуточную область и рабочий каталог, чтобы они соответствовали максимальному недавняя фиксация .
    Мой опыт опровергает это утверждение!
  • Если вы запустите git reset --hard origin/<branch_to_overwrite> без предварительного удаления всех файлов и папок из локального репозитория, помните, что любые ненужные файлы, которые все еще лежат, могут проникнуть на пульт репозиторий в более позднем git push , даже если это не было вашим намерением.
    Дополнительный git add -A . на шаге 2 предотвращает это, если вы выберите опустить шаг 1 .

Ссылки:
https://gitforwindows.org/
https://www.atlassian.com/git/tutorials/undoing- изменения / git-reset
https://www.atlassian.com/git/tutorials/rewriting- история / git-reflog

Вы можете попробовать:

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

У меня это сработало очень хорошо!

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