Functions/Rename-HgItem.ps1
function Rename-HgItem { <# .SYNOPSIS Renames a file/directory in Mercurial. .DESCRIPTION This does not move the item. It changes its name only. Properly handles changing the case of that item. Mercurial is case-sensitive. Windows is not. There may be times when you need to change just the case of a file or directory. This function takes the path to a file or directory, and a new name for the item, and renames the items so it has the expected case. This is a two-step operation, so requires two commits. Only the renamed files/directories are committed. This means if you're renaming a directory, and you have uncommitted changes under that directory, they may get committed. It's always best to have a clean repository. ALIASES rnhgi, hgrename .EXAMPLE Rename-HgItem -Path .\Test\Test-ConvertHgItemCase.ps1 -NewName Test-RenameHgItem.ps1 Renames the file at .\Test\Test-ConvertHgItemCase.ps1 to Test-RenameHgItem.ps1. .EXAMPLE Rename-HgItem -Path WebSite -NewName Website Renames the WebSite directory to Website. .EXAMPLE Rename-HgItem -Path src\Code.cs -NewName code.cs Renames the src\Code.cs file to src\code.cs. Note that NewName does NOT have a directory component. #> [CmdletBinding()] param( [Parameter(Mandatory=$true,Position=0)] [string] # The path to the item whose case should change. $Path, [Parameter(Mandatory=$true,Position=1)] [string] # The item's new name. Must not have a directory component. Should just be the new name. $NewName ) if( (Split-Path -Parent $NewName) -ne '' ) { Write-Error "'$NewName' should be a filename, not a path." return } $currentName = Split-Path -Leaf $Path if( $currentName -ceq $NewName ) { Write-Error "'$Path' is already named '$NewName'." return } $isDir = (Test-Path $Path -PathType Container) $isFile = (Test-Path $Path -PathType Leaf) if( -not $isDir -and -not $isFile ) { Write-Error "'$Path' not found." return } $repoRoot = Resolve-HgRoot -Path $Path if( -not $repoRoot ) { return } # Really re-naming something. Versions of Mercurial greater than 2.1.1 added support for case-only renames if( $currentName -ne $NewName -or ((Get-HgVersion) -gt ([Version]'2.1.1')) ) { $oldPath = Resolve-HgPath -Path $Path $newPathParent = Split-Path -Parent $oldPath if( $newPathParent ) { $newPath = Join-Path $newPathParent $NewName } else { $newPath = $NewName } Push-Location $repoRoot try { if( $isDir ) { $destinationDir = Join-Path $repoRoot $newPath if( -not (Test-Path $destinationDir) ) { New-Item $destinationDir -ItemType Directory } if( $currentName -eq $NewName -and $currentName -cne $NewName ) { $tempSuffix = [IO.Path]::GetRandomFileName() $tempName = '{0}.{1}' -f $newPath,$tempSuffix hg rename $oldPath $tempName if( (Test-Path -Path $oldPath -PathType Container) ) { Get-ChildItem $oldPath * | Move-Item -Destination $tempName Remove-Item $oldPath } hg rename $tempName $newPath if( (Test-Path -Path $tempName -PathType Container) ) { Get-ChildItem $tempName * | Move-Item -Destination $newPath Remove-Item $tempName } } else { hg rename "$oldPath\*" $newPath } } else { hg rename $oldPath $newPath } Write-Host "Renamed $oldPath -> $newPath. Don't forget to commit." return } finally { Pop-Location } } # Changing the case. if( $isDir ) { $dirRoot = Split-Path -Parent $Path $pathForCommit = $Path $Path = "$Path\*" $tempPath = "$NewName.casefix" $newPath = $NewName if( $dirRoot ) { $tempPath = Join-Path $dirRoot $tempPath $newPath = Join-Path $dirRoot $NewPath } if( -not (Test-Path $tempPath -PathType Container) ) { New-Item $tempPath -ItemType Directory } } elseif( $isFile ) { $fileRoot = Split-Path -Parent $Path $tempPath = "$newName.casefix" $newPath = $NewName if( $fileRoot ) { $tempPath = Join-Path $fileRoot "$newName.casefix" $newPath = Join-Path $fileRoot $newName } $pathForCommit = $Path } Write-Host "Renaming $Path -> $tempPath" hg rename $Path $tempPath if( $LastExitCode ) { return } hg commit -m "Renaming $pathForCommit -> $tempPath." $pathForCommit $tempPath if( $LastExitCode ) { return } Write-Host "Renaming $tempPath -> $newPath" hg rename $tempPath $newPath if( $LastExitCode ) { return } hg commit -m "Renaming $tempPath -> $newPath." $tempPath $newPath if( $LastExitCode ) { return } } Set-Alias -Name 'hgrename' -Value 'Rename-HgItem' Set-Alias -Name 'rnhgi' -Value 'Rename-HgItem' |