Skip to main content

Overview

Visual Studio Code has integrated source control management (SCM) with Git support built-in. The Source Control view provides a streamlined interface for common Git operations without leaving the editor.

Getting Started

1

Open Source Control View

Click the Source Control icon in the Activity Bar or press Ctrl+Shift+G (Windows/Linux) or Cmd+Shift+G (macOS)
2

Initialize Repository

Click “Initialize Repository” if you don’t have a Git repository yet
3

Stage Changes

Click the + icon next to changed files to stage them
4

Commit Changes

Enter a commit message and press Ctrl+Enter (Windows/Linux) or Cmd+Enter (macOS)

Source Control Architecture

VS Code’s SCM system is designed to support multiple providers:
// From VS Code source: src/vs/workbench/contrib/scm/common/scm.ts
export const VIEWLET_ID = 'workbench.view.scm';
export const VIEW_PANE_ID = 'workbench.scm';
export const REPOSITORIES_VIEW_PANE_ID = 'workbench.scm.repositories';
export const HISTORY_VIEW_PANE_ID = 'workbench.scm.history';

export interface ISCMProvider extends IDisposable {
  readonly id: string;
  readonly label: string;
  readonly rootUri?: URI;
  readonly groups: readonly ISCMResourceGroup[];
  readonly inputBoxTextModel: ITextModel;
  readonly count: IObservable<number | undefined>;
  readonly commitTemplate: IObservable<string>;
  readonly historyProvider: IObservable<ISCMHistoryProvider | undefined>;
}

View Modes

Switch between list and tree view for better organization:
export const enum ViewMode {
  List = 'list',
  Tree = 'tree'
}
{
  "scm.defaultViewMode": "list"
}

Resource Groups

Changes are organized into groups:
export interface ISCMResourceGroup {
  readonly id: string;
  readonly provider: ISCMProvider;
  readonly resources: readonly ISCMResource[];
  readonly label: string;
  readonly hideWhenEmpty: boolean;
}

export interface ISCMResource {
  readonly resourceGroup: ISCMResourceGroup;
  readonly sourceUri: URI;
  readonly decorations: ISCMResourceDecorations;
  open(preserveFocus: boolean): Promise<void>;
}

Common Resource Groups

  • Changes: Modified files not yet staged
  • Staged Changes: Files ready to commit
  • Merge Changes: Files with merge conflicts
  • Untracked: New files not yet added to Git

Common Operations

Staging and Unstaging

1

Stage Individual Files

Click the + icon next to a file in the Changes section
2

Stage All Changes

Click the + icon next to “Changes” header
3

Unstage Files

Click the - icon next to a file in the Staged Changes section
4

Stage Selected Lines

Select lines in the editor, right-click, and choose “Stage Selected Ranges”

Committing

Commit your staged changes with a message:
// The commit template is provided by the SCM provider
readonly commitTemplate: IObservable<string>;
Use Ctrl+Enter (Windows/Linux) or Cmd+Enter (macOS) to commit. The commit input box supports multi-line messages.

Keyboard Shortcuts

ActionWindows/LinuxmacOS
Open Source ControlCtrl+Shift+GCmd+Shift+G
CommitCtrl+EnterCmd+Enter
RefreshCtrl+RCmd+R
Stage changesCtrl+K Ctrl+ACmd+K Cmd+A
Undo last commitCtrl+K Ctrl+UCmd+K Cmd+U

Diff Editor

View changes in a side-by-side diff editor:
export interface ISCMResource {
  readonly multiDiffEditorOriginalUri: URI | undefined;
  readonly multiDiffEditorModifiedUri: URI | undefined;
}
Click on any changed file to open the diff editor showing the previous and current versions.
  • F7: Go to next change
  • Shift+F7: Go to previous change
  • Alt+F5: Go to next conflict
  • Shift+Alt+F5: Go to previous conflict

Branching and Merging

Branch Operations

Access branch operations from the Source Control menu or status bar:
1

View Current Branch

Check the branch name in the status bar (bottom left)
2

Switch Branch

Click the branch name and select a different branch
3

Create Branch

Click branch name, select “Create new branch”, and enter a name
4

Merge Branch

Use Git commands from the Command Palette (Ctrl+Shift+P)

Merge Conflict Resolution

When conflicts occur, VS Code provides inline tools:
<<<<<<< HEAD
const version = '1.0.0';
=======
const version = '1.1.0';
>>>>>>> feature-branch

