Unified Git
Unify your team's Git workflow — standardized branch naming and one-click pull
requests, integrated directly into VS Code's built-in Source Control.
Unified Git adds two commands, Create Branch and Create Pull Request, that
turn a ticket key into a correctly-named branch off the default branch and, when
you're done, push it and open a pull request — talking to Azure DevOps or GitHub
over their REST APIs using VS Code's built-in authentication (no extra CLIs, no
personal access tokens to manage).
Requirements
- VS Code 1.90+ with the built-in Git extension enabled (this extension
depends on
vscode.git).
- A repository hosted on Azure DevOps (
dev.azure.com or *.visualstudio.com)
or GitHub for in-editor pull-request creation. Other hosts still work via a
browser hand-off (see How pull requests are created).
- For in-editor PR creation you sign in once through VS Code's built-in
Microsoft (Azure DevOps) or GitHub account provider — no tokens to copy.
- For AI drafting (a ✨ button, on by default): GitHub Copilot (or any
registered VS Code language-model provider). Without one the button is hidden and
PR creation is fully manual; disable it with
unifiedGit.ai.enabled: false.
Installation
This is an internal extension distributed as a .vsix file (it is not on the
Marketplace).
- Get the
unified-git-<version>.vsix (build it yourself — see
For maintainers — or use the one your team publishes).
- In VS Code: Extensions view →
⋯ menu → Install from VSIX…, or from a
terminal:
code --install-extension unified-git-0.0.1.vsix
- Reload the window.
Where to find the commands
- Source Control view — a Unified Git section identifies its effective
repository in the header (
repo: <folder>) and shows the current branch plus
any open pull request. Use the Select Repository ($(repo)) header action to
pin one repository for this workspace; Automatic clears the pin and follows
the active SCM repository, then the active editor, or uses the only open
repository. A pin survives reloads. If a pinned repository is closed, the header
shows repo: unavailable; if automatic selection is ambiguous, it shows repo: none and workflow commands prompt for a repository. Draft PRs are marked
draft; ordinary open PRs need no status suffix. Reporting rows have no click
action. When the branch has an Azure DevOps or GitHub upstream, its inline
buttons open the remote branch or copy its link; the PR row has matching buttons
for the pull request. Create Branch, Create Pull Request, and Refresh
Pull Request are also available in the section header. PR lookup is silent and
appears only when an existing Azure DevOps or GitHub sign-in session is
available.
- Command Palette —
Unified Git: Create Branch, Unified Git: Create Pull Request,
Unified Git: Select Repository, Unified Git: Switch Account, and
Unified Git: Refresh Pull Request.
Usage
Create Branch
Creates a fresh ticket branch off the (protected) default branch.
- Pick a prefix —
feat, fix, bug, chore, docs, or type your own.
- Enter the ticket key — validated live against the configured pattern
(default: keys like
GR-123).
- Optional short description — a few words appended as a slug (skip with Enter).
Unified Git then, all through the built-in Git API:
- stashes any uncommitted work (carried onto the new branch),
- switches to the default branch and fast-forwards it from the remote,
- creates and checks out
prefix/TICKET-KEY[-slug] (e.g. feat/GR-123-login-timeout),
- restores your stashed work (and tells you if a conflict left it in the stash).
If the branch already exists you're offered to switch to it instead.
Create Pull Request
Run it while on a ticket branch.
- Enter a summary for the PR title — or press the ✨ Generate with AI button
inside the input field to draft one from your branch, ticket, and commit messages
via VS Code's language model (GitHub Copilot). VS Code versions before 1.109 show
the action in the input title bar instead. The text is inserted for you to review;
the description is not generated or pre-filled by this action. Set
unifiedGit.ai.autoGenerate to draft the title, description, or both up front, or
unifiedGit.ai.enabled: false to hide the button.
- Review the description in a multiline Markdown editor, pre-filled from the
template (or an up-front AI draft). Use the actions above the document to create
the PR, regenerate the description with AI, or cancel. Description generation
changes only the description. Turn this step off with
unifiedGit.pr.promptForDescription: false.
- Unified Git pushes the branch (setting upstream if needed), then creates
the pull request into the default branch and shows you a link to open it.
The PR title and description come from templates (see
Configuration); by default the title is
prefix(TICKET-KEY): summary, e.g. feat(GR-123): Fix login timeout on slow networks.
How pull requests are created
Create Pull Request degrades gracefully — it always gets you to a PR:
- In-editor (REST). On Azure DevOps or GitHub, if you're signed in through
VS Code's built-in account provider, the PR is created via the provider's REST
API and you can open its direct link or copy it to the clipboard. First use
shows a one-time sign-in/consent dialog.
- Browser hand-off. If you're not signed in, decline, or the API call fails,
your browser opens a fully-prefilled "create pull request" page — you just
review and click Create.
- Unknown host. For unrecognized remotes, the branch is pushed and its name
copied to your clipboard so you can open the PR manually.
Auto-complete (Azure DevOps only, opt-in). Set unifiedGit.pr.autoComplete to
true and the PR is marked to complete automatically once branch policies pass,
using your unifiedGit.pr.mergeStrategy and unifiedGit.pr.deleteSourceBranch
settings. GitHub auto-merge is not currently automated.
Configuration
Team conventions live in VS Code settings under the Unified Git section —
search "Unified Git" in Settings (Ctrl/Cmd ,), or edit settings.json
directly. Because these are ordinary settings you get autocomplete, validation,
and inline descriptions for free, and you can set them at any level:
- Workspace — commit
.vscode/settings.json to the repository so the whole
team shares the same conventions (recommended).
- Folder — per-folder overrides in a multi-root workspace.
- User — your personal defaults across every repository.
Everything is optional; anything you omit uses the built-in default. Example
committed .vscode/settings.json:
{
// "auto" derives the default branch from the repo; or set a literal name.
"unifiedGit.defaultBranch": "auto",
// RegExp the ticket key must match.
"unifiedGit.ticketPattern": "^[A-Z][A-Z0-9]+-\\d+$",
// Branch prefixes offered in the picker. `default: true` preselects one.
"unifiedGit.prefixes": [
{ "label": "feature", "value": "feat", "default": true },
{ "label": "fix", "value": "fix" },
{ "label": "bug", "value": "bug" },
{ "label": "chore", "value": "chore" },
{ "label": "docs", "value": "docs" }
],
// Branch name template. Supports ${prefix} and ${ticket}.
"unifiedGit.branchTemplate": "${prefix}/${ticket}",
// Allow an optional free-text slug appended to the branch.
"unifiedGit.allowBranchSuffix": true,
// Title/description templates. See "Template variables" below.
"unifiedGit.pr.titleTemplate": "${prefix}(${ticket}): ${summary}",
"unifiedGit.pr.descriptionTemplate": "Resolves ${ticket}.\n\n${summary}",
// Open the description in a Markdown editor before PR creation; empty = template.
"unifiedGit.pr.promptForDescription": true,
"unifiedGit.pr.draft": false,
// Azure DevOps auto-complete (opt-in; the human merges by default).
"unifiedGit.pr.autoComplete": false,
"unifiedGit.pr.deleteSourceBranch": true,
// One of: "squash" | "merge" | "rebase" | "noFastForward".
"unifiedGit.pr.mergeStrategy": "squash",
// Show ✨ "Generate with AI" actions for PR text (needs GitHub Copilot).
"unifiedGit.ai.enabled": true,
// One of: "none" | "title" | "description" | "both".
"unifiedGit.ai.autoGenerate": "none"
}
unifiedGit.ai.autoGenerate owns automatic drafting for both fields so every
combination is explicit and testable. The deprecated
unifiedGit.ai.autoCreate: true is still read as "both" when autoGenerate
has not been configured.
Template variables
| Variable |
Available in |
Meaning |
${prefix} |
branch, PR title/description |
The chosen branch prefix, e.g. feat. |
${Prefix} |
PR title/description |
The prefix, capitalized, e.g. Feat. |
${ticket} |
branch, PR title/description |
The ticket key, e.g. GR-123. |
${summary} |
PR title/description |
The summary you type when creating the PR. |
${branch} |
PR title/description |
The full source branch name. |
${base} |
PR title/description |
The target/default branch name. |
For maintainers
npm install # install dev dependencies
npm run compile # type-check + emit to out/ (npm run watch for continuous build)
npm run lint # eslint
npm run verify # lint + compile + unit tests
npm run package # verify, then produce unified-git-<version>.vsix
npm run package uses @vscode/vsce
and writes a .vsix you can hand to the team or install directly.
Publish to the Visual Studio Marketplace
Publishing requires access to the cbs-consulting Marketplace publisher. Create
an Azure DevOps personal access token with Marketplace management permission, then
authenticate without committing or passing the token as a command-line argument:
npx vsce login cbs-consulting
For CI, store the token as the secret environment variable VSCE_PAT. Before
publishing, update CHANGELOG.md and confirm that the Marketplace visibility is
appropriate for this proprietary internal extension. Marketplace publication of
a version is externally visible and cannot be overwritten with different content.
Publish the exact version currently declared in package.json:
npm run publish
Or increment and publish a semantic version in one command:
npm run publish:patch
npm run publish:minor
npm run publish:major
The semantic publish scripts update package.json and package-lock.json, but do
not create a Git commit or tag. Review and commit those version changes after a
successful release. None of the publish scripts suppress duplicate-version errors.
Troubleshooting
Open View → Output and select Unified Git, or run Unified Git: Show
Output from the Command Palette. The log records extension activation, Git API
initialization, open repository roots, active/pinned/editor repository resolution,
selector choices, SCM report updates, and command failures. It intentionally does
not log remote URLs, access tokens, account credentials, PR titles, or PR
descriptions.
For a repository-selection issue, clear the output, reproduce it, and inspect the
latest Resolved repository entry. Its resolution value identifies whether the
pin, active SCM repository, active editor, sole open repository, or an ambiguous
workspace controlled the result.
License
Proprietary — internal use within cbs-consulting only. See the bundled LICENSE file.