From 3cbd577120a9da6e51bb8b13534d1bf71ea5712c Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 1 Jul 2019 17:46:25 -0700 Subject: [PATCH] fix(git): strip GIT environs when running git When running an npm command from within a git environment, such as installing or testing during a git rebase or bisect, these environment variables will be passed to the child process, causing it to fetch/checkout/etc in the root project instead of doing what the user intends. Strip them out so that they are not passed to the child process. Also, remove git environs from the test environment, so that spawning git in a test to set up a dummy repo doesn't mess with the main project's git repository. This enables adding `exec npm test` in a `git rebase -i` list to run tests between commits. --- lib/utils/git.js | 10 ++++++++++ test/common-tap.js | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/lib/utils/git.js b/lib/utils/git.js index 6770853dd9622..1951640e81568 100644 --- a/lib/utils/git.js +++ b/lib/utils/git.js @@ -28,6 +28,16 @@ function execGit (args, options, cb) { function spawnGit (args, options) { log.info('git', args) + // If we're already in a git command (eg, running test as an exec + // line in an interactive rebase) then these environment variables + // will force git to operate on the current project, instead of + // checking out/fetching/etc. whatever the user actually intends. + options.env = options.env || Object.keys(process.env) + .filter(k => !/^GIT/.test(k)) + .reduce((set, k) => { + set[k] = process.env[k] + return set + }, {}) return spawn(git, prefixGitArgs().concat(args || []), options) } diff --git a/test/common-tap.js b/test/common-tap.js index d54a869995451..e15d5dab2487d 100644 --- a/test/common-tap.js +++ b/test/common-tap.js @@ -7,6 +7,12 @@ var readCmdShim = require('read-cmd-shim') var isWindows = require('../lib/utils/is-windows.js') var Bluebird = require('bluebird') +// remove any git envs so that we don't mess with the main repo +// when running git subprocesses in tests +Object.keys(process.env).filter(k => /^GIT/.test(k)).forEach( + k => delete process.env[k] +) + // cheesy hackaround for test deps (read: nock) that rely on setImmediate if (!global.setImmediate || !require('timers').setImmediate) { require('timers').setImmediate = global.setImmediate = function () {