steveukx/git-js

.env fails if not directory-owner

pragma-git opened this issue · 2 comments

I have issues doing some git commands that requires using simpleGit().env('myvar','value'), if I am not the owner of the folder. This is tested under linux.

My real world example that fails:
await simpleGit( '/mnt/Data/Projects/PETALGORITHMS/Code Master' ).env('GIT_NOTES_REF', "refs/notes/branchname").log()

My real world workaround :
process.env.GIT_NOTES_REF = "refs/notes/branchname"
await simpleGit( '/mnt/Data/Projects/PETALGORITHMS/Code Master' ).log()

--> Simplest example that fails: <--
await simpleGit( '/mnt/Data/Projects/PETALGORITHMS/Code Master' ).env('ABC', "hej").log()

whereas removing the .env-code works as a charm :
await simpleGit( '/mnt/Data/Projects/PETALGORITHMS/Code Master' ).log()

BUT :

  • All this works great using the terminal both when owning and not owning the directory. This by exporting the ENV-variable manually, and then running the git-command. This should be equivalent to what I try to do using the .env-command in simple-git
  • If I change the directory-owner to myself -> all works great using the troublesome simple-git commands. So simple-git .env-command seems to be sensitive to the directory owner (where git isn't in the terminal)

I believe getting "--> Simplest example that fails: <--" above to work would be enough to resolve this issue also for the real-world case. I am happy to validate this if it would be helpful.

I do use the .env feature in multiple places, so it would be great if I don't have to use workarounds

I've been testing against this with Docker and have found two issues that look like they apply here:

  1. Git blocks almost all uses of a repo that crossed user ownership, but that can be overcome by globally configuring the repo as trusted (ie: git config --global --add safe.directory ${baseDIr})
  2. When setting just one environment variable, you are no longer inheriting environment variables from the node process unless you use them first (ie: git.env(process.env).env('ABC', 'hej')).

This example explicitly trusts the repo globally and allows the override of a single environment variable at runtime:

import { resolve as resolvePath }  from 'node:path';
import { simpleGit } from 'simple-git';
import { promiseResult } from '@kwsites/promise-result';

const baseDir = resolvePath(process.cwd(), 'repo');

// set the child process environment explicitly to be the node process environment
const git = simpleGit({ baseDir }).env(process.env);

// explicitly trust the repo
await git.addConfig(
    'safe.directory', baseDir, true, 'global'
);

// use the single property version of `.env(a, b)` to override just that property
const {result, success} = await promiseResult(
    git.env('ABC', "hej").log()
);

console.log(`Success: ${ success }`);
console.log(result);

An alternative is to spread in an environment variable object that copies in the node process environment (useful for if you write to the process.env through the lifespan of your application):

const {result, success} = await promiseResult(
    git.env({ ...process.env, 'ABC': "hej" }).log()
);

I think you may find that it's just the .env step that's causing you a problem - I'll look at making a plugin to optionally include the node process's environment with local overrides which would simplify your calling code.

This issue has been automatically closed due to a lack of response. If your problem persists please open a new issue including any additional detail requested from this issue. For more detail on the issues/pull requests see ISSUES_AND_PULL_REQUESTS