Git - add `git.commitShortHashLength` setting (#237343)
parent
4e2ba23aed
commit
3548eae0e1
|
@ -3229,6 +3229,14 @@
|
|||
"type": "string",
|
||||
"default": "${authorName} (${authorDateAgo})",
|
||||
"markdownDescription": "%config.blameStatusBarItem.template%"
|
||||
},
|
||||
"git.commitShortHashLength": {
|
||||
"type": "number",
|
||||
"default": 7,
|
||||
"minimum": 7,
|
||||
"maximum": 40,
|
||||
"markdownDescription": "%config.commitShortHashLength%",
|
||||
"scope": "resource"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -278,9 +278,10 @@
|
|||
"config.publishBeforeContinueOn.prompt": "Prompt to publish unpublished Git state when using Continue Working On from a Git repository",
|
||||
"config.similarityThreshold": "Controls the threshold of the similarity index (the amount of additions/deletions compared to the file's size) for changes in a pair of added/deleted files to be considered a rename. **Note:** Requires Git version `2.18.0` or later.",
|
||||
"config.blameEditorDecoration.enabled": "Controls whether to show blame information in the editor using editor decorations.",
|
||||
"config.blameEditorDecoration.template": "Template for the blame information editor decoration. Supported variables:\n\n* `hash`: Commit hash\n\n* `hashShort`: First 8 characters of the commit hash\n\n* `subject`: First line of the commit message\n\n* `authorName`: Author name\n\n* `authorEmail`: Author email\n\n* `authorDate`: Author date\n\n* `authorDateAgo`: Time difference between now and the author date\n\n",
|
||||
"config.blameEditorDecoration.template": "Template for the blame information editor decoration. Supported variables:\n\n* `hash`: Commit hash\n\n* `hashShort`: First N characters of the commit hash according to `#git.commitShortHashLength#`\n\n* `subject`: First line of the commit message\n\n* `authorName`: Author name\n\n* `authorEmail`: Author email\n\n* `authorDate`: Author date\n\n* `authorDateAgo`: Time difference between now and the author date\n\n",
|
||||
"config.blameStatusBarItem.enabled": "Controls whether to show blame information in the status bar.",
|
||||
"config.blameStatusBarItem.template": "Template for the blame information status bar item. Supported variables:\n\n* `hash`: Commit hash\n\n* `hashShort`: First 8 characters of the commit hash\n\n* `subject`: First line of the commit message\n\n* `authorName`: Author name\n\n* `authorEmail`: Author email\n\n* `authorDate`: Author date\n\n* `authorDateAgo`: Time difference between now and the author date\n\n",
|
||||
"config.blameStatusBarItem.template": "Template for the blame information status bar item. Supported variables:\n\n* `hash`: Commit hash\n\n* `hashShort`: First N characters of the commit hash according to `#git.commitShortHashLength#`\n\n* `subject`: First line of the commit message\n\n* `authorName`: Author name\n\n* `authorEmail`: Author email\n\n* `authorDate`: Author date\n\n* `authorDateAgo`: Time difference between now and the author date\n\n",
|
||||
"config.commitShortHashLength": "Controls the length of the commit short hash.",
|
||||
"submenu.explorer": "Git",
|
||||
"submenu.commit": "Commit",
|
||||
"submenu.commit.amend": "Amend",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { DecorationOptions, l10n, Position, Range, TextEditor, TextEditorChange, TextEditorDecorationType, TextEditorChangeKind, ThemeColor, Uri, window, workspace, EventEmitter, ConfigurationChangeEvent, StatusBarItem, StatusBarAlignment, Command, MarkdownString, languages, HoverProvider, CancellationToken, Hover, TextDocument } from 'vscode';
|
||||
import { Model } from './model';
|
||||
import { dispose, fromNow, IDisposable } from './util';
|
||||
import { dispose, fromNow, getCommitShortHash, IDisposable } from './util';
|
||||
import { Repository } from './repository';
|
||||
import { throttle } from './decorators';
|
||||
import { BlameInformation, Commit } from './git';
|
||||
|
@ -186,14 +186,14 @@ export class GitBlameController {
|
|||
this._onDidChangeConfiguration();
|
||||
}
|
||||
|
||||
formatBlameInformationMessage(template: string, blameInformation: BlameInformation): string {
|
||||
formatBlameInformationMessage(documentUri: Uri, template: string, blameInformation: BlameInformation): string {
|
||||
const subject = blameInformation.subject && blameInformation.subject.length > this._subjectMaxLength
|
||||
? `${blameInformation.subject.substring(0, this._subjectMaxLength)}\u2026`
|
||||
: blameInformation.subject;
|
||||
|
||||
const templateTokens = {
|
||||
hash: blameInformation.hash,
|
||||
hashShort: blameInformation.hash.substring(0, 8),
|
||||
hashShort: getCommitShortHash(documentUri, blameInformation.hash),
|
||||
subject: emojify(subject ?? ''),
|
||||
authorName: blameInformation.authorName ?? '',
|
||||
authorEmail: blameInformation.authorEmail ?? '',
|
||||
|
@ -260,7 +260,7 @@ export class GitBlameController {
|
|||
markdownString.appendMarkdown(`\n\n---\n\n`);
|
||||
}
|
||||
|
||||
markdownString.appendMarkdown(`[\`$(git-commit) ${blameInformationOrCommit.hash.substring(0, 8)} \`](command:git.blameStatusBarItem.viewCommit?${encodeURIComponent(JSON.stringify([documentUri, blameInformationOrCommit.hash]))} "${l10n.t('View Commit')}")`);
|
||||
markdownString.appendMarkdown(`[\`$(git-commit) ${getCommitShortHash(documentUri, blameInformationOrCommit.hash)} \`](command:git.blameStatusBarItem.viewCommit?${encodeURIComponent(JSON.stringify([documentUri, blameInformationOrCommit.hash]))} "${l10n.t('View Commit')}")`);
|
||||
markdownString.appendMarkdown(' ');
|
||||
markdownString.appendMarkdown(`[$(copy)](command:git.blameStatusBarItem.copyContent?${encodeURIComponent(JSON.stringify(blameInformationOrCommit.hash))} "${l10n.t('Copy Commit Hash')}")`);
|
||||
markdownString.appendMarkdown(' | ');
|
||||
|
@ -571,7 +571,9 @@ class GitBlameEditorDecoration implements HoverProvider {
|
|||
}
|
||||
|
||||
private _onDidChangeConfiguration(e?: ConfigurationChangeEvent): void {
|
||||
if (e && !e.affectsConfiguration('git.blame.editorDecoration.template')) {
|
||||
if (e &&
|
||||
!e.affectsConfiguration('git.commitShortHashLength') &&
|
||||
!e.affectsConfiguration('git.blame.editorDecoration.template')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -610,7 +612,7 @@ class GitBlameEditorDecoration implements HoverProvider {
|
|||
|
||||
const decorations = blameInformation.map(blame => {
|
||||
const contentText = typeof blame.blameInformation !== 'string'
|
||||
? this._controller.formatBlameInformationMessage(template, blame.blameInformation)
|
||||
? this._controller.formatBlameInformationMessage(textEditor.document.uri, template, blame.blameInformation)
|
||||
: blame.blameInformation;
|
||||
|
||||
return this._createDecoration(blame.lineNumber, contentText);
|
||||
|
@ -663,7 +665,8 @@ class GitBlameStatusBarItem {
|
|||
}
|
||||
|
||||
private _onDidChangeConfiguration(e: ConfigurationChangeEvent): void {
|
||||
if (!e.affectsConfiguration('git.blame.statusBarItem.template')) {
|
||||
if (!e.affectsConfiguration('git.commitShortHashLength') &&
|
||||
!e.affectsConfiguration('git.blame.statusBarItem.template')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -690,7 +693,7 @@ class GitBlameStatusBarItem {
|
|||
const config = workspace.getConfiguration('git');
|
||||
const template = config.get<string>('blame.statusBarItem.template', '${authorName} (${authorDateAgo})');
|
||||
|
||||
this._statusBarItem.text = `$(git-commit) ${this._controller.formatBlameInformationMessage(template, blameInformation[0].blameInformation)}`;
|
||||
this._statusBarItem.text = `$(git-commit) ${this._controller.formatBlameInformationMessage(window.activeTextEditor.document.uri, template, blameInformation[0].blameInformation)}`;
|
||||
this._statusBarItem.tooltip = this._controller.getBlameInformationHover(window.activeTextEditor.document.uri, blameInformation[0].blameInformation);
|
||||
this._statusBarItem.command = {
|
||||
title: l10n.t('View Commit'),
|
||||
|
|
|
@ -14,7 +14,7 @@ import { Model } from './model';
|
|||
import { GitResourceGroup, Repository, Resource, ResourceGroupType } from './repository';
|
||||
import { DiffEditorSelectionHunkToolbarContext, applyLineChanges, getModifiedRange, getWorkingTreeAndIndexDiffInformation, getWorkingTreeDiffInformation, intersectDiffWithRange, invertLineChange, toLineChanges, toLineRanges } from './staging';
|
||||
import { fromGitUri, toGitUri, isGitUri, toMergeUris, toMultiFileDiffEditorUris } from './uri';
|
||||
import { dispose, grep, isDefined, isDescendant, pathEquals, relativePath, truncate } from './util';
|
||||
import { dispose, getCommitShortHash, grep, isDefined, isDescendant, pathEquals, relativePath, truncate } from './util';
|
||||
import { GitTimelineItem } from './timelineProvider';
|
||||
import { ApiRepository } from './api/api1';
|
||||
import { getRemoteSourceActions, pickRemoteSource } from './remoteSource';
|
||||
|
@ -4286,16 +4286,17 @@ export class CommandCenter {
|
|||
|
||||
let title: string | undefined;
|
||||
let historyItemParentId: string | undefined;
|
||||
const rootUri = Uri.file(repository.root);
|
||||
|
||||
// If historyItem2 is not provided, we are viewing a single commit. If historyItem2 is
|
||||
// provided, we are viewing a range and we have to include both start and end commits.
|
||||
// TODO@lszomoru - handle the case when historyItem2 is the first commit in the repository
|
||||
if (!historyItem2) {
|
||||
const commit = await repository.getCommit(historyItem1.id);
|
||||
title = `${historyItem1.id.substring(0, 8)} - ${truncate(commit.message)}`;
|
||||
title = `${getCommitShortHash(rootUri, historyItem1.id)} - ${truncate(commit.message)}`;
|
||||
historyItemParentId = historyItem1.parentIds.length > 0 ? historyItem1.parentIds[0] : `${historyItem1.id}^`;
|
||||
} else {
|
||||
title = l10n.t('All Changes ({0} ↔ {1})', historyItem2.id.substring(0, 8), historyItem1.id.substring(0, 8));
|
||||
title = l10n.t('All Changes ({0} ↔ {1})', getCommitShortHash(rootUri, historyItem2.id), getCommitShortHash(rootUri, historyItem1.id));
|
||||
historyItemParentId = historyItem2.parentIds.length > 0 ? historyItem2.parentIds[0] : `${historyItem2.id}^`;
|
||||
}
|
||||
|
||||
|
@ -4310,8 +4311,9 @@ export class CommandCenter {
|
|||
return;
|
||||
}
|
||||
|
||||
const modifiedShortRef = historyItem.id.substring(0, 8);
|
||||
const originalShortRef = historyItem.parentIds.length > 0 ? historyItem.parentIds[0].substring(0, 8) : `${modifiedShortRef}^`;
|
||||
const rootUri = Uri.file(repository.root);
|
||||
const modifiedShortRef = getCommitShortHash(rootUri, historyItem.id);
|
||||
const originalShortRef = historyItem.parentIds.length > 0 ? getCommitShortHash(rootUri, historyItem.parentIds[0]) : `${modifiedShortRef}^`;
|
||||
const title = l10n.t('All Changes ({0} ↔ {1})', originalShortRef, modifiedShortRef);
|
||||
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), historyItem.id, { scheme: 'git-changes' });
|
||||
|
@ -4350,8 +4352,9 @@ export class CommandCenter {
|
|||
return;
|
||||
}
|
||||
|
||||
const rootUri = Uri.file(repository.root);
|
||||
const commit = await repository.getCommit(historyItemId);
|
||||
const title = `${historyItemId.substring(0, 8)} - ${truncate(commit.message)}`;
|
||||
const title = `${getCommitShortHash(rootUri, historyItemId)} - ${truncate(commit.message)}`;
|
||||
const historyItemParentId = commit.parents.length > 0 ? commit.parents[0] : `${historyItemId}^`;
|
||||
|
||||
const multiDiffSourceUri = Uri.from({ scheme: 'scm-history-item', path: `${repository.root}/${historyItemParentId}..${historyItemId}` });
|
||||
|
|
|
@ -6,20 +6,22 @@
|
|||
|
||||
import { Disposable, Event, EventEmitter, FileDecoration, FileDecorationProvider, SourceControlHistoryItem, SourceControlHistoryItemChange, SourceControlHistoryOptions, SourceControlHistoryProvider, ThemeIcon, Uri, window, LogOutputChannel, SourceControlHistoryItemRef, l10n, SourceControlHistoryItemRefsChangeEvent } from 'vscode';
|
||||
import { Repository, Resource } from './repository';
|
||||
import { IDisposable, deltaHistoryItemRefs, dispose, filterEvent } from './util';
|
||||
import { IDisposable, deltaHistoryItemRefs, dispose, filterEvent, getCommitShortHash } from './util';
|
||||
import { toGitUri } from './uri';
|
||||
import { Branch, LogOptions, Ref, RefType } from './api/git';
|
||||
import { emojify, ensureEmojis } from './emoji';
|
||||
import { Commit } from './git';
|
||||
import { OperationKind, OperationResult } from './operation';
|
||||
|
||||
function toSourceControlHistoryItemRef(ref: Ref): SourceControlHistoryItemRef {
|
||||
function toSourceControlHistoryItemRef(repository: Repository, ref: Ref): SourceControlHistoryItemRef {
|
||||
const rootUri = Uri.file(repository.root);
|
||||
|
||||
switch (ref.type) {
|
||||
case RefType.RemoteHead:
|
||||
return {
|
||||
id: `refs/remotes/${ref.name}`,
|
||||
name: ref.name ?? '',
|
||||
description: ref.commit ? l10n.t('Remote branch at {0}', ref.commit.substring(0, 8)) : undefined,
|
||||
description: ref.commit ? l10n.t('Remote branch at {0}', getCommitShortHash(rootUri, ref.commit)) : undefined,
|
||||
revision: ref.commit,
|
||||
icon: new ThemeIcon('cloud'),
|
||||
category: l10n.t('remote branches')
|
||||
|
@ -28,7 +30,7 @@ function toSourceControlHistoryItemRef(ref: Ref): SourceControlHistoryItemRef {
|
|||
return {
|
||||
id: `refs/tags/${ref.name}`,
|
||||
name: ref.name ?? '',
|
||||
description: ref.commit ? l10n.t('Tag at {0}', ref.commit.substring(0, 8)) : undefined,
|
||||
description: ref.commit ? l10n.t('Tag at {0}', getCommitShortHash(rootUri, ref.commit)) : undefined,
|
||||
revision: ref.commit,
|
||||
icon: new ThemeIcon('tag'),
|
||||
category: l10n.t('tags')
|
||||
|
@ -37,7 +39,7 @@ function toSourceControlHistoryItemRef(ref: Ref): SourceControlHistoryItemRef {
|
|||
return {
|
||||
id: `refs/heads/${ref.name}`,
|
||||
name: ref.name ?? '',
|
||||
description: ref.commit ? ref.commit.substring(0, 8) : undefined,
|
||||
description: ref.commit ? getCommitShortHash(rootUri, ref.commit) : undefined,
|
||||
revision: ref.commit,
|
||||
icon: new ThemeIcon('git-branch'),
|
||||
category: l10n.t('branches')
|
||||
|
@ -178,7 +180,7 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
|||
|
||||
// Refs (alphabetically)
|
||||
const historyItemRefs = this.repository.refs
|
||||
.map(ref => toSourceControlHistoryItemRef(ref))
|
||||
.map(ref => toSourceControlHistoryItemRef(this.repository, ref))
|
||||
.sort((a, b) => a.id.localeCompare(b.id));
|
||||
|
||||
// Auto-fetch
|
||||
|
@ -207,13 +209,13 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
|||
for (const ref of refs) {
|
||||
switch (ref.type) {
|
||||
case RefType.RemoteHead:
|
||||
remoteBranches.push(toSourceControlHistoryItemRef(ref));
|
||||
remoteBranches.push(toSourceControlHistoryItemRef(this.repository, ref));
|
||||
break;
|
||||
case RefType.Tag:
|
||||
tags.push(toSourceControlHistoryItemRef(ref));
|
||||
tags.push(toSourceControlHistoryItemRef(this.repository, ref));
|
||||
break;
|
||||
default:
|
||||
branches.push(toSourceControlHistoryItemRef(ref));
|
||||
branches.push(toSourceControlHistoryItemRef(this.repository, ref));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -259,7 +261,7 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
|||
message: emojify(commit.message),
|
||||
author: commit.authorName,
|
||||
icon: new ThemeIcon('git-commit'),
|
||||
displayId: commit.hash.substring(0, 8),
|
||||
displayId: getCommitShortHash(Uri.file(this.repository.root), commit.hash),
|
||||
timestamp: commit.authorDate?.getTime(),
|
||||
statistics: commit.shortStat ?? { files: 0, insertions: 0, deletions: 0 },
|
||||
references: references.length !== 0 ? references : undefined
|
||||
|
|
|
@ -23,7 +23,7 @@ import { IPushErrorHandlerRegistry } from './pushError';
|
|||
import { IRemoteSourcePublisherRegistry } from './remotePublisher';
|
||||
import { StatusBarCommands } from './statusbar';
|
||||
import { toGitUri } from './uri';
|
||||
import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, IDisposable, isDescendant, onceEvent, pathEquals, relativePath } from './util';
|
||||
import { anyEvent, combinedDisposable, debounceEvent, dispose, EmptyDisposable, eventToPromise, filterEvent, find, getCommitShortHash, IDisposable, isDescendant, onceEvent, pathEquals, relativePath } from './util';
|
||||
import { IFileWatcher, watch } from './watch';
|
||||
import { detectEncoding } from './encoding';
|
||||
|
||||
|
@ -1657,7 +1657,7 @@ export class Repository implements Disposable {
|
|||
}
|
||||
|
||||
async checkout(treeish: string, opts?: { detached?: boolean; pullBeforeCheckout?: boolean }): Promise<void> {
|
||||
const refLabel = opts?.detached ? treeish.substring(0, 8) : treeish;
|
||||
const refLabel = opts?.detached ? getCommitShortHash(Uri.file(this.root), treeish) : treeish;
|
||||
|
||||
await this.run(Operation.Checkout(refLabel),
|
||||
async () => {
|
||||
|
@ -1675,7 +1675,7 @@ export class Repository implements Disposable {
|
|||
}
|
||||
|
||||
async checkoutTracking(treeish: string, opts: { detached?: boolean } = {}): Promise<void> {
|
||||
const refLabel = opts.detached ? treeish.substring(0, 8) : treeish;
|
||||
const refLabel = opts.detached ? getCommitShortHash(Uri.file(this.root), treeish) : treeish;
|
||||
await this.run(Operation.CheckoutTracking(refLabel), () => this.repository.checkout(treeish, [], { ...opts, track: true }));
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Disposable, EventEmitter, SourceControlHistoryItemRef, l10n } from 'vscode';
|
||||
import { Event, Disposable, EventEmitter, SourceControlHistoryItemRef, l10n, workspace, Uri } from 'vscode';
|
||||
import { dirname, sep, relative } from 'path';
|
||||
import { Readable } from 'stream';
|
||||
import { promises as fs, createReadStream } from 'fs';
|
||||
|
@ -766,3 +766,9 @@ export function fromNow(date: number | Date, appendAgoLabel?: boolean, useFullTi
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getCommitShortHash(scope: Uri, hash: string): string {
|
||||
const config = workspace.getConfiguration('git', scope);
|
||||
const shortHashLength = config.get<number>('commitShortHashLength', 7);
|
||||
return hash.substring(0, shortHashLength);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue