Як змусити "git pull" перезаписати локальні файли?

Як примусово перезаписати локальні файли в git pull ?

Сценарій наступний:

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

Це помилка, яку я отримую:

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

Як змусити Git перезаписати їх? Ця людина дизайнер. Зазвичай я дозволяю все конфлікти вручну, тому на сервері встановлена ​​остання версія, яку їм просто необхідно оновити на своєму комп'ютері.

5705
14 июля '09 в 17:58 2009-07-14 17:58 заданий Jakub Troszok 14 липня '09 о 17:58 2009-07-14 17:58
@ 39 відповідей
  • 1
  • 2

Важливо: якщо у вас є які-небудь локальні зміни, вони будуть втрачені. З опцією --hard або без --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 
7980
17 янв. відповідь дан RNA 17 Січня. 2012-01-17 03:02 '12 в 3:02 2012-01-17 3:02

Спробуйте наступне:

 git reset --hard HEAD git pull 
border=0

Він повинен робити те, що ви хочете.

798
09 мая '10 в 22:45 2010-05-09 22:45 відповідь дан Travis Reeder 09 травня '10 о 22:45 2010-05-09 22:45

УВАГА: git clean видаляє всі ваші неотслежіваемих файли / каталоги і не може бути скасований.


Іноді просто clean -f не допомагає. Якщо у вас немає відслідковуються каталогів, опція -d також необхідна:

 # WARNING: this can't be undone! git reset --hard HEAD git clean -f -d git pull 

УВАГА: git clean видаляє всі ваші неотслежіваемих файли / каталоги і не може бути скасований.

Спробуйте -n використовувати -n ( --dry-run ). Це покаже вам, що буде видалено, фактично нічого не видаляючи:

 git clean -n -f -d 

Приклад виведення:

 Would remove untracked-file-1.txt Would remove untracked-file-2.txt Would remove untracked/folder ... 
406
19 марта '11 в 12:10 2011-03-19 12:10 відповідь дан David Avsajanishvili 19 березня '11 о 12:10 2011-03-19 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" - значення для цієї опції. Ви віддаєте перевагу використовувати "свої" зміни замість "ваших" змін, якщо є конфлікт.

347
11 апр. відповідь дан Richard Kersey 11 Квітня. 2012-04-11 23:13 '12 о 23:13 2012-04-11 23:13

Замість цього:

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

Я б порадив зробити наступне:

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

Не потрібно брати все пульти і гілки, якщо ви йдете на reset в гілку origin / master справа?

248
26 апр. відповідь дан Johanneke 26 Квітня. 2013-04-26 16:48 '13 о 16:48 2013-04-26 16:48

Схоже, що найкраще зробити це:

 git clean 

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

125
14 июля '09 в 18:16 2009-07-14 18:16 відповідь дан Jakub Troszok 14 липня '09 о 18:16 2009-07-14 18:16

Увага, це назавжди знищить ваші файли, якщо у вас є які-небудь записи каталогу / * в вашому файлі gitignore.

Деякі відповіді здаються жахливими. Жахливо в сенсі того, що трапилося з @Lauri, слідуючи пропозицією Давида Авсаджанішвілі.

Швидше (мерзотник> 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} 
102
12 февр. відповідь дан Hedgehog 12 февр. 2012-02-12 02:00 '12 о 2:00 2012-02-12 2:00

Ви можете знайти цю команду корисною для видалення локальних змін:

 git checkout <your-branch> -f 

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

 git clean -f 

Якщо ви хочете видалити непотрібні каталоги на додаток до файлів без сліду:

 git clean -fd 
88
05 авг. відповідь дан Vishal 05 Серпня. 2010-08-05 21:06 '10 о 21:06 2010-08-05 21:06

Замість злиття з git pull спробуйте це:

git fetch --all

з наступним:

git reset --hard origin/master .

81
22 нояб. відповідь дан Lloyd Moore 22 нояб. 2012-11-22 13:56 '12 о 13:56 2012-11-22 13:56

Єдине, що спрацювало для мене, було:

 git reset --hard HEAD~5 

Це поверне вам п'ять коммітов, а потім

 git pull 

Я виявив, що, подивившись як скасувати Git merge .

54
06 мая '11 в 0:53 2011-05-06 00:53 відповідь дан Chris BIllante 06 травня '11 в 0:53 2011-05-06 00:53

Проблема з усіма цими рішеннями полягає в тому, що вони все або занадто складні, або ще більш серйозна проблема полягає в тому, що вони видаляють всі необроблені файли з веб-сервера, чого ми не хочемо, оскільки завжди потрібні файли конфігурації які знаходяться на сервері , а не в репозиторії Git.

Ось найчистіше рішення, яке ми використовуємо:

51
06 нояб. відповідь дан Strahinja Kustudic 06 нояб. 2012-11-06 02:32 '12 в 2:32 2012-11-06 2:32

У мене така ж проблема. Ніхто не дав мені це рішення, але воно спрацювало для мене.

Я вирішив це:

  1. Видалити всі файли. Залиште тільки каталог .git .
  2. git reset --hard HEAD
  3. git pull
  4. git push

Тепер це працює.

