diff --git a/garden-service/src/vcs/git.ts b/garden-service/src/vcs/git.ts index 5b74b22f75..1fb0ddb7e1 100644 --- a/garden-service/src/vcs/git.ts +++ b/garden-service/src/vcs/git.ts @@ -126,7 +126,12 @@ export class GitHandler extends VcsHandler { // If we can't compute the hash, i.e. the file is gone, we filter it out below let hash = "" try { - hash = await this.hashObject(resolvedPath) || "" + // "git ls-files" returns a symlink even if it points to a directory. + // We filter symlinked directories out, since hashObject() will fail to + // process them. + if (!(await stat(resolvedPath)).isDirectory()) { + hash = await this.hashObject(resolvedPath) || "" + } } catch (err) { // 128 = File no longer exists if (err.code !== 128 && err.code !== "ENOENT") { diff --git a/garden-service/test/unit/src/vcs/git.ts b/garden-service/test/unit/src/vcs/git.ts index 61ea4d5c2f..5adf59529b 100644 --- a/garden-service/test/unit/src/vcs/git.ts +++ b/garden-service/test/unit/src/vcs/git.ts @@ -1,6 +1,6 @@ import { expect } from "chai" import * as tmp from "tmp-promise" -import { createFile, writeFile, realpath, mkdir, remove } from "fs-extra" +import { createFile, writeFile, realpath, mkdir, remove, symlink } from "fs-extra" import { join, resolve } from "path" import { expectError } from "../../../helpers" @@ -231,6 +231,21 @@ describe("GitHandler", () => { expect(files).to.eql([]) }) + + it("should exclude an untracked symlink to a directory", async () => { + const tmpDir2 = await tmp.dir({ unsafeCleanup: true }) + const tmpPathB = await realpath(tmpDir2.path) + + const name = "a-symlink-to-a-directory" + const path = resolve(tmpPath, name) + + await symlink(tmpPathB, path) + + const files = (await handler.getFiles(tmpPath, undefined, [])) + .filter(f => !f.path.includes(ignoreFileName)) + + expect(files).to.eql([]) + }) }) describe("hashObject", () => {