renaming multiple files in a repository

I have created on web service “GitHub” (hereinafter I will call it “GitHub” so that I can incline) a repository into which I gradually uploaded files through the web interface, both one by one and in groups. At the moment, this repository stores about one and a half hundred files in different folders, including nesting folders of different depths. The files have different extensions.

I needed to rename 157 files at once in the described repository according to the following principle:

00-00_имя-файла.ext   # было
00-000_имя-файла.ext  # стало, добавился '0'

This block of code shows templates. Instead of .ext there may be different extensions (in my case, these are extensions .cpp And .h). Instead of имя-файла there may be different names of several words, these names can be of different lengths. Instead of 00-00 there may be, for example, the following character sequences: 00-01, 00-02…, 01-00, 01-01…, 02-00, 02-01, 02-02 and so on. That is, I needed to expand the second number that comes after the hyphen from two digits to three, so I need to rename all files by adding the symbol 0 to the above location in the file name.

I know how you can rename files one by one through the Github web interface, you can read about this in separate article the Github documentation, but it does not describe how to rename many project files at once. I didn’t manage to do it quickly, in one operation, so I broke the task into several simpler points.

Action plan

  1. Clone the repository (create a copy) on your computer;

  2. Write a script to rename multiple project files and rename them;

  3. Create a commit with all renames;

  4. Push changes to the original GitHub repository.

1. Clone the repository on your computer

I work on the Windows 10 operating system and use the program (version control system) “Git for Windows‘ from the command line. As a shell program I use “PowerShell” version 7. As a “terminal emulator” program I use “Windows Terminal“.

Cloning (creating a copy) of the repository from Github to my computer (sometimes I will shorten the path to the current location with an ellipsis ...so that the command fits into the article format):

PS C:\...\repos> git clone https://github.com/ilyachalov/learncpp-com-examples

team git clone we just pass the URL of the repository on Github. Authorization is not required. As far as I understand, this is because this is my repository public. As a result of this command, a folder “learncpp-com-examples” with repository files was created in the current location. For further actions, it is more convenient to go to this folder and work from it.

PS C:\Users\Илья\source\repos> cd learncpp-com-examples
PS C:\Users\Илья\source\repos\learncpp-com-examples>

For convenience, I will refer to this location as follows:

PS ..\learncpp-com-examples>

2. Script for renaming files and its application

For the basis of the script, I took the code from example 4 articles about the cmdletRename-Item» documentation of the “PowerShell” wrapper program. I rewrote that code for my needs, added regular expressions and got the following:

file “rename-files.ps1” (in UTF-8 encoding without BOM, CRLF line endings)

Get-ChildItem -File -Recurse |
    Rename-Item -NewName {
        $_.Name -replace '^(\d\d)-(\d\d)_(.*)', '$1-0$2_$3'
    }

This script only looks at files (folders are discarded, this is ensured by the parameter -File cmdlet “Get-ChildItem”), starting from the current folder and moving deeper into subfolders (this is provided by the parameter -Recurse cmdlet “Get-ChildItem”). The “Get-ChildItem” cmdlet selects all files, so the parameter -Path the “Get-ChildItem” cmdlet is not required, it is omitted. Files selected by the Get-ChildItem cmdlet are piped | cmdlet “Rename-Item”, which performs the renaming.

I wrote another version of this script that does the same thing, but also prints messages to the console window during its execution, informing about the progress of the renames. At the end of the work, it issues a message to the console window with information about the number of files viewed, as well as how many of the viewed files were renamed:

file “rename-files.ps1” (in UTF-8 encoding without BOM, CRLF line endings)

$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"

I have more detailed analysis this script.

To rename the files, I placed the file “rename-files.ps1” with the script in the desired folder of the cloned repository and ran it:

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

After the renaming is completed, the file “rename-files.ps1” of the script should be deleted from the project folder so that it does not interfere with the creation of the commit.

3.1. Checking Git repository settings

Before creating a commit that will later go to Github, it makes sense to check the setting of the name of the author of the commit and the email address of the author of the commit, if you do not want to “shine” them on the Internet.

To check the settings of the Git repository, it is convenient to use the following command from the project folder (thanks to the parameter --show-origin you will be able to see in which files the Git repository settings are stored; often different settings are stored in different files):

PS ..\learncpp-com-examples> git config --list --show-origin

To view only the two settings I’m interested in (name of the commit author, his email address), you can use the following two commands:

PS ..\learncpp-com-examples> git config user.name
Ilya Chalov
PS ..\learncpp-com-examples> git config user.email
почта@домен.ru

I have such a name and it is registered on Github, but I would not want to “shine” the email address there. Github, at the request of the user, creates a “service” email address for commits performed through the web interface, which “covers” the user’s real email address.

This “service” email address can be viewed in the settings of your GitHub account (“Settings / Emails” menu, if you enter through your avatar in the upper right corner of the web service pages) at the following URL (it will work if you are already authorized on the web service):

Меню «Settings / Emails» (если заходить через свою аватарку)
https://github.com/settings/emails

I change the email address in the settings of the current one (parameter --local) Git repository:

PS ..\learncpp-com-examples> git config --local user.email служебный@github.com

3.2. Creating a commit with all renames

team git mv I couldn’t use it for renaming, because it seems that you can’t use regular expressions in it (you can use wildcards, but they are not enough). However, as write in a famous book about “Git”, actually the command git mv is a combination of three commands: 1) renaming a file using the operating system or using other programs, 2) git rm for file with name before renaming, 3) git add for the file with the name after renaming.

Point one of the three above, I have already completed earlier using my script “rename-files.ps1”. The remaining two steps can be done for all 157 renamed files with one command:

PS ..\learncpp-com-examples> git add --all

Now all the changes are placed in the index and you can finally create a commit:

PS ..\learncpp-com-examples> git commit -m "Переименование группы файлов (157 штук)"

4. Sending changes to the original repository on Github

Authorization is required when submitting changes to the original Github repository. When I tried to enter my password, Github told me that as of August 13, 2021, password authentication is no longer used. I was prompted to go into the documentation for following link and read about the valid methods of authentication.

I chose the authentication method using an access token and created granulated access token (now on Github there are two valid implementations of access tokens: the old (classic) and the new (granular access tokens, in English “fine-grained access token”)). I have a separate detailed article about creating a granular access token. Using an access token is easy: when authenticating, you just need to enter it (paste from the clipboard) instead of a password.

I send the changes to the original repository on GitHub:

PS C:\Users\Илья\source\repos\learncpp-com-examples> git push origin main
Username for 'https://github.com': ilyachalov
Password for 'https://ilyachalov@github.com':

When entering a password (in my case, an access token), the input is not reflected in the console window, but in reality it occurs. This approach is probably taken for security reasons so that no outsider can see the length of the input character sequence.

Conclusion

After pushing the changes to Github, I opened the original repository in a browser and checked to see if the commit was received. Everything worked out just as I planned. Here is the link to the commit renaming 157 files at once in the original repository.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *