Застрял репо с использованием 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 поскольку его файл конфигурации шаблона адаптирован к каждой локальной среде.

Базовый "шаблон" может меняться. Ничего удивительного. Вот что я планировал:

  1. переиндексации wp-config.php
  2. stash мои собственные изменения конфигурации
  3. pull origin master
  4. 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,

Другие вопросы по тегам