Conflict Resolution Actions

  • Accept Current Change: Keep the HEAD version
  • Accept Incoming Change: Keep the merging branch version
  • Accept Both Changes: Keep both versions
  • Compare Changes: Open in diff editor

Git Commands

Access Git commands via the Command Palette:
Git: Clone
Git: Pull
Git: Push
Git: Fetch
Git: Checkout to...
Git: Create Branch...
Git: Delete Branch...
Git: Merge Branch...
Git: Rebase Branch...
Git: Stash
Git: Pop Stash
Git: View History

Configuration

Git Settings

{
  "git.enabled": true,
  "git.path": null,
  "git.autorefresh": true,
  "git.autofetch": true,
  "git.autofetchPeriod": 180,
  "git.confirmSync": true,
  "git.enableSmartCommit": false,
  "git.enableCommitSigning": false,
  "git.defaultCloneDirectory": null
}

SCM View Settings

{
  "scm.diffDecorations": "all",
  "scm.diffDecorationsGutterWidth": 3,
  "scm.alwaysShowRepositories": false,
  "scm.repositories.visible": 10
}

Decorations

Customize how changes are displayed in the editor:
{
  "git.decorations.enabled": true,
  "scm.diffDecorations": "all",
  "scm.diffDecorationsGutterVisibility": "always",
  "scm.diffDecorationsGutterAction": "diff"
}
export interface ISCMResourceDecorations {
  icon?: URI | ThemeIcon;
  iconDark?: URI | ThemeIcon;
  tooltip?: string;
  strikeThrough?: boolean;
  faded?: boolean;
}

History and Timeline

View file history and timeline:
readonly historyProvider: IObservable<ISCMHistoryProvider | undefined>;
1

View File History

Right-click a file and select “View File History”
2

Timeline View

Open the Timeline view in the Explorer sidebar to see file changes over time
3

Compare with Previous

Right-click a commit in the timeline to compare with current version

Advanced Features

Baseline Resources

Compare against different baselines:
export interface IBaselineResourceProvider {
  getBaselineResource(resource: URI): Promise<URI>;
}

Multi-Repository Support

Work with multiple Git repositories simultaneously:
{
  "scm.alwaysShowRepositories": true,
  "scm.repositories.visible": 5
}
VS Code automatically detects multiple Git repositories in your workspace and displays them separately in the Source Control view.

Action Buttons

Customize the source control action button:
readonly actionButton: IObservable<ISCMActionButtonDescriptor | undefined>;
readonly statusBarCommands: IObservable<readonly Command[] | undefined>;

Git Integration

.gitignore Support

VS Code respects .gitignore files and provides:
  • Syntax highlighting for .gitignore files
  • Auto-completion of patterns
  • Grayed-out ignored files in Explorer

Git Output

View detailed Git command output:
1

Open Output Panel

Press Ctrl+Shift+U (Windows/Linux) or Cmd+Shift+U (macOS)
2

Select Git

Choose “Git” from the dropdown menu
3

View Commands

See all Git commands executed by VS Code

Third-Party SCM Providers

Extend source control support beyond Git:

Popular SCM Extensions

  • GitHub Pull Requests and Issues: Manage PRs and issues
  • GitLens: Advanced Git features and visualization
  • SVN: Subversion support
  • Perforce: P4 integration

Best Practices

Use meaningful commit messages that describe what changed and why. The first line should be a brief summary (50 chars or less).
Avoid committing sensitive information like passwords, API keys, or personal data. Use environment variables and .gitignore instead.

Commit Message Format

Short summary (50 chars or less)

More detailed explanation if needed. Wrap at 72 characters.
Explain the problem this commit solves and why you made
the changes you did.

- Bullet points are okay too
- Use imperative mood: "Add feature" not "Added feature"

Troubleshooting

  1. Changes not appearing
    • Click the refresh icon in the Source Control view
    • Check that Git is installed and in your PATH
    • Verify you’re in a Git repository
  2. Authentication issues
    • Configure Git credentials: git config --global user.name "Your Name"
    • Use SSH keys or credential manager
    • Check Git extension settings
  3. Performance with large repos
    • Limit scope with git.scanRepositories
    • Disable auto-fetch: "git.autofetch": false
    • Use sparse checkout for monorepos

Build docs developers (and LLMs) love