Застрял репо с использованием stash после нормализации crlf?
У меня есть локальное репо в состоянии, которое запрещает мне либо фиксировать, копить, оформлять заказы в другой ветке или даже отменять изменения. Так что я просто застрял.
Я постараюсь описать, какие шаги привели меня к этой ситуации, насколько я помню.
Садитесь, пожалуйста.
Не так давно, на другом компьютере далеко, далеко... другой разработчик нормализовал crlf в проекте в соответствии с: https://help.github.com/articles/dealing-with-line-endings
В то же время (вы знаете, скорость света...) я сделал некоторые локальные изменения, зафиксировал и потянул.
Когда я вытащил Git сказал:
error: Your local changes to the following files would be overwritten by merge:
wp-config.php
wp-config.php
ранее был удален из индекса с помощью git update-index --assume-unchanged wp-config.php
поскольку его файл конфигурации шаблона адаптирован к каждой локальной среде.
Базовый "шаблон" может меняться. Ничего удивительного. Вот что я планировал:
- переиндексации
wp-config.php
stash
мои собственные изменения конфигурацииpull origin master
stash apply
мой конфиг обратно
На шаге 3 все пошло не так. git pull origin master
все равно поднял ошибку выше, как будто тайник был неэффективен.
git status
сказал wp-config.php
изменения не ставились для фиксации. Это удивило меня немного после тайника.
Так как я спрятал свои изменения, я побежал git checkout -- wp-config.php
... но без какого-либо эффекта! Файл все еще не был подготовлен для фиксации.
Так как я схожу с ума, я создал новую ветку my-config, добавил и зафиксировал wp-config.php
в него, затем переключился обратно на мастер, удалил wp-config.php
(с помощью git rm
) и слил происхождение / мастер... с успехом!
Так что теперь, когда мастер был обновлен и очищен, я планировал восстановить свою конфигурацию без помощи Git (редактирование файла вручную).
Поскольку я хотел знать, что случилось, я переключился на ветку my-config и попробовал здесь очень простую манипуляцию:
git stash
git stash apply
И угадай что? stash apply
не удалось сказать:
error: Your local changes to the following files would be overwritten by merge:
wordpress/license.txt
wordpress/readme.html
...
(all the files that where modified by the crlf conversion)
А теперь я застрял на своей ветке (и планирую ее увидеть, франкофоны поймут;)) так как:
git stash apply
,commit
а такжеcheckout master
выдает ошибку вышеgit stash
создает запись тайника, но не изменяет неустановленные состояния- а также
git checkout -- <file>
ни один не удаляет неустановленное состояние
Единственное, что я могу сейчас сделать - это удалить все эти файлы (используя ОС rm
) чтобы можно было вернуться в главную ветку.
Правдивая история.
Я хотел бы понять, что произошло в основной ветке, затем в ветке my-config, и что привело меня в такие ситуации (я подозреваю, что использование stash для преобразованного файла crlf).
Важные заметки:
- Я бегу на Linux
git core.autocrlf
находится наinput
- мой
.gitattributes
такой же, как в статье "Работа с окончаниями строки" - Я относительно новичок в Git (второй день жизни с ним)
Когда я сделал stash
в ветке my-config это выдается:
warning: CRLF will be replaced by LF in wordpress/license.txt.
The file will have its original line endings in your working directory.
... (one for each crlf converted file) ...
Saved working directory and index state WIP on my-config: dbf65ad my config -- should not be pushed
HEAD is now at dbf65ad my config -- should not be pushed
(dbf65ad
это единственный коммит, который я сделал в ветке my-config)
3 ответа
После некоторого исследования я думаю, что произошло следующее. Ваш напарник изменил окончание, которое вызвало первый конфликт.
Вот почему вы спрятали свою работу, вытащили вещи (теперь без проблем) и снова начали применять тайник.
С обращением git stash apply
git запускает рекурсивное слияние ваших спрятанных изменений.
Сообщение об ошибке просто говорит о том, что вы столкнулись с конфликтом слияний. Согласно stash-документации разработчика, это может быть решено git stash drop
после разрешения конфликтов:
"Применение [stash] может привести к сбою при конфликтах; в этом случае оно не удаляется из списка stash. Вам необходимо разрешить конфликты вручную и вызвать
git stash drop
потом вручную."
Вывод: если конфигурация окончаний строк должна быть сделана в существующем проекте, представляется целесообразным сделать это с помощью .gitattributes
в вашей папке проекта. Так как он распространяется с вашей строкой end-change-commit, он избежит головной боли, переключающей вашу текущую работу на новый стандарт нормализации.
Изменение окончаний строк в проектах и .gitattributes
Согласно документации разработчиков .gitattributes
Вы можете изменить окончания строк для всех файлов (в активной ветке), выполнив следующие действия:
$ echo "<<filepattern>> eol=lf" >>.gitattributes
$ rm .git/index # Remove the index to force Git to
$ git reset # re-scan the working directory
$ git status # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"
замещать <<filepattern>>
с шаблоном, который соответствует вашим исходным файлам - в вашем случае *.py
для python-файлов (хорошее шаблонное объяснение дано в этом .gitignore
-описание).
Если у вас есть несколько файловых шаблонов, которые вы хотите добавить, вы можете добавить несколько определений конца строки к .gitattributes
,
Внимание: поскольку на втором шаге необходимо удалить
.git/index
(это зависит от ветки), это должно быть сделано в каждой ветке, которую вы хотите сохранить.
Если у вас есть много веток для обработки, вы можете написать короткий скрипт, повторяющийся в ваших ветках git.
Лучший способ перезагрузить ваш локальный модуль - это использовать
git clean -f -x -d
Это эффективно удаляет все неотслеживаемые изменения в вашем локальном модуле и возвращает его в "ванильное" состояние.
-f
чистые файлы.-x
чистые файлы обычно игнорируются.gitignore.-d
чистые каталоги.
Теперь беги git reset --hard origin/<BRANCH_NAME>
, Это вернет вашу ветку в состояние пульта.
git status
на данный момент должен сказать вам:
# On branch master
nothing to commit (working directory clean)
Если у вас есть реальные изменения, вы должны быть в состоянии git stash apply
поставить их обратно правильно.
Если git stash show stash@{0}
показывает больше изменений, чем вы ожидали, вы можете просто применить те, которые вы хотите видеть с git checkout stash@{0} -- <filename>
,
Надеюсь это поможет
Во-первых, что касается справочной страницы GitHub, я бы настоятельно рекомендовал установить:
git config --global core.autocrlf false
Пусть зарезервировать модификацию eol для явного объявления .gitattributes
файлы вместо глобального магического правила: держать core.autocrlf
ложно.
Во-вторых, вы можете увидеть, наблюдаете ли вы те же модификации EOL наgit stash
сgit update-index --skip-worktree
,