├── .github ├── dependabot.yml └── workflows │ └── test-and-release.yml ├── .gitignore ├── CHANGELOG.md ├── README.md ├── branch-diff.js ├── package.json └── snap └── snapcraft.yaml /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'github-actions' 4 | directory: '/' 5 | schedule: 6 | interval: 'daily' 7 | commit-message: 8 | prefix: 'chore' 9 | include: 'scope' 10 | - package-ecosystem: 'npm' 11 | directory: '/' 12 | schedule: 13 | interval: 'daily' 14 | commit-message: 15 | prefix: 'chore' 16 | include: 'scope' 17 | -------------------------------------------------------------------------------- /.github/workflows/test-and-release.yml: -------------------------------------------------------------------------------- 1 | name: Test & Maybe Release 2 | on: [push, pull_request] 3 | jobs: 4 | test: 5 | strategy: 6 | fail-fast: false 7 | matrix: 8 | node: [18.x, 20.x, lts/*, current] 9 | os: [macos-latest, ubuntu-latest, windows-latest] 10 | runs-on: ${{ matrix.os }} 11 | steps: 12 | - name: Checkout Repository 13 | uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | - name: Use Node.js ${{ matrix.node }} 17 | uses: actions/setup-node@v4.4.0 18 | with: 19 | node-version: ${{ matrix.node }} 20 | - name: Install Dependencies 21 | run: | 22 | npm install --no-progress 23 | - name: Run tests 24 | run: | 25 | npm config set script-shell bash 26 | npm run test:ci 27 | release: 28 | name: Release 29 | needs: test 30 | runs-on: ubuntu-latest 31 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 32 | steps: 33 | - name: Checkout 34 | uses: actions/checkout@v4 35 | with: 36 | fetch-depth: 0 37 | - name: Setup Node.js 38 | uses: actions/setup-node@v4.4.0 39 | with: 40 | node-version: lts/* 41 | - name: Install dependencies 42 | run: | 43 | npm install --no-progress --no-package-lock --no-save 44 | - name: Build 45 | run: | 46 | npm run build 47 | - name: Install plugins 48 | run: | 49 | npm install \ 50 | @semantic-release/commit-analyzer \ 51 | conventional-changelog-conventionalcommits \ 52 | @semantic-release/release-notes-generator \ 53 | @semantic-release/npm \ 54 | @semantic-release/github \ 55 | @semantic-release/git \ 56 | @semantic-release/changelog \ 57 | --no-progress --no-package-lock --no-save 58 | - name: Release 59 | env: 60 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 61 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 62 | run: npx semantic-release 63 | 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [3.1.1](https://github.com/nodejs/branch-diff/compare/v3.1.0...v3.1.1) (2024-07-19) 2 | 3 | ### Bug Fixes 4 | 5 | * add commit.prurl check ([#72](https://github.com/nodejs/branch-diff/issues/72)) ([1ceae1a](https://github.com/nodejs/branch-diff/commit/1ceae1abbf038a25de4609d15460fc413c627809)) 6 | 7 | ## [3.1.0](https://github.com/nodejs/branch-diff/compare/v3.0.5...v3.1.0) (2024-07-16) 8 | 9 | ### Features 10 | 11 | * support PR-URL with trailing slash ([#70](https://github.com/nodejs/branch-diff/issues/70)) ([a0d1846](https://github.com/nodejs/branch-diff/commit/a0d18469ed69fe0d55a0742901e697faf430e353)) 12 | 13 | ## [3.0.5](https://github.com/nodejs/branch-diff/compare/v3.0.4...v3.0.5) (2024-07-10) 14 | 15 | ### Trivial Changes 16 | 17 | * **deps:** bump actions/setup-node from 4.0.2 to 4.0.3 ([adc2e60](https://github.com/nodejs/branch-diff/commit/adc2e600e2acaa95f1950079e86798c20bde08cf)) 18 | * use `pipeline` from `node:stream/promises` ([70062d4](https://github.com/nodejs/branch-diff/commit/70062d421f14f30c1fc0829e1aa4c6cdb3aac838)) 19 | 20 | ## [3.0.4](https://github.com/nodejs/branch-diff/compare/v3.0.3...v3.0.4) (2024-02-07) 21 | 22 | 23 | ### Trivial Changes 24 | 25 | * update repository URL ([#65](https://github.com/nodejs/branch-diff/issues/65)) ([0a3d35d](https://github.com/nodejs/branch-diff/commit/0a3d35d8ae68f57a0d466f212aa23d20a77f8e8d)) 26 | 27 | ## [3.0.3](https://github.com/rvagg/branch-diff/compare/v3.0.2...v3.0.3) (2024-02-07) 28 | 29 | 30 | ### Trivial Changes 31 | 32 | * **deps:** bump actions/setup-node from 4.0.1 to 4.0.2 ([#64](https://github.com/rvagg/branch-diff/issues/64)) ([0a8c56c](https://github.com/rvagg/branch-diff/commit/0a8c56ccd7adfd6774cff2b77309de9447fe4e7c)) 33 | 34 | ## [3.0.2](https://github.com/rvagg/branch-diff/compare/v3.0.1...v3.0.2) (2024-01-01) 35 | 36 | 37 | ### Trivial Changes 38 | 39 | * **deps:** bump actions/setup-node from 4.0.0 to 4.0.1 ([16d2df6](https://github.com/rvagg/branch-diff/commit/16d2df6709b1bcf64664742cafce9a6261e33cbf)) 40 | 41 | ## [3.0.1](https://github.com/rvagg/branch-diff/compare/v3.0.0...v3.0.1) (2023-12-13) 42 | 43 | 44 | ### Tests 45 | 46 | * remove 16.x and add 20.x to CI ([8f3fae2](https://github.com/rvagg/branch-diff/commit/8f3fae2050dc54e99a9c05a3bb57eee3ce4fca64)) 47 | 48 | ## [3.0.0](https://github.com/rvagg/branch-diff/compare/v2.1.5...v3.0.0) (2023-12-13) 49 | 50 | 51 | ### ⚠ BREAKING CHANGES 52 | 53 | * **deps:** bump changelog-maker from 3.2.7 to 4.0.0 (#61) 54 | 55 | ### Trivial Changes 56 | 57 | * **deps:** bump changelog-maker from 3.2.7 to 4.0.0 ([#61](https://github.com/rvagg/branch-diff/issues/61)) ([11b8dab](https://github.com/rvagg/branch-diff/commit/11b8dabd0f77479c48daf126f70b2b8dda94f07f)) 58 | 59 | ## [2.1.5](https://github.com/rvagg/branch-diff/compare/v2.1.4...v2.1.5) (2023-10-25) 60 | 61 | 62 | ### Trivial Changes 63 | 64 | * **deps:** bump actions/checkout from 3 to 4 ([5159aee](https://github.com/rvagg/branch-diff/commit/5159aee62651cea6d11c8ea9d081887bc57984a3)) 65 | * **deps:** bump actions/setup-node from 3.8.1 to 4.0.0 ([7aee4b2](https://github.com/rvagg/branch-diff/commit/7aee4b2dd229067a8d3546b86565919047e6e660)) 66 | 67 | ## [2.1.4](https://github.com/rvagg/branch-diff/compare/v2.1.3...v2.1.4) (2023-08-21) 68 | 69 | 70 | ### Trivial Changes 71 | 72 | * **deps:** bump actions/setup-node from 3.8.0 to 3.8.1 ([650ea95](https://github.com/rvagg/branch-diff/commit/650ea95f817252c703fff6dc90032a8d4d9c8d54)) 73 | 74 | ## [2.1.3](https://github.com/rvagg/branch-diff/compare/v2.1.2...v2.1.3) (2023-08-15) 75 | 76 | 77 | ### Trivial Changes 78 | 79 | * **deps:** bump actions/setup-node from 3.7.0 to 3.8.0 ([465acae](https://github.com/rvagg/branch-diff/commit/465acaed1229ab33e98211754fbbd9ead449f3a0)) 80 | 81 | ## [2.1.2](https://github.com/rvagg/branch-diff/compare/v2.1.1...v2.1.2) (2023-07-07) 82 | 83 | 84 | ### Trivial Changes 85 | 86 | * **deps:** bump actions/setup-node from 3.6.0 to 3.7.0 ([#56](https://github.com/rvagg/branch-diff/issues/56)) ([a0c5385](https://github.com/rvagg/branch-diff/commit/a0c5385b74fe8595f74e25f159e5d4760d01293a)) 87 | 88 | ## [2.1.1](https://github.com/rvagg/branch-diff/compare/v2.1.0...v2.1.1) (2023-04-10) 89 | 90 | 91 | ### Bug Fixes 92 | 93 | * update releaser action ([#54](https://github.com/rvagg/branch-diff/issues/54)) ([31a3687](https://github.com/rvagg/branch-diff/commit/31a3687f609693ae8f7acbe8c4a0810ce3d9f52e)) 94 | 95 | 96 | ### Trivial Changes 97 | 98 | * **deps:** bump commit-stream from 1.1.0 to 2.0.1 ([aaf897f](https://github.com/rvagg/branch-diff/commit/aaf897f797598f7991b4f575108dcd446c8c3c5f)) 99 | 100 | ## [2.1.0](https://github.com/rvagg/branch-diff/compare/v2.0.4...v2.1.0) (2022-09-01) 101 | 102 | 103 | ### Features 104 | 105 | * add --user and --repo options ([#49](https://github.com/rvagg/branch-diff/issues/49)) ([7130ec9](https://github.com/rvagg/branch-diff/commit/7130ec9960faeed0871abee5dd5b03cc14473e47)) 106 | 107 | ### [2.0.4](https://github.com/rvagg/branch-diff/compare/v2.0.3...v2.0.4) (2022-05-05) 108 | 109 | 110 | ### Bug Fixes 111 | 112 | * restore label filtering ([#50](https://github.com/rvagg/branch-diff/issues/50)) ([660a71f](https://github.com/rvagg/branch-diff/commit/660a71ff39d53065c118b5262b1025daadb9641d)) 113 | 114 | 115 | ### Trivial Changes 116 | 117 | * **no-release:** bump standard from 16.0.4 to 17.0.0 ([#52](https://github.com/rvagg/branch-diff/issues/52)) ([a87c38f](https://github.com/rvagg/branch-diff/commit/a87c38f0e2611dc44ef1e73d4df66adbfd5d68a8)) 118 | 119 | ### [2.0.3](https://github.com/rvagg/branch-diff/compare/v2.0.2...v2.0.3) (2022-03-02) 120 | 121 | 122 | ### Trivial Changes 123 | 124 | * **deps:** bump actions/checkout from 2 to 3 ([#48](https://github.com/rvagg/branch-diff/issues/48)) ([000ceab](https://github.com/rvagg/branch-diff/commit/000ceabf9f142dfd34426654107d8cf7a4f3b4ba)) 125 | 126 | ### [2.0.2](https://github.com/rvagg/branch-diff/compare/v2.0.1...v2.0.2) (2022-02-28) 127 | 128 | 129 | ### Bug Fixes 130 | 131 | * require is not defined error ([#47](https://github.com/rvagg/branch-diff/issues/47)) ([be4ec56](https://github.com/rvagg/branch-diff/commit/be4ec5697cccdbfc9e95f602f69fa39015b5d70e)) 132 | 133 | ### [2.0.1](https://github.com/rvagg/branch-diff/compare/v2.0.0...v2.0.1) (2022-02-26) 134 | 135 | 136 | ### Trivial Changes 137 | 138 | * **deps:** bump actions/setup-node from 2 to 3 ([#46](https://github.com/rvagg/branch-diff/issues/46)) ([221ca14](https://github.com/rvagg/branch-diff/commit/221ca146d683711505724f73e115ffa44ffa72d3)) 139 | 140 | ## [2.0.0](https://github.com/rvagg/branch-diff/compare/v1.10.5...v2.0.0) (2022-01-18) 141 | 142 | 143 | ### ⚠ BREAKING CHANGES 144 | 145 | * switch to ESM, dedupe more code w/ changelog-maker 146 | 147 | ### Features 148 | 149 | * switch to ESM, dedupe more code w/ changelog-maker ([df17633](https://github.com/rvagg/branch-diff/commit/df176331c82ad9d27d5325ca29b059e89c7abef3)) 150 | 151 | 152 | ### Trivial Changes 153 | 154 | * remove package-lock.json ([55f0487](https://github.com/rvagg/branch-diff/commit/55f0487b714419375b9a8482a677ead822c5104f)) 155 | 156 | ### [1.10.5](https://github.com/rvagg/branch-diff/compare/v1.10.4...v1.10.5) (2021-11-04) 157 | 158 | 159 | ### Trivial Changes 160 | 161 | * **deps:** bump changelog-maker from 2.7.2 to 2.7.3 ([abd4986](https://github.com/rvagg/branch-diff/commit/abd498623d57fb94fdc173e4763fc2033bc0c275)) 162 | 163 | ### [1.10.4](https://github.com/rvagg/branch-diff/compare/v1.10.3...v1.10.4) (2021-10-25) 164 | 165 | 166 | ### Trivial Changes 167 | 168 | * **deps:** bump changelog-maker from 2.7.1 to 2.7.2 ([766dbb9](https://github.com/rvagg/branch-diff/commit/766dbb9884cdb485d3537fc568df8c07318554d0)) 169 | * **deps:** bump split2 from 4.0.0 to 4.1.0 ([a714f13](https://github.com/rvagg/branch-diff/commit/a714f13e551352ee5cf3d036e3a7853da41d382c)) 170 | 171 | ### [1.10.3](https://github.com/rvagg/branch-diff/compare/v1.10.2...v1.10.3) (2021-10-18) 172 | 173 | 174 | ### Trivial Changes 175 | 176 | * **deps:** bump changelog-maker from 2.7.0 to 2.7.1 ([796e51e](https://github.com/rvagg/branch-diff/commit/796e51e51d38f02b26e5ad1c934d578b345a9db0)) 177 | 178 | ### [1.10.2](https://github.com/rvagg/branch-diff/compare/v1.10.1...v1.10.2) (2021-10-15) 179 | 180 | 181 | ### Trivial Changes 182 | 183 | * **deps:** bump split2 from 3.2.2 to 4.0.0 ([#35](https://github.com/rvagg/branch-diff/issues/35)) ([7281e09](https://github.com/rvagg/branch-diff/commit/7281e09090e6475019e1a5616f8819f5840ec928)) 184 | 185 | ### [1.10.1](https://github.com/rvagg/branch-diff/compare/v1.10.0...v1.10.1) (2021-10-14) 186 | 187 | 188 | ### Bug Fixes 189 | 190 | * remove build step ([302b66c](https://github.com/rvagg/branch-diff/commit/302b66c594aa938236e1fec454ef045da13cd275)) 191 | 192 | 193 | ### Trivial Changes 194 | 195 | * add auto-release workflow ([dd67a3d](https://github.com/rvagg/branch-diff/commit/dd67a3d65d829a99593aebf2abad42ed870267da)) 196 | * add dependabot config ([#30](https://github.com/rvagg/branch-diff/issues/30)) ([66ee30b](https://github.com/rvagg/branch-diff/commit/66ee30bf24b18aee0031b1a9f4352061762f7e36)) 197 | * **deps-dev:** bump standard from 16.0.3 to 16.0.4 ([6202ae5](https://github.com/rvagg/branch-diff/commit/6202ae5b59a8bb3fa24c98d2bfe17f975d8418b2)) 198 | * **deps:** bump changelog-maker from 2.5.0 to 2.6.0 ([e6f0fef](https://github.com/rvagg/branch-diff/commit/e6f0feff5cb3cfc92abf458afd64b915251dc2a6)) 199 | * **deps:** bump changelog-maker from 2.6.0 to 2.7.0 ([781c292](https://github.com/rvagg/branch-diff/commit/781c2929dbf5ec964f17f25c22d450802d061793)) 200 | * update branch references to "main" ([fa0da24](https://github.com/rvagg/branch-diff/commit/fa0da24fe321d7a7744e35e7325ffd6fc7488d2f)) 201 | * update dependencies ([3cd98d8](https://github.com/rvagg/branch-diff/commit/3cd98d8eaa73cd699f12b9bed06b3b57a5fcb744)) 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # branch-diff 2 | 3 | **A tool to list print the commits on one git branch that are not on another using loose comparison** 4 | 5 | [![npm](https://nodei.co/npm/branch-diff.png?downloads=true&downloadRank=true)](https://nodei.co/npm/branch-diff/) 6 | [![npm](https://nodei.co/npm-dl/branch-diff.png?months=6&height=3)](https://nodei.co/npm/branch-diff/) 7 | 8 | ## Usage 9 | 10 | **`$ branch-diff [--sha] [--plaintext] [--markdown] [--group] [--reverse] [--patch-only] base-branch comparison-branch`** 11 | 12 | A commit is considered to be in the comparison-branch but not in the base-branch if: 13 | 14 | * the commit sha is identical, or 15 | * the commit summary is identical _and_ the commit description is identical _and_ a `PR-URL` exists in the metadata and is identical (in the description but split out by commit-stream) 16 | 17 | The output is the same as [changelog-maker](https://github.com/rvagg/changelog-maker/) and you can use `--simple` to simplify it for console output instead of Markdown. 18 | 19 | The commit list is very close to running: 20 | 21 | `$ git log main..next` 22 | 23 | But the comparison isn't quite as strict, generally leading to a shorter list of commits. 24 | 25 | ### Options 26 | 27 | * `--version`: Only prints branch-diff's package.json version. 28 | * `--group` or `-g`: Group commits by prefix, this uses the part of the commit summary that is usually used in Node.js core to indicate subsystem for example. Groups are made up of numbers, letters, `,` and `-`, followed by a `:`. 29 | * `--exclude-label`: Exclude any commits from the list that come from a GitHub pull request with the given label. Multiple `--exclude-label` options may be provided, they will also be split by `,`. e.g. `--exclude-label=semver-major,meta`. 30 | * `--require-label`: Only include commits in the list that come from a GitHub pull request with the given label. Multiple `--require-label` options may be provided, they will also be split by `,`. e.g. `--require-label=test,doc`. 31 | * `--patch-only`: An alias for `--exclude-label=semver-major,semver-minor`. 32 | * `--format`: Dictates what formatting the output will have. Possible options are: `simple`, `markdown`, `plaintext`, and `sha`. The default is to print a `simple` output suitable for stdout. 33 | - `simple`: Don't print full markdown output, good for console printing without the additional fluff. 34 | - `sha`: Print only the 10-character truncated commit hashes. Good for piping though additional tooling, such as `xargs git cherry-pick` for applying commits. 35 | - `plaintext`: A very simple form, without commit details, implies `--group`. 36 | - `markdown`: A Markdown formatted from, with links and proper escaping. 37 | * `--sha`: Same as `--format=sha`. 38 | * `--plaintext`: Same as `--format=plaintext`. 39 | * `--markdown`: Same as `--format=markdown`. 40 | * `--filter-release`: Exclude Node-style release commits from the list. e.g. `Working on v1.0.0` or `2015-10-21 Version 2.0.0`. 41 | * `--reverse`: Reverse the results, this is especially useful when piping output to `xargs`. 42 | * `--commit-url`:A URL template which will be used to generate commit URLs for a repository not hosted in GitHub. `{ref}` is the placeholder that will be replaced with the commit, i.e. `--commit-url=https://gitlab.com/myUser/myRepo/commit/{ref}`. `{ghUser}` and `{ghRepo}` are available if they can be derived from package.json (Gitlab and Bitbucket URLs should be understood in package.json). 43 | * `--user`: Override the auto-detected GitHub user/org derived from package.json 44 | * `--repo`: Override the auto-detected GitHub repository name derived from package.json 45 | 46 | ## License 47 | 48 | **branch-diff** is Copyright (c) 2015 Rod Vagg [@rvagg](https://twitter.com/rvagg) and licenced under the MIT licence. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE.md file for more details. 49 | -------------------------------------------------------------------------------- /branch-diff.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import fs from 'fs' 4 | import { createRequire } from 'module' 5 | import path from 'path' 6 | import process from 'process' 7 | import { pipeline } from 'stream/promises' 8 | import { promisify } from 'util' 9 | import commitStream from 'commit-stream' 10 | import split2 from 'split2' 11 | import pkgtoId from 'pkg-to-id' 12 | import minimist from 'minimist' 13 | import { isReleaseCommit } from 'changelog-maker/groups' 14 | import { processCommits } from 'changelog-maker/process-commits' 15 | import { collectCommitLabels } from 'changelog-maker/collect-commit-labels' 16 | import gitexec from 'gitexec' 17 | 18 | const pkgFile = path.join(process.cwd(), 'package.json') 19 | const require = createRequire(import.meta.url) 20 | const pkgData = fs.existsSync(pkgFile) ? require(pkgFile) : {} 21 | const pkgId = pkgtoId(pkgData) 22 | const refcmd = 'git rev-list --max-count=1 {{ref}}' 23 | const commitdatecmd = '$(git show -s --format=%cd `{{refcmd}}`)' 24 | const gitcmd = 'git log {{startCommit}}..{{branch}} --until="{{untilcmd}}"' 25 | const ghId = { 26 | user: pkgId.user || 'nodejs', 27 | repo: pkgId.name || 'node' 28 | } 29 | 30 | function replace (s, m) { 31 | Object.keys(m).forEach(function (k) { 32 | s = s.replace(new RegExp('\\{\\{' + k + '\\}\\}', 'g'), m[k]) 33 | }) 34 | return s 35 | } 36 | 37 | export async function branchDiff (branch1, branch2, options) { 38 | if (!branch1 || !branch2) { 39 | throw new Error('Must supply two branch names to compare') 40 | } 41 | 42 | const repoPath = options.repoPath || process.cwd() 43 | const commit = await findMergeBase(repoPath, branch1, branch2) 44 | const branchCommits = await Promise.all([branch1, branch2].map(async (branch) => { 45 | return collect(repoPath, branch, commit, branch === branch2 && options.endRef) 46 | })) 47 | return await diffCollected(options, branchCommits) 48 | } 49 | 50 | async function findMergeBase (repoPath, branch1, branch2) { 51 | const gitcmd = `git merge-base ${branch1} ${branch2}` 52 | const data = await promisify(gitexec.execCollect)(repoPath, gitcmd) 53 | return data.substr(0, 10) 54 | } 55 | 56 | function normalizeIfTrailingSlash (commit) { 57 | if (commit.prUrl && commit.prUrl.at(-1) === '/') { 58 | commit.prUrl = commit.prUrl.slice(0, -1) 59 | } 60 | } 61 | 62 | async function diffCollected (options, branchCommits) { 63 | function isInList (commit) { 64 | normalizeIfTrailingSlash(commit) 65 | return branchCommits[0].some((c) => { 66 | if (commit.sha === c.sha) { return true } 67 | if (commit.summary === c.summary) { 68 | normalizeIfTrailingSlash(c) 69 | if (commit.prUrl && c.prUrl) { 70 | return commit.prUrl === c.prUrl 71 | } else if (commit.author.name === c.author.name && 72 | commit.author.email === c.author.email) { 73 | if (process.stderr.isTTY) { 74 | console.error(`Note: Commit fell back to author checking: "${commit.summary}" -`, commit.author) 75 | } 76 | return true 77 | } 78 | } 79 | return false 80 | }) 81 | } 82 | 83 | let list = branchCommits[1].filter((commit) => !isInList(commit)) 84 | 85 | await collectCommitLabels(list) 86 | 87 | if (options.excludeLabels.length > 0) { 88 | list = list.filter((commit) => { 89 | return !commit.labels || !commit.labels.some((label) => { 90 | return options.excludeLabels.indexOf(label) >= 0 91 | }) 92 | }) 93 | } 94 | 95 | if (options.requireLabels.length > 0) { 96 | list = list.filter((commit) => { 97 | return commit.labels && commit.labels.some((label) => { 98 | return options.requireLabels.indexOf(label) >= 0 99 | }) 100 | }) 101 | } 102 | 103 | return list 104 | } 105 | 106 | async function collect (repoPath, branch, startCommit, endRef) { 107 | const endrefcmd = endRef && replace(refcmd, { ref: endRef }) 108 | const untilcmd = endRef ? replace(commitdatecmd, { refcmd: endrefcmd }) : '' 109 | const _gitcmd = replace(gitcmd, { branch, startCommit, untilcmd }) 110 | 111 | const commitList = [] 112 | await pipeline( 113 | gitexec.exec(repoPath, _gitcmd), 114 | split2(), 115 | commitStream(ghId.user, ghId.repo), 116 | async function * (source) { 117 | for await (const commit of source) { 118 | commitList.push(commit) 119 | } 120 | }) 121 | return commitList 122 | } 123 | 124 | async function main () { 125 | const minimistConfig = { 126 | boolean: ['version', 'group', 'patch-only', 'simple', 'filter-release', 'reverse'] 127 | } 128 | const argv = minimist(process.argv.slice(2), minimistConfig) 129 | const branch1 = argv._[0] 130 | const branch2 = argv._[1] 131 | const group = argv.group || argv.g 132 | const endRef = argv['end-ref'] 133 | let excludeLabels = [] 134 | let requireLabels = [] 135 | 136 | if (argv.version || argv.v) { 137 | return console.log(`v ${require('./package.json').version}`) 138 | } 139 | 140 | if (argv['patch-only']) { 141 | excludeLabels = ['semver-minor', 'semver-major'] 142 | } 143 | 144 | if (argv['exclude-label']) { 145 | if (!Array.isArray(argv['exclude-label'])) { 146 | argv['exclude-label'] = argv['exclude-label'].split(',') 147 | } 148 | excludeLabels = excludeLabels.concat(argv['exclude-label']) 149 | } 150 | 151 | if (argv['require-label']) { 152 | if (!Array.isArray(argv['require-label'])) { 153 | argv['require-label'] = argv['require-label'].split(',') 154 | } 155 | requireLabels = requireLabels.concat(argv['require-label']) 156 | } 157 | 158 | if (argv.user) { 159 | ghId.user = argv.user 160 | } 161 | 162 | if (argv.repo) { 163 | ghId.repo = argv.repo 164 | } 165 | 166 | const options = { 167 | group, 168 | excludeLabels, 169 | requireLabels, 170 | endRef 171 | } 172 | 173 | let list = await branchDiff(branch1, branch2, options) 174 | if (argv['filter-release']) { 175 | list = list.filter((commit) => !isReleaseCommit(commit.summary)) 176 | } 177 | 178 | await processCommits(argv, ghId, list) 179 | } 180 | 181 | main().catch((err) => { 182 | console.error(err) 183 | process.exit(1) 184 | }) 185 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "branch-diff", 3 | "version": "3.1.1", 4 | "description": "A tool to list print the commits on one git branch that are not on another using loose comparison", 5 | "main": "branch-diff.js", 6 | "type": "module", 7 | "bin": { 8 | "branch-diff": "./branch-diff.js" 9 | }, 10 | "scripts": { 11 | "lint": "standard", 12 | "format": "standard --fix", 13 | "build": "true", 14 | "test:ci": "npm run test", 15 | "test": "npm run lint" 16 | }, 17 | "author": "Rod (http://r.va.gg/)", 18 | "license": "MIT", 19 | "dependencies": { 20 | "changelog-maker": "^4.0.0", 21 | "commit-stream": "^2.0.1", 22 | "gitexec": "^2.0.1", 23 | "minimist": "^1.2.8", 24 | "pkg-to-id": "^0.0.3", 25 | "split2": "^4.2.0" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "https://github.com/nodejs/branch-diff.git" 30 | }, 31 | "preferGlobal": true, 32 | "devDependencies": { 33 | "standard": "^17.0.0" 34 | }, 35 | "release": { 36 | "branches": [ 37 | "main" 38 | ], 39 | "plugins": [ 40 | [ 41 | "@semantic-release/commit-analyzer", 42 | { 43 | "preset": "conventionalcommits", 44 | "releaseRules": [ 45 | { 46 | "breaking": true, 47 | "release": "major" 48 | }, 49 | { 50 | "revert": true, 51 | "release": "patch" 52 | }, 53 | { 54 | "type": "feat", 55 | "release": "minor" 56 | }, 57 | { 58 | "type": "fix", 59 | "release": "patch" 60 | }, 61 | { 62 | "type": "chore", 63 | "release": "patch" 64 | }, 65 | { 66 | "type": "docs", 67 | "release": "patch" 68 | }, 69 | { 70 | "type": "test", 71 | "release": "patch" 72 | }, 73 | { 74 | "scope": "no-release", 75 | "release": false 76 | } 77 | ] 78 | } 79 | ], 80 | [ 81 | "@semantic-release/release-notes-generator", 82 | { 83 | "preset": "conventionalcommits", 84 | "presetConfig": { 85 | "types": [ 86 | { 87 | "type": "feat", 88 | "section": "Features" 89 | }, 90 | { 91 | "type": "fix", 92 | "section": "Bug Fixes" 93 | }, 94 | { 95 | "type": "chore", 96 | "section": "Trivial Changes" 97 | }, 98 | { 99 | "type": "docs", 100 | "section": "Trivial Changes" 101 | }, 102 | { 103 | "type": "test", 104 | "section": "Tests" 105 | } 106 | ] 107 | } 108 | } 109 | ], 110 | "@semantic-release/changelog", 111 | "@semantic-release/npm", 112 | "@semantic-release/github", 113 | "@semantic-release/git" 114 | ] 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | name: branch-diff 2 | version: git 3 | summary: Compares 2 git branches without hassle. 4 | description: | 5 | A tool to list print the commits on one git branch 6 | that are not on another using loose comparison. 7 | grade: stable 8 | confinement: strict 9 | 10 | apps: 11 | branch-diff: 12 | command: bin/branch-diff 13 | plugs: [network, home] 14 | 15 | parts: 16 | branch-diff: 17 | source: . 18 | plugin: nodejs 19 | stage-packages: [git] 20 | --------------------------------------------------------------------------------