Repository: atlassian/changesets (ts)

Issue:
Monorepo itself appears as changed package instead of package
## Affected Packages

@changesets/cli

## Problem
If src/monorepo/pgk/index.js was changed, src/monorepo also satisfies isSubdir check. 

## Proposed solution
Search for longest subdir. I'm going to provide pull request asap


Pull request:
Use longest path to determine package
I've added packages/package.json to fixture to simulate issue I'm having on own repository. After that a lot of tests started to fail. Fix in git/index.ts fixed all that tests. I assume there is no need to add some specific tests to that case since other ones cover this functionality
close #351

Patch:
diff --git a/.changeset/green-buttons-switch.md b/.changeset/green-buttons-switch.md
new file mode 100644
index 0000000..e7dbcd4
--- /dev/null
+++ b/.changeset/green-buttons-switch.md
@@ -0,0 +1,5 @@
+---
+"@changesets/git": patch
+---
+
+Previously packages nested inside of other packages would show both the nested package and the outer package as changed. Now, only the nested package will show as changed.
diff --git a/__fixtures__/with-git/package.json b/__fixtures__/with-git/package.json
index 2e742d8..1ce4de0 100644
--- a/__fixtures__/with-git/package.json
+++ b/__fixtures__/with-git/package.json
@@ -5,6 +5,7 @@
   "version": "1.0.0",
   "bolt": {
     "workspaces": [
+      "packages",
       "packages/*"
     ]
   }
diff --git a/__fixtures__/with-git/packages/package.json b/__fixtures__/with-git/packages/package.json
new file mode 100644
index 0000000..d67d546
--- /dev/null
+++ b/__fixtures__/with-git/packages/package.json
@@ -0,0 +1,4 @@
+{
+  "name": "packages",
+  "version": "1.0.0"
+}
diff --git a/packages/git/src/index.ts b/packages/git/src/index.ts
index 5aa1285..da8c5f9 100644
--- a/packages/git/src/index.ts
+++ b/packages/git/src/index.ts
@@ -1,9 +1,11 @@
 import spawn from "spawndamnit";
 import path from "path";
-import { getPackages } from "@manypkg/get-packages";
+import { getPackages, Package } from "@manypkg/get-packages";
 import { GitError } from "@changesets/errors";
 import isSubdir from "is-subdir";
 
+const isInDir = (dir: string) => (subdir: string) => isSubdir(dir, subdir);
+
 async function add(pathToFile: string, cwd: string) {
   const gitCmd = await spawn("git", ["add", pathToFile], { cwd });
 
@@ -108,17 +110,17 @@ async function getChangedPackagesSinceRef({
   const changedFiles = await getChangedFilesSince({ ref, cwd, fullPath: true });
   let packages = await getPackages(cwd);
 
-  const fileNameToPackage = (fileName: string) =>
-    packages.packages.find(pkg => isSubdir(pkg.dir, fileName))!;
+  const fileToPackage: Record<string, Package> = {};
 
-  const fileExistsInPackage = (fileName: string) =>
-    !!fileNameToPackage(fileName);
+  packages.packages.forEach(pkg =>
+    changedFiles.filter(isInDir(pkg.dir)).forEach(fileName => {
+      const prevPkg = fileToPackage[fileName] || { dir: "" };
+      if (pkg.dir.length > prevPkg.dir.length) fileToPackage[fileName] = pkg;
+    })
+  );
 
   return (
-    changedFiles
-      // ignore deleted files
-      .filter(fileExistsInPackage)
-      .map(fileNameToPackage)
+    Object.values(fileToPackage)
       // filter, so that we have only unique packages
       .filter((pkg, idx, packages) => packages.indexOf(pkg) === idx)
   );


Test patch:
diff --git a/packages/git/src/index.test.ts b/packages/git/src/index.test.ts
index bbcf100..25752de 100644
--- a/packages/git/src/index.test.ts
+++ b/packages/git/src/index.test.ts
@@ -115,11 +115,13 @@ describe("git", () => {
         .split("\n")
         .filter(a => a);
 
-      expect(stagedFiles).toHaveLength(4);
-      expect(stagedFiles[0]).toEqual("packages/pkg-a/index.js");
-      expect(stagedFiles[1]).toEqual("packages/pkg-a/package.json");
-      expect(stagedFiles[2]).toEqual("packages/pkg-b/index.js");
-      expect(stagedFiles[3]).toEqual("packages/pkg-b/package.json");
+      expect(stagedFiles).toEqual([
+        "packages/package.json",
+        "packages/pkg-a/index.js",
+        "packages/pkg-a/package.json",
+        "packages/pkg-b/index.js",
+        "packages/pkg-b/package.json"
+      ]);
     });
   });