Search code examples
bashgitwindows-server-2016windows-task-scheduler

Git Portable 64 Bash not working in Windows Server 2016 Task Scheduler


I need help trying to figure out why Git repository commands are not not executing when run in a script in Windows Server 2016 Task scheduler. All works OK when I execute them in a command console.

In the Windows Server 2016 Task Scheduler, my Action "Start a Program" is: C:\Apps\repo.scripts\UpdateMyRepo.bat

The UpdateMyRepo.bat cmd code is:

SET HOME=C:\Users\Repo
REM change to MyRepo git working repository
C:
cd \MyRepo
REM execute my script bash script to update my repository
C:\Apps\Git\bin\bash.exe --login -i -c "/c/Apps/repo.scripts/UpdateMyRepo.sh"

The UpdateMyRepo.sh bash code is

#!/c/Apps/Git/bin/bash.exe -x
export HOME=/c/Users/Repo
cd /c/MyRepo
# write a log entry so we know we are in the repository folder
ls -al > /c/Apps/repo.scripts/myrepofolder.log
# write the git --version to a log file so we know git is working
/c/Apps/Git/bin/git.exe --version > /c/Apps/repo.scripts/version.log
# write the git status to a log file so we know git repository commands work
/c/Apps/Git/bin/git.exe status > /c/Apps/repo.scripts/status.log
# write a done log entry and quit the bash shell
echo done > /c/Apps/repo.scripts/done.log
exit

Everything works in Windows 2016 Task Scheduler except the git status command. The git status writes an empty blank status.log file. Actually, it seems like any other commands, like git add, git commit, git push, etc., that act on the repository yield blank output.

If I execute the command manually when logged in as the Repo user and double clicking on the C:\Apps\repo.scripts\UpdateMyRepo.bat in Windows file explorer or running in a console, all works perfectly and the repository git status is written to the status.log. I get the "null" results when executing the task from the Task Scheduler either manually or on trigger.

Please help me figure out how to run git repository commands in Windows Server 2016 task scheduler. I have already tried too many variations of commands, scripts, and permissions to list each that did not work here.

Platform Details: Windows Server 2016 Standard, all current updates Git Portable 64bit, 2.17.1.windows.2 Repository files are stored on in the operating system and task scheduler's local hard drive, not in a network share

When I run the Git repository tasks in the WS2016 Task Scheduler and figured out how to log some of the output, I get the following error:

fatal: this operation must be run in a work tree

The repository folder is NOT a "bare" repository. So I am suspecting that the WS2016 Task Scheduler is applying additional permission constraints that do not apply to the user account assigned in the task. I get this same error if I try to run the tasks in an Admin Console instead of a normal user console.


Solution

  • First, most Git commands writes their output to stderr, not stdout

    So you need to redirect stderr to stdout, using for instance &> instead of >.


    As noted by Charles Duffy in the comments:

    More accurate to say most git commands don't have output.
    Those that do write it to stdout; stderr is correctly/properly where things that are diagnostic or informational logs as opposed to being output go.

    That reminds me of a recent (2023) discussion over git fetch output:

    Introduce a new machine-parseable "porcelain" output format ...

    With these assumptions, the output format becomes unambiguously parsable.

    Furthermore, given that this output is designed to be consumed by scripts, the machine-readable data is printed to stdout instead of stderr like the human-readable output is.

    This is mostly done so that other data printed to stderr, like error messages or progress meters, don't interfere with the parseable data.


    Second, to be sure all your Git command will be executed in the right working tree/repo, you can add environment variables for the repository location

    export GIT_WORK_TREE=/c/path/to/my/repo
    export GIT_DIR=/c/path/to/my/repo/.git