clang-format во всех коммитах, чтобы исправить отступы и удалить конечные пробелы

Я планирую исправить только отступы и конечные пробелы во всех коммитах. Я не хочу помещать .clang-format файл в каталог. Брекеты трогать тоже не хочу.

Команда, которую я рассмотрел, должна быть похожа на

git filter-branch --tree-filter 'clang-format ?????????' --tag-name-filter cat -- --all

Как я могу это сделать?

Требования:

  • Никакого вреда для папки .git.
  • IndentWidth: 2
  • Удалите все конечные пробелы
  • Никаких других изменений в файле (например, фиксация мест открытия / закрытия).

person mercury    schedule 04.02.2021    source источник
comment
Это вопрос git или вопрос формата clang? Эти два понятия должны быть ортогональными.   -  person mkrieger1    schedule 05.02.2021
comment
@ mkrieger1, оба. Ортогональные решения не решают мою проблему. Мне нужно, чтобы оба ограничения не мешали друг другу. Для меня clang-format должен работать в таких особых условиях. Например, я не могу поместить файл .clang-format в каталог.   -  person mercury    schedule 05.02.2021
comment
Вы читали clang.llvm.org/docs/ClangFormatStyleOptions.html, чтобы выяснить параметры, которые вы хотите использовать, и возникла ли проблема, когда вы пытались их применить? Я не уверен, что именно вы имеете в виду, говоря, что папка .git не причинит вреда, потому что git filter-branch перезаписывает историю, которая по определению касается содержимого папки .git.   -  person mkrieger1    schedule 05.02.2021
comment
@ mkrieger1, решения на основе linux wild sed могут повредить файлы в папке .git. Я просто сказал это, чтобы предотвратить некоторые безумные предложения.   -  person mercury    schedule 05.02.2021
comment
Хорошо, тогда используйте git filter-branch. Он создан для этого и не убьет себя.   -  person mkrieger1    schedule 05.02.2021
comment
@ mkrieger1, вот откуда у меня базовый код. Без .clang-format как я могу поставить IndentWith на встроенный переключатель, а также какова команда для конечных пробелов?   -  person mercury    schedule 05.02.2021
comment
Итак, вы читали clang.llvm.org/docs/ClangFormatStyleOptions.html? Я почти уверен, что это объясняется там (в частности, это объясняется в первый раздел).   -  person mkrieger1    schedule 05.02.2021
comment
См. Также stackoverflow.com/questions/44482062/   -  person mkrieger1    schedule 05.02.2021
comment
@ mkrieger1, я видел эту страницу. Я не собираюсь использовать Google или другие стили. Мне нужно всего два изменения. Больше ничего не должно меняться. Кроме того, я тоже ничего не могу найти о конечных пробелах. У вас действительно есть ответ на этот вопрос?   -  person mercury    schedule 05.02.2021
comment
О конечных пробелах читайте - ›› здесь ‹< - Вы не нужно делать что-то особенное, clang-format их уберет в любом случае кажется.   -  person mkrieger1    schedule 05.02.2021
comment
@ mkrieger1, -style=Google очень плохо. Я объяснил, почему не использую этот метод.   -  person mercury    schedule 05.02.2021
comment
Я не советую вам использовать -style=Google. Я просто указал вам на ответ, в котором говорится, что clang-format в любом случае удаляет конечные пробелы.   -  person mkrieger1    schedule 05.02.2021


Ответы (2)


Со стороны Git: команда filter-branch 1 в принципе работает следующим образом:

  • извлечение каждого коммита по одному во временный каталог;
  • запуск ваших фильтров в временном каталоге на, в котором был извлечен коммит; а потом
  • создание нового коммита замены из результатов, оставленных в каталоге.

Замещающие коммиты связываются вместе, по одному, обычным способом, и когда все коммиты отфильтрованы, Git обновляет различные ветки и другие подобные ссылки (--all) по мере необходимости, при этом --tag-name-filter определяет новые имена тегов (для вас случае это все правильно).

Метод --tree-filter, который на сегодняшний день является самым медленным фильтром, использует этот подход без каких-либо оптимизаций. Существуют другие фильтры, чтобы (а) работать быстрее, если вы не планируете трогать большую часть файлов и / или (б) вносить изменения в такие вещи, как фиксация сообщений или другие метаданные, вместо или в дополнение к снимкам. Вероятно, нет смысла пытаться использовать более оптимальный фильтр, поскольку вам действительно нужно извлечь все файлы, чтобы их переформатировать. Так что здесь нужно убрать то, что каждый запуск в формате clang будет запускаться в частном временном каталоге, не содержащем репозитория Git. $PWD этой команды будет этим частным каталогом.