38
13 янв. відповідь дан John John Pichler 13 Січня. 2011-01-13 02:58 '11 о 2:58 2011-01-13 2:58

Перш за все, спробуйте стандартний спосіб:

 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 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 завжди виявляє деякі "зміни".

33
26 окт. відповідь дан kenorb 26 Жовтня. 2012-10-26 12:17 '12 о 12:17 2012-10-26 12:17

бонус:

Говорячи про pull / fetch / merge в попередніх відповідях, я хотів би поділитися цікавим і продуктивним прийомом:

git pull --rebase

Ця команда є найкориснішою командою в моєму житті в Git, яка заощадила багато часу.

Перед відправкою вашого нового коммітов на сервер, спробуйте цю команду, і вона автоматично синхронізує останні зміни сервера (з вибіркою + злиттям) та помістить ваш Комміт нагорі в журналі Git. Немає необхідності турбуватися про ручному витяганні / злиття.

Знайти деталі в Що робить "git pull --rebase"? ,

31
23 дек. відповідь дан Sazzad Hissain Khan 23 дек. 2015-12-23 18:41 '15 о 18:41 2015-12-23 18:41

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

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

Попередження. Цей script дуже потужний, тому ви можете втратити свої зміни.

27
07 авг. відповідь дан Robert Moon 07 Серпня. 2015-08-07 06:03 '15 о 6:03 2015-08-07 6:03

У мене була аналогічна проблема. Я повинен був зробити це:

 git reset --hard HEAD git clean -f git pull 
27
14 янв. відповідь дан Ryan 14 Січня. 2011-01-14 18:18 '11 о 18:18 2011-01-14 18:18

Грунтуючись на моїх власних подібних дослідах, рішення, запропоноване Strahinja Kustudic вище, є безумовно кращим. Як відзначали інші, просто виконання жорсткого reset видалить все не перевірені файли, які можуть включати в себе безліч речей, які ви не хочете видаляти, наприклад, файли конфігурації. Що більш безпечно, потрібно видалити тільки файли, які повинні бути додані, і, в цьому відношенні, ви, ймовірно, також захочете перевірити будь-які локально модифіковані файли, які повинні бути оновлені.

Саме тому я оновив Kustudic script, щоб зробити саме це. Я також виправив друкарську помилку (відсутній в оригіналі).

26
27 февр. відповідь дан Rolf Kaiser 27 февр. 2013-02-27 17:43 '13 о 17:43 2013-02-27 17:43

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

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

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

23
12 дек. відповідь дан tiho 12 дек. 2011-12-12 22:54 '11 о 22:54 2011-12-12 22:54

Ще простіше:

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

Це перевизначити ваш локальний файл з файлом на git

20
05 мая '15 в 11:03 2015-05-05 11:03 відповідь дан maximus 69 05 травня '15 о 11:03 2015-05-05 11:03

Здається, що більшість відповідей тут зосереджено на гілці 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}" 

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

19
25 февр. відповідь дан JacobEvelyn 25 февр. 2014-02-25 20:19 '14 о 20:19 2014-02-25 20:19

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

19
03 авг. відповідь дан Tierlieb 03 Серпня. 2011-08-03 12:23 '11 в 12:23 2011-08-03 12:23

Я просто вирішив це сам:

18
03 дек. відповідь дан Simon B. 03 дек. 2010-12-03 18:00 '10 о 18:00 2010-12-03 18:00

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

 git rm [file] 

Тоді я можу тягнути просто відмінно.

17
19 сент. відповідь дан Chen Zhang 19 сент. 2011-09-19 17:18 '11 о 17:18 2011-09-19 17:18

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

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

Це!

16
05 сент. відповідь дан ddmytrenko 05 сент. 2015-09-05 21:23 '15 о 21:23 2015-09-05 21:23

Ці чотири команди працюють для мене.

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

Щоб перевірити / витягнути після виконання цих команд

 git pull origin master 

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

13
20 марта '14 в 7:24 2014-03-20 07:24 відповідь дан vishesh chandra 20 березня '14 о 7:24 2014-03-20 7:24

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

12
22 окт. відповідь дан Snowcrash 22 Жовтня. 2014-10-22 20:31 '14 о 20:31 2014-10-22 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 

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

12
19 окт. відповідь дан user2696128 19 Жовтня. 2015-10-19 12:54 '15 о 12:54 2015-10-19 12:54

Reset покажчик і head на origin/master , але не reset робоче дерево:

 git reset origin/master 
11
15 февр. відповідь дан user811773 15 февр. 2013-02-15 16:41 '13 о 16:41 2013-02-15 16:41

вимоги:

  • Відстежуйте локальні зміни, тому ніхто не втрачає їх.
  • Зробити локальний репозиторій сумісним з репозиторієм віддаленого джерела.

Рішення:

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

     git stash --include-untracked git fetch --all git clean -fdx git reset --hard origin/master 
9
02 сент. відповідь дан vezenkov 02 сент. 2015-09-02 02:00 '15 о 2:00 2015-09-02 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 
9
08 июля '16 в 16:11 2016-07-08 16:11 відповідь дан Venkat Kotra 08 липня '16 о 16:11 2016-07-08 16:11
  • 1
  • 2

Інші питання по мітках або Задайте питання