Может ли git автоматически переключаться между пробелами и вкладками?

Я использую вкладки для отступов в своих программах на Python, но я хотел бы сотрудничать (используя git) с людьми, которые вместо этого используют пробелы.

Есть ли способ для git автоматически конвертировать между пробелами и вкладками (скажем, 4 пробела = 1 вкладка) при нажатии / выборке? (аналогично преобразованию CR / LF)


person Olivier Verdier    schedule 23.02.2010    source источник
comment
PEP8 - это как раз моя проблема. Все следят за ним, и я застрял на своих вкладках. Я думаю, что один отступ = одна табуляция - это правильно (почему пробелы? Почему 4 пробела? PEP8 этого не объясняет ...). В любом случае, с помощью этого трюка с git я могу с радостью использовать вкладки на своем компьютере и делиться своим кодом со всеми последователями PEP8.   -  person Olivier Verdier    schedule 23.02.2010
comment
Ой! Я использую TextMate и могу преобразовывать пробелы в табуляции. Дело в том, что когда я нажимаю вкладку, мне нравится, что мой редактор пишет ... вкладку. Поэтому, если я проверяю проект Python с пробелами, я вставляю всевозможные вкладки. Я должен вручную преобразовать в вкладки, но когда я регистрируюсь, похоже, что 1000 удалений, 1000 добавлений, и мои соавторы не будут довольны. :-)   -  person Olivier Verdier    schedule 23.02.2010
comment
Причина, по которой PEP8 указывает пробелы вместо табуляции, заключается в правилах отступа продолжения. Есть два способа продолжить слишком длинную строку внутри скобок. Если вы начинаете новую строку сразу после скобки, вы просто делаете отступ. Если вместо этого вы поместите часть содержимого круглой скобки в первую строку, вам придется продолжить скобку на следующей строке на уровне отступа открывающей скобки. Если вы используете вкладки, это не работает.   -  person John Christopher Jones    schedule 25.11.2015
comment
@JohnChristopherJones в этой ситуации можно использовать табуляцию для сопоставления отступа с предыдущей строкой, а затем пробелы для сопоставления позиции в предыдущей строке. Это можно легко преобразовать в пробелы. К сожалению, обратное неверно, потому что оно смешивает информацию об отступах с информацией о выравнивании.   -  person Patrick Parker    schedule 11.09.2019


Ответы (4)


Вот полное решение:

Добавьте в свой репозиторий файл .git/info/attributes, содержащий:

*.py  filter=tabspace

Linux / Unix

Теперь запустим команды:

git config --global filter.tabspace.smudge 'unexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'expand --tabs=4 --initial'

OS X

Сначала установите coreutils с помощью brew:

brew install coreutils

Теперь запустим команды:

git config --global filter.tabspace.smudge 'gunexpand --tabs=4 --first-only'
git config --global filter.tabspace.clean 'gexpand --tabs=4 --initial'

Все системы

Теперь вы можете проверить все файлы своего проекта. Вы можете сделать это с помощью:

git checkout HEAD -- **

и все файлы python теперь будут иметь табуляции вместо пробелов.

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

person Olivier Verdier    schedule 23.02.2010
comment
@Olivier: хороший трис, git checkout --force (быстрее, чем удалить и снова проверить соответствующие файлы) - person VonC; 17.03.2010
comment
Чистый фильтр мне не подходит. Когда я делаю git add. Я получаю сообщение об ошибке: внешний фильтр expand --tabs = 4 --initial failed. Я на винде. Это имеет значение? - person Jeremy Hicks; 09.06.2011
comment
@Jeremy: expand / undepand - это команды unix. Вам придется либо найти порты / эквиваленты Windows, либо использовать что-то вроде Cygwin. - person Tim; 10.06.2011
comment
Я нашел бест рабочую версию sourceforge.net/projects/gnuwin32/files/ coreutils / 5.3.0 - person hazzik; 21.12.2011
comment
В OS X (снежный барс) unexpand и expand не имеют одинаковых параметров, и unexpand, похоже, не работают (нет разницы с параметром -a или без него) - person Marc-André Lafortune; 01.05.2012
comment
@ Marc-André Хорошее замечание. На самом деле я использую версии coreutils. (Установите homebrew, а затем запустите brew install coreutils). - person Olivier Verdier; 01.05.2012
comment
git checkout HEAD -- ** выдает ошибки типа error: pathspec 'name.sublime-project' did not match any file(s) known to git.. Есть ли способы их обойти? - person Kostas; 20.03.2013
comment
для всех, кто запутался ... чтобы использовать команды, как указано ... вам либо нужно добавить g в начало обеих команд - brew оставляет coreutils исполняемые файлы с префиксом, то есть gexpand - или как-то их псевдоним .. - person Alex Gray; 16.10.2013
comment
Почему конфиги глобальные, а файл атрибутов только в этом репозитории? Разве не имеет смысла поместить конфигурацию в это репо или сделать все глобальным? - person iconoclast; 19.07.2014
comment
@OlivierVerdier, последний шаг в моем случае ничего не делает. Наверное, потому что я не совсем понимаю, что он должен делать. Я знаю, что могу git checkout filename отменить изменения в определенном файле. Но, согласно моему пониманию вашего сообщения, git checkout HEAD -- ** должен пройти через все файлы в репо и применить фильтр? Это верно? - person Nimrod Dayan; 26.05.2016
comment
какая реальная прибыль от этой схемы? Почему бы просто не заменить все файлы? - person dmitryvim; 10.02.2017
comment
Вроде больше не работает, фильтры мне ничего не делают. После оформления в файлах все еще есть пробелы. Есть новости по этому поводу? - person Philipp Ludwig; 14.05.2017

