git pull сохраняет локальные изменения

132

Как я могу безопасно обновить (вытащить) проект git, не трогая определенные файлы, даже если есть изменения в исходной версии?

myrepo / Config / config.php

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

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

Итак, мне нужен способ писать сценарии обновления, которые не теряют то, что было изменено локально. Я надеялся на что-нибудь простое:

git assume-remote-unchanged file1
git assume-remote-unchanged file2

затем git pull

Джонни Эверсон
источник
Изменения config.phpзафиксированы?
Марк Лонгэр
Это не совершено. Я бы предпочел не делать этого
Джонни Эверсон
@JhonnyEverson: Это тот же самый общий класс проблемы (у вас есть файл конфигурации, и вы не хотите фиксировать определенные настройки, но структуру файла конфигурации необходимо отслеживать.)
Daenyth

Ответы:

249

Есть простое решение, основанное на Git stash. Спрячьте все, что вы изменили, возьмите все новое, примените свой запас.

git stash
git pull
git stash pop

На тайнике могут быть конфликты. В случае, который вы описываете, на самом деле будет конфликт для config.php. Но разрешить конфликт легко, потому что вы знаете, что то, что вы кладете в тайник, - это то, что вы хотите. Так сделай это:

git checkout --theirs -- config.php
GoZoner
источник
5
эта команда git checkout --theirs очень сбивает с толку. Один раз он сделал то, что я хотел, а в другой раз сделал что-то действительно плохое. Есть хорошая документация по нему?
Milimetric
3
Да, иногда слова «их» и «наши» могут сбивать с толку. В git merge«нашем» указано то, что в данный момент находится в рабочем каталоге. Но на git rebase(или git rebase -onto) значение можно поменять местами.
GoZoner
1
git stash , git pull , git stash apply Вы можете сбросить тайник с помощью: git stash dropПосле успешного объединения изменений
BeingSuman
12
Дело в том, что с git нужно понимать, что он будет делать. Еще одна вещь, связанная с git, заключается в том, что даже умным людям часто очень трудно понять, что git собирается делать.
Брэд Томас
1
Вы должны проверить, действительно ли есть что припрятать. В противном случае вы бы извлекли сохраненные изменения из более раннего git stash.
Йорн Реймердес
15

Если у вас есть файл в вашем репо, который должен быть настроен большинством съемщиков, переименуйте файл во что-то вроде config.php.templateи добавьте config.phpв свой .gitignore.

KurzedMetal
источник
5
проверьте и этот ответ , вы можете использовать его, .gitattributesчтобы всегда сохранять свои изменения при слиянии.
KurzedMetal
Это больше похоже на то, что мне нужно. Шаблон - это элегантное решение, но, боюсь, я не могу его использовать, поскольку я просто пишу сценарии развертывания.
Джонни Эверсон
6

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

При условии, что:

  1. Ты на ветке master
  2. Восходящий филиал находится masterвorigin
  3. У вас нет незафиксированных изменений

.... вы могли бы сделать:

# Do a pull as usual, but don't commit the result:
git pull --no-commit

# Overwrite config/config.php with the version that was there before the merge
# and also stage that version:
git checkout HEAD config/config.php

# Create the commit:
git commit -F .git/MERGE_MSG

Вы можете создать для этого псевдоним, если вам нужно делать это часто. Обратите внимание, что если у вас есть незафиксированные изменения config/config.php, они будут отброшены.

Марк Лонгэр
источник
4

Мы также можем попробовать git pull с rebase

git pull --rebase origin dev
Бхавеш Мания
источник
1

Чтобы ответить на вопрос: если вы хотите исключить определенные файлы оформления заказа, вы можете использовать sparse-checkout

1) В .git/info/sparse-checkoutопределите, что вы хотите сохранить. Здесь нам нужны все (*), кроме (обратите внимание на восклицательный знак) config.php:

 /*
 !/config.php

2) Скажите git, что вы хотите принять во внимание разреженную проверку

 git config core.sparseCheckout true

3) Если у вас уже есть этот файл локально, сделайте то, что git делает при разреженной проверке (скажите ему, что он должен исключить этот файл, установив на нем флаг "skip-worktree")

git update-index --skip-worktree config.php

4) Наслаждайтесь репозиторием, в котором ваш файл config.php принадлежит вам - независимо от того, какие изменения есть в репозитории.


Обратите внимание, что значения конфигурации НЕ ДОЛЖНЫ быть в системе управления версиями:

  • Это потенциальное нарушение безопасности
  • Это вызывает проблемы, подобные этой, для развертывания

Это означает, что вы ДОЛЖНЫ исключить их (поместить их в .gitignore перед первой фиксацией) и создать соответствующий файл в каждом экземпляре, где вы проверяете свое приложение (путем копирования и адаптации файла «шаблона»).

Обратите внимание, что после того, как файл возьмет на себя управление git, .gitignore не будет иметь никакого эффекта.

Учитывая, что, когда файл находится под контролем источника, у вас есть только два варианта (): - перебазировать всю историю, чтобы удалить файл (с помощью git filter-branch) - создать фиксацию, которая удаляет файл. Это похоже на проигрышную битву, но иногда с этим приходится мириться.

Пьер-Оливье Варес
источник
0

Если это локальные незафиксированные изменения, избегайте конфликта слияния при извлечении.

git stash save
git pull
git stash pop

обратитесь - https://happygitwithr.com/pull-tricky.html

Уджвал Рой
источник