Чтобы ускорить процесс, рекомендуется использовать параметр -d, чтобы поместить этот частный каталог в память или на твердотельный накопитель или в другую файловую систему с быстрым доступом. Например, если /tmp - файловая система в памяти, mkdir /tmp/foo; git filter-branch -d /tmp/foo ... может работать намного быстрее, чем система без директивы -d /tmp/foo. По умолчанию -d - это подкаталог, который Git создает внутри каталога .git; если это медленная, но высоконадежная файловая система, ваша операция ветвления фильтра будет выполняться очень медленно.

Со стороны формата clang: используйте любые -style= параметры, которые вам нравятся. Как отмечали многочисленные комментаторы, удаление конечных пробелов используется по умолчанию (и, по-видимому, сейчас нет никаких вариантов для управления этим).

Обратите внимание, что можно добавить .clang-format файл во временный каталог. Если вы оставите его там, он будет добавляться в каждый коммит замены. Если вы удалите его снова после добавления, отсутствие файла .clang-format (потому что вы его удалили) будет тем, что есть в каждой фиксации. Если вы ничего не сделаете, будет или не будет .clang-format файла в зависимости от того, был ли он в фильтруемом коммите.

Если вы решите, что, в конце концов, вы хотели бы использовать .clang-format файл и добавлять его в каждую фиксацию, обратите внимание, что вам придется копировать файл из-за пределов временного каталог, в временный каталог, перед каждым запуском clang-format, потому что Git сам очищает временный каталог между каждой фиксацией. Обратите внимание, что вы не будете знать, где находится временный каталог, 2, поэтому для копирования известного файла используйте, например, полный путь: cp /tmp/new-clang-format-file .clang-format && clang-format -style=file.


1 git filter-branch сейчас номинально устарел, но его замена, filter-repo, не включена в Git, поэтому здесь возникает небольшая дилемма. Вы можете установить filter-repo отдельно, или для такого рода одноразовой работы вы можете просто жить с filter-branch.

2 Даже с параметром -d Git создает различные подкаталоги указанного вами каталога (он удаляет кучу временных файлов в разных местах для своих собственных целей).

person torek    schedule 04.02.2021
comment
Большое тебе спасибо. Не могли бы вы также посоветовать, как исправить отступ? - person mercury; 05.02.2021
comment
На самом деле я не знаю: я всегда использовал файл в стиле .clang, сгенерированный с помощью одной из опций больших домов (microsoft, google, кто угодно), а затем настроенный на местные вкусы. Так что файлы формата .clang, которые я унаследовал, всегда были огромными. - person torek; 05.02.2021
comment
предоставление -style=/media/..../.clang-format выдаст мне ошибку: Invalid value for -style. - person mercury; 05.02.2021
comment
Да, это буквально -style=file, а затем в формате clang выполняется поиск .clang-format файла, начиная с $ PWD и выше. Так что, если вы используете файл, вам нужно нужно скопировать его на место. Вы можете удалить его позже, если не хотите оставлять директивы в коммите. ... Ой, или: mkdir /tmp/foo; cp /media/.../.clang-format /tmp/foo; git filter-branch -d /tmp/foo, вероятно, сработает, хотя я никогда этого не проверял. - person torek; 05.02.2021
comment
Опять получаю No such file or directory. Я поместил его в файл с именем aaa в родительском каталоге и сказал -style=aaa. - person mercury; 05.02.2021
comment
Я не думаю, что -style принимает имена файлов. Кажется, он принимает буквальную строку file, что означает поиск .clang-format (и вариант с подчеркиванием), а также microsoft, google и т. Д. То есть аргументы name для -style являются магическими именами. Остальные -style аргументы - это отдельные элементы, которые вы можете указать в файле. - person torek; 05.02.2021

Кажется, что clang-format вносит столько изменений, что я не сказал об этом. Также вылетает на сетевых дисках.

Для тех, кто прочтет этот пост в будущем: я заменил clang-format на sed, так как он выполняет такую ​​простую работу намного лучше, чем clang-format, и без проблем. Вот мое решение.

git filter-branch -f --tree-filter "find . -regex '.*\.\(cpp\|hpp\|c\|h\)' | xargs -L1 sed -i -b -e 's/\s*$/\r/g' -e 's/\t/  /g'" --tag-name-filter cat -- --all

У меня тоже были проблемы с **/*.h wild-card. Это не работало правильно. Итак, я заменил его на find.

Я добавил -f из-за некоторых ошибок.

Я также добавил \r, поскольку это среда Linux, редактирующая файл Windows. Не используйте \r, если он вам не нужен.

person mercury    schedule 05.02.2021