Я создал на веб-сервисе «GitHub» (далее я буду называть его «Гитхабом», чтобы можно было склонять) репозиторий, в который постепенно загружал файлы через веб-интерфейс, как по одному, так и группами. На данный момент в этом репозитории хранится около полутора сотен файлов в разных папках, в том числе с вложением папок разной глубины. Файлы имеют разные расширения.
Мне понадобилось переименовать сразу 157 файлов в описанном репозитории по следующему принципу:
00-00_имя-файла.ext # было
00-000_имя-файла.ext # стало, добавился '0'
В этом блоке кода показаны шаблоны. Вместо .ext
могут быть разные расширения (в моем случае это расширения .cpp
и .h
). Вместо имя-файла
могут быть разные названия из нескольких слов, эти названия могут быть разной длины. Вместо 00-00
могут быть, например, следующие последовательности символов: 00-01
, 00-02
, ..., 01-00
, 01-01
, ..., 02-00
, 02-01
, 02-02
и так далее. То есть мне понадобилось расширить второй номер, который идет после дефиса, с двух разрядов до трех, поэтому мне нужно переименовать все файлы, добавляя символ 0
в указанное выше место в названии файлов.
Я знаю, как через веб-интерфейс «Гитхаба» можно переименовывать файлы по одиночке, об этом можно прочитать в отдельной статье документации «Гитхаба», но там не описано, как переименовать сразу множество файлов проекта. Быстро, одной операцией, это сделать у меня не получилось, поэтому я разбил задачу на несколько более простых пунктов.
План действий
Клонировать репозиторий (создать копию) на свой компьютер;
Написать скрипт для переименования множества файлов проекта и переименовать их;
Создать коммит со всеми переименованиями;
Отправить изменения в оригинальный репозиторий на «Гитхабе».
1. Клонирование репозитория на свой компьютер
Я работаю в операционной системе «Windows 10» и пользуюсь программой (системой управления версиями) «Git for Windows» из командной строки. В качестве программы-оболочки я использую «PowerShell» версии 7. В качестве программы-«эмулятора терминала» использую «Windows Terminal».
Клонирование (создание копии) репозитория с «Гитхаба» на мой компьютер (иногда я буду сокращать путь к текущему местоположению с помощью многоточия ...
, чтобы команда влезла в формат статьи):
PS C:\...\repos> git clone https://github.com/ilyachalov/learncpp-com-examples
Команде git clone
просто передаём URL-адрес репозитория на «Гитхабе». Авторизация при этом не требуется. Насколько я понимаю, это потому, что этот мой репозиторий публичный. В результате этой команды в текущем местоположении создалась папка «learncpp-com-examples» с файлами репозитория. Для дальнейших действий удобнее перейти в эту папку и работать из нее.
PS C:\Users\Илья\source\repos> cd learncpp-com-examples
PS C:\Users\Илья\source\repos\learncpp-com-examples>
Для удобства далее я буду обозначать это местоположение так:
PS ..\learncpp-com-examples>
2. Скрипт для переименования файлов и его применение
За основу скрипта я взял код из примера 4 статьи про командлет «Rename-Item» документации программы-оболочки «PowerShell». Я переписал тот код под свои нужды, добавил регулярные выражения и получил следующее:
файл «rename-files.ps1» (в кодировке UTF-8 без BOM, окончания строк CRLF)
Get-ChildItem -File -Recurse |
Rename-Item -NewName {
$_.Name -replace '^(\d\d)-(\d\d)_(.*)', '$1-0$2_$3'
}
Данный скрипт просматривает только файлы (папки отбрасываются, это обеспечивается параметром -File
командлета «Get-ChildItem»), начиная с текущей папки и вглубь, во вложенных папках (это обеспечивается параметром -Recurse
командлета «Get-ChildItem»). Командлет «Get-ChildItem» отбирает все файлы, поэтому параметр -Path
командлету «Get-ChildItem» не требуется, он опущен. Файлы, отобранные командлетом «Get-ChildItem», передаются по конвейеру |
командлету «Rename-Item», который и выполняет переименования.
Я написал еще один вариант этого скрипта, который делает то же самое, но еще выдает во время своей работы сообщения в окно консоли, информирующие о ходе переименований. По окончании работы он выдает в окно консоли сообщение с информацией о количестве просмотренных файлов, а также о том, сколько из просмотренных файлов было переименовано:
файл «rename-files.ps1» (в кодировке UTF-8 без BOM, окончания строк CRLF)
$total = 0
$renamed = 0
Get-ChildItem -File -Recurse |
Rename-Item -NewName {
$old = $_.Name
$new = $old -replace '^(\d\d)-(\d\d)_(.*)', '$1-0$2_$3'
$script:total++
if ($old -ne $new) {
Write-Host "$old --> $new"
$script:renamed++
} else {
Write-Host "$new"
}
$new
}
"Проверено файлов всего: $total, из них переименовано: $renamed"
У меня есть более подробный разбор этого скрипта.
Для переименования файлов я поместил файл «rename-files.ps1» со скриптом в нужную папку клонированного репозитория и запустил его:
PS C:\Users\Илья\source\repos\learncpp-com-examples\chapters> .\rename-files
rename-files.ps1
00-00_helloworld.cpp --> 00-000_helloworld.cpp
00-01_helloworld-wait.cpp --> 00-001_helloworld-wait.cpp
00-02_cpp17compat.cpp --> 00-002_cpp17compat.cpp
00-03_cpp20compat.cpp --> 00-003_cpp20compat.cpp
01-00_snippet.cpp --> 01-000_snippet.cpp
...
02-98_io.cpp --> 02-098_io.cpp
02-98_main.cpp --> 02-098_main.cpp
02-99_io.cpp --> 02-099_io.cpp
02-99_io.h --> 02-099_io.h
02-99_main.cpp --> 02-099_main.cpp
Проверено файлов всего: 158, из них переименовано: 157
После окончания переименования файл «rename-files.ps1» скрипта следует из папки проекта удалить, чтобы он не мешал при создании коммита.
3.1. Проверка настроек Git-репозитория
Перед созданием коммита, который позже попадет на «Гитхаб», имеет смысл проверить настройку имени автора коммита и адреса электронной почты автора коммита, если вы не хотите «светить» их в интернете.
Для проверки настроек Git-репозитория удобно использовать следующую команду из папки проекта (благодаря параметру --show-origin
вы сможете увидеть, в каких файлах хранятся настройки Git-репозитория; часто разные настройки хранятся в разных файлах):
PS ..\learncpp-com-examples> git config --list --show-origin
Чтобы просмотреть только две интересующие меня настройки (имя автора коммита, его адрес электронной почты), можно использовать следующие две команды:
PS ..\learncpp-com-examples> git config user.name
Ilya Chalov
PS ..\learncpp-com-examples> git config user.email
почта@домен.ru
Имя у меня такое и зарегистрировано на «Гитхабе», а вот адрес электронной почты «светить» там не хотелось бы. «Гитхаб» по желанию пользователя создает для коммитов, выполняемых через веб-интерфейс, «служебный» адрес электронной почты, который «прикрывает» реальный адрес электронной почты пользователя.
Этот «служебный» адрес электронной почты можно посмотреть в настройках своей учетной записи на «Гитхабе» (меню «Settings / Emails», если заходить через свою аватарку в правом верхнем углу страниц веб-сервиса) по следующему URL-адресу (он сработает, если вы уже авторизованы на веб-сервисе):
Меню «Settings / Emails» (если заходить через свою аватарку)
https://github.com/settings/emails
Меняю адрес электронной почты в настройках текущего (параметр --local
) Git-репозитория:
PS ..\learncpp-com-examples> git config --local user.email служебный@github.com
3.2. Создание коммита со всеми переименованиями
Команду git mv
я не смог использовать для переименований, так как в ней, вроде бы, нельзя использовать регулярные выражения (можно использовать символы-джокеры, но их недостаточно). Однако, как пишут в известной книге про «Git», на самом деле команда git mv
— это совмещение трех команд: 1) переименование файла средствами операционной системы или с помощью других программ, 2) git rm
для файла с названием до переименования, 3) git add
для файла с названием после переименования.
Пункт первый из трех вышеперечисленных я уже выполнил ранее с помощью своего скрипта «rename-files.ps1». Оставшиеся два пункта можно выполнить для всех 157 переименованных файлов одной следующей командой:
PS ..\learncpp-com-examples> git add --all
Теперь все изменения помещены в индекс и можно, наконец, создать коммит:
PS ..\learncpp-com-examples> git commit -m "Переименование группы файлов (157 штук)"
4. Отправка изменений в оригинальный репозиторий на «Гитхабе»
При отправке изменений в оригинальный репозиторий на «Гитхабе» потребуется авторизация. Когда я попытался ввести свой пароль, «Гитхаб» сообщил мне, что с 13 августа 2021 года аутентификация с помощью пароля больше не используется. Мне было предложено пройти в документацию по следующей ссылке и почитать про действующие способы аутентификации.
Я выбрал способ аутентификации с помощью токена доступа и создал гранулированный токен доступа (сейчас на «Гитхабе» есть две действующие реализации токенов доступа: старая (классическая) и новая (гранулированные токены доступа, по-английски «fine-grained access token»)). У меня есть отдельная подробная статья про создание гранулированного токена доступа. Использовать токен доступа несложно: при аутентификации его нужно просто ввести (вставить из буфера обмена) вместо пароля.
Отправляю изменения в оригинальный репозиторий на «Гитхабе»:
PS C:\Users\Илья\source\repos\learncpp-com-examples> git push origin main
Username for 'https://github.com': ilyachalov
Password for 'https://ilyachalov@github.com':
При вводе пароля (в моем случае — токена доступа) ввод не отражается в окне консоли, но в действительности происходит. Вероятно, такой подход принят в целях безопасности, чтобы никто из посторонних не мог увидеть длину вводимой последовательности символов.
Заключение
После отправки изменений на «Гитхаб» я открыл оригинальный репозиторий в браузере и проверил получение отправленного коммита. Всё получилось так, как я и планировал. Вот ссылка на коммит с переименованием сразу 157 файлов в оригинальном репозитории.