Да, одно из возможных решений - использовать драйвер фильтра атрибутов git (см. Также книга GitPro), чтобы определить механизм размазывания / очистки.

alt text

Сюда:

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

Вы можете объявить этот драйвер фильтра (названный здесь 'tabspace') в .git/info/attributes (для фильтра, применяемого ко всем файлам в репозитории Git) со следующим содержимым:

*.py  filter=tabspace

Теперь запустим команды:

# local config for the current repo
git config filter.tabspace.smudge 'script_to_make_tabs'
git config filter.tabspace.clean 'script_to_make_spaces'

См. Оливье answer, чтобы получить конкретный рабочий пример такого набора инструкций по удалению / очистке.

person VonC    schedule 23.02.2010
comment
К сожалению, это просто не работает. Я выполнил все инструкции, но git не применяет приспособление. :-( Когда я оформляю заказ, фильтр пятен не применяется, и когда я регистрируюсь, тоже ничего не происходит ... git иногда так расстраивает ... - person Olivier Verdier; 23.02.2010
comment
@Olivier: Странно, у меня никогда не было проблем с этим, пока я тщательно ограничивал область действия фильтра атрибутов (конкретным поддеревом, только для определенного типа файлов), чтобы не замедлять оформление / проверку- в процессе. См., Например, stackoverflow .com / questions / 62264 /. - person VonC; 23.02.2010
comment
Спасибо! Теперь это работает. См. Полное решение: stackoverflow.com/questions/2316677/ - person Olivier Verdier; 23.02.2010
comment
@Vonc: возможно, стоит удалить флаг --global, поскольку это будет означать, что вы отправляете пробелы в каждый совместный проект ... - person Willem Van Onsem; 22.10.2014
comment
@CommuSoft только проектам, имеющим право .gitattributes. Но да, легче понять, если конфигурация хранится локально для репо. Я отредактировал ответ. - person VonC; 22.10.2014

Очень полезная информация для всех, кто использует GitHub (или другой подобный сервис)

~/.gitconfig

[filter "tabspace"]
    smudge = unexpand --tabs=4 --first-only
    clean = expand --tabs=4 --initial
[filter "tabspace2"]
    smudge = unexpand --tabs=2 --first-only
    clean = expand --tabs=2 --initial

Затем у меня есть два файла: attributes

*.js  filter=tabspace
*.html  filter=tabspace
*.css  filter=tabspace
*.json  filter=tabspace

и attributes2

*.js  filter=tabspace2
*.html  filter=tabspace2
*.css  filter=tabspace2
*.json  filter=tabspace2

Работа над личными проектами

mkdir project
cd project
git init
cp ~/path/to/attributes .git/info/

Таким образом, когда вы, наконец, разместите свою работу на github, это не будет выглядеть глупо в представлении кода с 8 space tabs, которое является поведением по умолчанию во всех браузерах.

Участие в других проектах

mkdir project
cd project
git init
cp ~/path/to/attributes2 .git/info/attributes
git remote add origin [email protected]:some/repo.git
git pull origin branch

Таким образом, вы можете работать с обычными вкладками в 2 space indented проектах.

Конечно, вы можете написать аналогичное решение для преобразования из 4 space to 2 space, что имеет место, если вы хотите внести свой вклад в проекты, опубликованные мной, и вы, как правило, используете 2 пробела при разработке.

person simo    schedule 07.02.2013
comment
Связано: Сохранение конфигурации git как части репозитория; также обратите внимание, что вы можете использовать (и зафиксировать) файл .gitattributes в своем репо. - person Tobias Kienzler; 03.05.2016

Если вы используете Windows, у вас есть несколько дополнительных шагов, чтобы получить Решение @Olivier Verdier работает.

  1. Загрузите CoreUtils для Windows.
  2. После установки укажите место установки в вашем PATH (Как добавить переменную пути)
  3. Я переименовал expand.exe в gexpand.exe, так как уже есть утилита расширения Windows.
person odyth    schedule 19.05.2018