batch-filegit-bashgit-worktree

How can I find the windows drive letter substitutions used for all my git worktrees with a single command?


I have a batch file I use to maintain drive letters for local paths. As these are volatile I have them saved to a txt file that gets read when I boot up my machine. This lets me have local "mapped" drives. The saved text output from 'subst'. Local_Map.txt:

F:\: => C:\tools\dev\Tools
M:\: => C:\tools\dev\Tools_Master_Worktree
W:\: => C:\tools\dev\Tools_ALT_Worktree
X:\: => C:\tools\dev\Tools_Xtra_Worktree

I have found myself required to bounce from one git branch to another so often that I have a workflow of using several worktrees. I use bash and it is super convenient to only type "cd /m" and switch to the branch I have on the worktree that lives at the alias "m". My problem is that I forget which branch I have checkout out on which alias. Its easy to see when I switch to the alias because the name of the branch is shown in the bash prompt. MINGW64 /m (myBranch_1.2.3) $ I end up having to switch to each alias until I find the worktree that has the branch I want. If I use git worktree list, it shows me the branch checkout on each worktree but it doesn't know the subst drive letter I have assigned to that path. git worktree list:

C:/tools/dev/Tools                  a1a2abdf4 [reviewBranch_1.2.3]
C:/tools/dev/Tools_ALT_Worktree     1ace7f077 [myBranch_in-work]
C:/tools/dev/Tools_Master_Worktree  19a1277ba [myBranch_1.2.3]
C:/tools/dev/Tools_Xtra_Worktree    ddd960a7d [myAltBranch]

If I type "subst" in the bash prompt it shows me all the alias drives and the paths but no git branch information. I think I need to write a bash script or batch file that I can then access from anywhere that will equate the git worktree list output to the subst output and show me my aliased drive to worktree branches. Some form of this output would be perfect if I could have it.

F:\ [reviewBranch_1.2.3]
M:\ [myBranch_in-work]
W:\ [myBranch_1.2.3]
X:\ [myAltBranch]

Does anyone have advice on the most simple way to accomplish this?

This is the batch that runs at startup and reads the saved txt.

 for /F "tokens=1,2,*" %%i in (C:\Batch_Files\Local_Map.txt) do (
   if exist %%~di subst %%~di /D 
   subst %%~di %%k
   )

This is my local "mapped" drive interface batch.

@echo off
wmic logicaldisk get Name, VolumeName
REM Path_Map_Boot_Up.bat runs at startup to load subst's from txt file

REM for /F "tokens=1,2,*" %%i in (C:\Batch_Files\Local_Map.txt) do (
REM     if exist %%~di subst %%~di /D 
REM     subst %%~di %%k
REM     )

echo.

 subst

echo.

set /p new= Map Drive(m) Delete Map(d) Refresh(r) Quit(q):

CALL :%new% 
  CLS 
  %0 

:m
  set /p drive=Enter Drive Letter:
  if exist %drive%: subst %drive%: /D 
  set /p mp= Set map path:
  subst %drive%: %mp%

    subst >"C:\Batch_Files\Local_Map.txt"

  EXIT /B
:d
  set /p drive=Enter Drive Letter:
 REM if exist %drive%: subst %drive%: /D
  subst %drive%: /D
  subst >"C:\Batch_Files\Local_Map.txt"
  EXIT /B
:q
  EXIT

Solution

  • There can be used the following Windows batch file processed by the Windows Command Processor cmd.exe if no directory path contains ever a space character.

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    for /F "tokens=1,3" %%G in ('git.exe worktree list') do ( 
        set "BranchDirectory=%%G"
        set "BranchName=%%H"
        for /F "tokens=1* delims=:=>\ " %%I in ('subst') do (
            set "DriveDirectory=%%J"
            setlocal EnableDelayedExpansion
            if /I "!BranchDirectory!" == "!DriveDirectory:\=/!" echo %%I:\ !BranchName! !DriveDirectory!
            endlocal
        )
    )   
    endlocal
    

    There could be used even a single line batch file if no directory path contains a space character:

    @for /F "tokens=1,3" %%G in ('git.exe worktree list') do @for %%K in ("%%G") do @for /F "tokens=1* delims=:=>\ " %%I in ('subst') do @if /I "%%~fK" == "%%J" echo %%I:\ %%H %%J
    

    Another batch file solution running subst only once would be:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    set "Drives=" & (for /F "tokens=1* delims=:=>\ " %%I in ('subst') do set "DirectoryPath=%%J" & set "DriveLetter=%%I" & call :AppendDrive) & goto ProcessList
    :AppendDrive
    set Drives=%Drives% "%DriveLetter%|%DirectoryPath%"& goto :EOF
    :ProcessList
    if defined Drives for /F "tokens=1,3" %%G in ('git.exe worktree list') do for %%K in ("%%G") do for %%L in (%Drives%) do for /F "tokens=1,2 delims=|" %%I in (%%L) do if /I "%%~fK" == "%%J" echo %%I:\ %%H %%J
    endlocal
    

    'subst' can be replaced in all three batch files by C:\Batch_Files\Local_Map.txt for reading the list of directory paths associated with a drive letter with command subst from the text file instead of the output of the command subst executed by cmd.exe processing the batch file by running in the background:

    %ComSpec% /c subst
    

    The delayed expanded environment variable reference !DriveDirectory! in the first batch file respectively the loop variable reference %%J in the second and the third batch file can be removed from the end of the echo command on just drive letter with colon and backslash and the branch name is of interest and no directory path.

    To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

    Read single line with multiple commands using Windows batch file for an explanation of the unconditional command operator & used in the third batch file to reduce the number of command lines in the batch file to process by the Windows Command Processor.