fix: clarify sync button and result toasts
Show sync label when no remote changes are known Report pulled file counts in sync success toasts Count pulled files correctly in VS Code sync
This commit is contained in:
@@ -948,6 +948,8 @@ export const GitView: React.FC = () => {
|
|||||||
if (!remote) {
|
if (!remote) {
|
||||||
throw new Error('No remote available for sync');
|
throw new Error('No remote available for sync');
|
||||||
}
|
}
|
||||||
|
let pulledFileCount = 0;
|
||||||
|
let pushedChanges = false;
|
||||||
await git.gitFetch(currentDirectory, { remote: remote.name });
|
await git.gitFetch(currentDirectory, { remote: remote.name });
|
||||||
const afterFetch = await git.getGitStatus(currentDirectory);
|
const afterFetch = await git.getGitStatus(currentDirectory);
|
||||||
|
|
||||||
@@ -956,15 +958,33 @@ export const GitView: React.FC = () => {
|
|||||||
toast.error(t('gitView.toast.commitOrStashBeforeSync'));
|
toast.error(t('gitView.toast.commitOrStashBeforeSync'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await git.gitPull(currentDirectory, getPullOptions(remote));
|
const pullResult = await git.gitPull(currentDirectory, getPullOptions(remote));
|
||||||
|
pulledFileCount = pullResult.files.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const afterPull = await git.getGitStatus(currentDirectory);
|
const afterPull = await git.getGitStatus(currentDirectory);
|
||||||
if ((afterPull.ahead ?? 0) > 0) {
|
if ((afterPull.ahead ?? 0) > 0) {
|
||||||
await git.gitPush(currentDirectory);
|
await git.gitPush(currentDirectory);
|
||||||
|
pushedChanges = true;
|
||||||
}
|
}
|
||||||
|
if (pulledFileCount > 0 && pushedChanges) {
|
||||||
|
toast.success(
|
||||||
|
pulledFileCount === 1
|
||||||
|
? t('gitView.toast.syncedPulledSingleAndPushed', { count: pulledFileCount, name: remote.name })
|
||||||
|
: t('gitView.toast.syncedPulledPluralAndPushed', { count: pulledFileCount, name: remote.name })
|
||||||
|
);
|
||||||
|
} else if (pulledFileCount > 0) {
|
||||||
|
toast.success(
|
||||||
|
pulledFileCount === 1
|
||||||
|
? t('gitView.toast.pulledFilesSingle', { count: pulledFileCount, name: remote.name })
|
||||||
|
: t('gitView.toast.pulledFilesPlural', { count: pulledFileCount, name: remote.name })
|
||||||
|
);
|
||||||
|
} else if (pushedChanges) {
|
||||||
|
toast.success(t('gitView.toast.pushedToUpstream'));
|
||||||
|
} else {
|
||||||
toast.success(t('gitView.toast.syncedChanges'));
|
toast.success(t('gitView.toast.syncedChanges'));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await refreshStatusAndBranches(false);
|
await refreshStatusAndBranches(false);
|
||||||
await refreshLog();
|
await refreshLog();
|
||||||
|
|||||||
@@ -54,11 +54,16 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
|||||||
const blocksRebaseSync = behindCount > 0 && hasUncommittedChanges;
|
const blocksRebaseSync = behindCount > 0 && hasUncommittedChanges;
|
||||||
const isPrimaryDisabled = disabled || syncAction !== null || isRemovingRemote || !trackingRemote || blocksRebaseSync;
|
const isPrimaryDisabled = disabled || syncAction !== null || isRemovingRemote || !trackingRemote || blocksRebaseSync;
|
||||||
const isDropdownDisabled = disabled || syncAction !== null || isRemovingRemote || remotes.length === 0;
|
const isDropdownDisabled = disabled || syncAction !== null || isRemovingRemote || remotes.length === 0;
|
||||||
const countsLabel = t('gitView.sync.syncCounts', { ahead: aheadCount, behind: behindCount });
|
const hasKnownSyncWork = aheadCount > 0 || behindCount > 0;
|
||||||
|
const primaryLabel = hasKnownSyncWork
|
||||||
|
? t('gitView.sync.syncCounts', { ahead: aheadCount, behind: behindCount })
|
||||||
|
: t('gitView.sync.sync');
|
||||||
const tooltipLabel = blocksRebaseSync
|
const tooltipLabel = blocksRebaseSync
|
||||||
? t('gitView.sync.commitOrStashTooltip')
|
? t('gitView.sync.commitOrStashTooltip')
|
||||||
: trackingRemote
|
: trackingRemote
|
||||||
|
? hasKnownSyncWork
|
||||||
? t('gitView.sync.syncChangesTooltip', { ahead: aheadCount, behind: behindCount })
|
? t('gitView.sync.syncChangesTooltip', { ahead: aheadCount, behind: behindCount })
|
||||||
|
: t('gitView.sync.syncChanges')
|
||||||
: t('gitView.sync.noRemoteTooltip');
|
: t('gitView.sync.noRemoteTooltip');
|
||||||
|
|
||||||
const handleSync = () => {
|
const handleSync = () => {
|
||||||
@@ -87,7 +92,7 @@ export const SyncActions: React.FC<SyncActionsProps> = ({
|
|||||||
) : (
|
) : (
|
||||||
<RiRefreshLine className="size-4" />
|
<RiRefreshLine className="size-4" />
|
||||||
)}
|
)}
|
||||||
<span className="whitespace-nowrap tabular-nums">{countsLabel}</span>
|
<span className="whitespace-nowrap tabular-nums">{primaryLabel}</span>
|
||||||
</button>
|
</button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent sideOffset={8}>{tooltipLabel}</TooltipContent>
|
<TooltipContent sideOffset={8}>{tooltipLabel}</TooltipContent>
|
||||||
|
|||||||
@@ -557,6 +557,7 @@ export const dict = {
|
|||||||
'gitView.sync.push': 'Push',
|
'gitView.sync.push': 'Push',
|
||||||
'gitView.sync.pushTooltip': 'Push changes',
|
'gitView.sync.pushTooltip': 'Push changes',
|
||||||
'gitView.sync.pushTooltipAhead': 'Push changes ({count} ahead)',
|
'gitView.sync.pushTooltipAhead': 'Push changes ({count} ahead)',
|
||||||
|
'gitView.sync.sync': 'sync',
|
||||||
'gitView.sync.syncChanges': 'Sync Changes',
|
'gitView.sync.syncChanges': 'Sync Changes',
|
||||||
'gitView.sync.syncChangesTooltip': 'Sync Changes ({behind} down, {ahead} up)',
|
'gitView.sync.syncChangesTooltip': 'Sync Changes ({behind} down, {ahead} up)',
|
||||||
'gitView.sync.syncChangesWithCounts': 'Sync Changes {behind}↓ {ahead}↑',
|
'gitView.sync.syncChangesWithCounts': 'Sync Changes {behind}↓ {ahead}↑',
|
||||||
@@ -705,6 +706,8 @@ export const dict = {
|
|||||||
'gitView.toast.pulledFilesSingle': 'Pulled {count} file from {name}',
|
'gitView.toast.pulledFilesSingle': 'Pulled {count} file from {name}',
|
||||||
'gitView.toast.pushedToUpstream': 'Pushed to upstream',
|
'gitView.toast.pushedToUpstream': 'Pushed to upstream',
|
||||||
'gitView.toast.commitOrStashBeforeSync': 'Commit or stash your changes before syncing',
|
'gitView.toast.commitOrStashBeforeSync': 'Commit or stash your changes before syncing',
|
||||||
|
'gitView.toast.syncedPulledPluralAndPushed': 'Pulled {count} files from {name} and pushed to upstream',
|
||||||
|
'gitView.toast.syncedPulledSingleAndPushed': 'Pulled {count} file from {name} and pushed to upstream',
|
||||||
'gitView.toast.syncedChanges': 'Synced changes',
|
'gitView.toast.syncedChanges': 'Synced changes',
|
||||||
'gitView.toast.rebaseAborted': 'Rebase aborted',
|
'gitView.toast.rebaseAborted': 'Rebase aborted',
|
||||||
'gitView.toast.rebaseConflictsDetected': 'Rebase conflicts detected',
|
'gitView.toast.rebaseConflictsDetected': 'Rebase conflicts detected',
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.sync.push": "Push",
|
"gitView.sync.push": "Push",
|
||||||
"gitView.sync.pushTooltip": "Hacer push",
|
"gitView.sync.pushTooltip": "Hacer push",
|
||||||
"gitView.sync.pushTooltipAhead": "Hacer push ({count} por delante)",
|
"gitView.sync.pushTooltipAhead": "Hacer push ({count} por delante)",
|
||||||
|
"gitView.sync.sync": "sync",
|
||||||
"gitView.sync.syncChanges": "Sync Changes",
|
"gitView.sync.syncChanges": "Sync Changes",
|
||||||
"gitView.sync.syncChangesTooltip": "Sync Changes ({behind} abajo, {ahead} arriba)",
|
"gitView.sync.syncChangesTooltip": "Sync Changes ({behind} abajo, {ahead} arriba)",
|
||||||
"gitView.sync.syncChangesWithCounts": "Sync Changes {behind}↓ {ahead}↑",
|
"gitView.sync.syncChangesWithCounts": "Sync Changes {behind}↓ {ahead}↑",
|
||||||
@@ -706,6 +707,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.toast.pulledFilesSingle": "Se trajo {count} archivo de {name}",
|
"gitView.toast.pulledFilesSingle": "Se trajo {count} archivo de {name}",
|
||||||
"gitView.toast.pushedToUpstream": "Enviado al upstream",
|
"gitView.toast.pushedToUpstream": "Enviado al upstream",
|
||||||
"gitView.toast.commitOrStashBeforeSync": "Haz commit o stash de tus cambios antes de sincronizar",
|
"gitView.toast.commitOrStashBeforeSync": "Haz commit o stash de tus cambios antes de sincronizar",
|
||||||
|
"gitView.toast.syncedPulledPluralAndPushed": "Se trajeron {count} archivos de {name} y se envió al upstream",
|
||||||
|
"gitView.toast.syncedPulledSingleAndPushed": "Se trajo {count} archivo de {name} y se envió al upstream",
|
||||||
"gitView.toast.syncedChanges": "Cambios sincronizados",
|
"gitView.toast.syncedChanges": "Cambios sincronizados",
|
||||||
"gitView.toast.rebaseAborted": "Rebase abortado",
|
"gitView.toast.rebaseAborted": "Rebase abortado",
|
||||||
"gitView.toast.rebaseConflictsDetected": "Se detectaron conflictos al hacer rebase",
|
"gitView.toast.rebaseConflictsDetected": "Se detectaron conflictos al hacer rebase",
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'gitView.sync.push': '푸시',
|
'gitView.sync.push': '푸시',
|
||||||
'gitView.sync.pushTooltip': '변경 사항 푸시',
|
'gitView.sync.pushTooltip': '변경 사항 푸시',
|
||||||
'gitView.sync.pushTooltipAhead': '변경 사항 푸시({count}개 앞섬)',
|
'gitView.sync.pushTooltipAhead': '변경 사항 푸시({count}개 앞섬)',
|
||||||
|
'gitView.sync.sync': 'sync',
|
||||||
'gitView.sync.syncChanges': 'Sync Changes',
|
'gitView.sync.syncChanges': 'Sync Changes',
|
||||||
'gitView.sync.syncChangesTooltip': 'Sync Changes({behind}개 내려받기, {ahead}개 올리기)',
|
'gitView.sync.syncChangesTooltip': 'Sync Changes({behind}개 내려받기, {ahead}개 올리기)',
|
||||||
'gitView.sync.syncChangesWithCounts': 'Sync Changes {behind}↓ {ahead}↑',
|
'gitView.sync.syncChangesWithCounts': 'Sync Changes {behind}↓ {ahead}↑',
|
||||||
@@ -706,6 +707,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'gitView.toast.pulledFilesSingle': '{name}에서 파일 {count}개를 풀했습니다',
|
'gitView.toast.pulledFilesSingle': '{name}에서 파일 {count}개를 풀했습니다',
|
||||||
'gitView.toast.pushedToUpstream': '업스트림에 푸시했습니다',
|
'gitView.toast.pushedToUpstream': '업스트림에 푸시했습니다',
|
||||||
'gitView.toast.commitOrStashBeforeSync': '동기화하기 전에 변경 사항을 커밋하거나 stash하세요',
|
'gitView.toast.commitOrStashBeforeSync': '동기화하기 전에 변경 사항을 커밋하거나 stash하세요',
|
||||||
|
'gitView.toast.syncedPulledPluralAndPushed': '{name}에서 파일 {count}개를 풀하고 업스트림에 푸시했습니다',
|
||||||
|
'gitView.toast.syncedPulledSingleAndPushed': '{name}에서 파일 {count}개를 풀하고 업스트림에 푸시했습니다',
|
||||||
'gitView.toast.syncedChanges': '변경 사항을 동기화했습니다',
|
'gitView.toast.syncedChanges': '변경 사항을 동기화했습니다',
|
||||||
'gitView.toast.rebaseAborted': 'rebase 중단됨',
|
'gitView.toast.rebaseAborted': 'rebase 중단됨',
|
||||||
'gitView.toast.rebaseConflictsDetected': '리베이스 충돌이 감지되었습니다',
|
'gitView.toast.rebaseConflictsDetected': '리베이스 충돌이 감지되었습니다',
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.sync.push": "Push",
|
"gitView.sync.push": "Push",
|
||||||
"gitView.sync.pushTooltip": "Fazer push",
|
"gitView.sync.pushTooltip": "Fazer push",
|
||||||
"gitView.sync.pushTooltipAhead": "Fazer push ({count} por delante)",
|
"gitView.sync.pushTooltipAhead": "Fazer push ({count} por delante)",
|
||||||
|
"gitView.sync.sync": "sync",
|
||||||
"gitView.sync.syncChanges": "Sync Changes",
|
"gitView.sync.syncChanges": "Sync Changes",
|
||||||
"gitView.sync.syncChangesTooltip": "Sync Changes ({behind} abaixo, {ahead} acima)",
|
"gitView.sync.syncChangesTooltip": "Sync Changes ({behind} abaixo, {ahead} acima)",
|
||||||
"gitView.sync.syncChangesWithCounts": "Sync Changes {behind}↓ {ahead}↑",
|
"gitView.sync.syncChangesWithCounts": "Sync Changes {behind}↓ {ahead}↑",
|
||||||
@@ -706,6 +707,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.toast.pulledFilesSingle": "Se trajo {count} arquivo de {name}",
|
"gitView.toast.pulledFilesSingle": "Se trajo {count} arquivo de {name}",
|
||||||
"gitView.toast.pushedToUpstream": "Enviado ao upstream",
|
"gitView.toast.pushedToUpstream": "Enviado ao upstream",
|
||||||
"gitView.toast.commitOrStashBeforeSync": "Faça commit ou stash das alterações antes de sincronizar",
|
"gitView.toast.commitOrStashBeforeSync": "Faça commit ou stash das alterações antes de sincronizar",
|
||||||
|
"gitView.toast.syncedPulledPluralAndPushed": "Foram trazidos {count} arquivos de {name} e enviados ao upstream",
|
||||||
|
"gitView.toast.syncedPulledSingleAndPushed": "Foi trazido {count} arquivo de {name} e enviado ao upstream",
|
||||||
"gitView.toast.syncedChanges": "Alterações sincronizadas",
|
"gitView.toast.syncedChanges": "Alterações sincronizadas",
|
||||||
"gitView.toast.rebaseAborted": "Rebase abortado",
|
"gitView.toast.rebaseAborted": "Rebase abortado",
|
||||||
"gitView.toast.rebaseConflictsDetected": "Se detectaron conflitos ao hacer rebase",
|
"gitView.toast.rebaseConflictsDetected": "Se detectaron conflitos ao hacer rebase",
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.sync.push": "Push",
|
"gitView.sync.push": "Push",
|
||||||
"gitView.sync.pushTooltip": "Push змін",
|
"gitView.sync.pushTooltip": "Push змін",
|
||||||
"gitView.sync.pushTooltipAhead": "Push змін ({count} попереду)",
|
"gitView.sync.pushTooltipAhead": "Push змін ({count} попереду)",
|
||||||
|
"gitView.sync.sync": "sync",
|
||||||
"gitView.sync.syncChanges": "Sync Changes",
|
"gitView.sync.syncChanges": "Sync Changes",
|
||||||
"gitView.sync.syncChangesTooltip": "Sync Changes ({behind} вниз, {ahead} вгору)",
|
"gitView.sync.syncChangesTooltip": "Sync Changes ({behind} вниз, {ahead} вгору)",
|
||||||
"gitView.sync.syncChangesWithCounts": "Sync Changes {behind}↓ {ahead}↑",
|
"gitView.sync.syncChangesWithCounts": "Sync Changes {behind}↓ {ahead}↑",
|
||||||
@@ -706,6 +707,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.toast.pulledFilesSingle": "Отримано файл: {count} з {name}",
|
"gitView.toast.pulledFilesSingle": "Отримано файл: {count} з {name}",
|
||||||
"gitView.toast.pushedToUpstream": "Надіслано в upstream",
|
"gitView.toast.pushedToUpstream": "Надіслано в upstream",
|
||||||
"gitView.toast.commitOrStashBeforeSync": "Закомітьте або сховайте зміни перед синхронізацією",
|
"gitView.toast.commitOrStashBeforeSync": "Закомітьте або сховайте зміни перед синхронізацією",
|
||||||
|
"gitView.toast.syncedPulledPluralAndPushed": "Отримано файлів: {count} з {name} і надіслано в upstream",
|
||||||
|
"gitView.toast.syncedPulledSingleAndPushed": "Отримано файл: {count} з {name} і надіслано в upstream",
|
||||||
"gitView.toast.syncedChanges": "Зміни синхронізовано",
|
"gitView.toast.syncedChanges": "Зміни синхронізовано",
|
||||||
"gitView.toast.rebaseAborted": "Перебазування перервано",
|
"gitView.toast.rebaseAborted": "Перебазування перервано",
|
||||||
"gitView.toast.rebaseConflictsDetected": "Виявлено конфлікти перебазування",
|
"gitView.toast.rebaseConflictsDetected": "Виявлено конфлікти перебазування",
|
||||||
|
|||||||
@@ -558,6 +558,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'gitView.sync.push': '推送',
|
'gitView.sync.push': '推送',
|
||||||
'gitView.sync.pushTooltip': '推送更改',
|
'gitView.sync.pushTooltip': '推送更改',
|
||||||
'gitView.sync.pushTooltipAhead': '推送更改(领先 {count})',
|
'gitView.sync.pushTooltipAhead': '推送更改(领先 {count})',
|
||||||
|
'gitView.sync.sync': 'sync',
|
||||||
'gitView.sync.syncChanges': 'Sync Changes',
|
'gitView.sync.syncChanges': 'Sync Changes',
|
||||||
'gitView.sync.syncChangesTooltip': 'Sync Changes({behind} 下,{ahead} 上)',
|
'gitView.sync.syncChangesTooltip': 'Sync Changes({behind} 下,{ahead} 上)',
|
||||||
'gitView.sync.syncChangesWithCounts': 'Sync Changes {behind}↓ {ahead}↑',
|
'gitView.sync.syncChangesWithCounts': 'Sync Changes {behind}↓ {ahead}↑',
|
||||||
@@ -706,6 +707,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'gitView.toast.pulledFilesSingle': '已从 {name} 拉取 {count} 个文件',
|
'gitView.toast.pulledFilesSingle': '已从 {name} 拉取 {count} 个文件',
|
||||||
'gitView.toast.pushedToUpstream': '已推送到上游',
|
'gitView.toast.pushedToUpstream': '已推送到上游',
|
||||||
'gitView.toast.commitOrStashBeforeSync': '同步前请先提交或储藏你的更改',
|
'gitView.toast.commitOrStashBeforeSync': '同步前请先提交或储藏你的更改',
|
||||||
|
'gitView.toast.syncedPulledPluralAndPushed': '已从 {name} 拉取 {count} 个文件并推送到上游',
|
||||||
|
'gitView.toast.syncedPulledSingleAndPushed': '已从 {name} 拉取 {count} 个文件并推送到上游',
|
||||||
'gitView.toast.syncedChanges': '已同步更改',
|
'gitView.toast.syncedChanges': '已同步更改',
|
||||||
'gitView.toast.rebaseAborted': '变基已中止',
|
'gitView.toast.rebaseAborted': '变基已中止',
|
||||||
'gitView.toast.rebaseConflictsDetected': '检测到变基冲突',
|
'gitView.toast.rebaseConflictsDetected': '检测到变基冲突',
|
||||||
|
|||||||
@@ -2380,6 +2380,7 @@ export async function gitPull(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to raw git
|
// Fallback to raw git
|
||||||
|
const beforeHead = await execGit(['rev-parse', 'HEAD'], directory);
|
||||||
const args = ['pull'];
|
const args = ['pull'];
|
||||||
if (options?.rebase === true) args.push('--rebase');
|
if (options?.rebase === true) args.push('--rebase');
|
||||||
if (options?.remote) args.push(options.remote);
|
if (options?.remote) args.push(options.remote);
|
||||||
@@ -2389,11 +2390,20 @@ export async function gitPull(
|
|||||||
if (result.exitCode !== 0) {
|
if (result.exitCode !== 0) {
|
||||||
throw new Error(result.stderr.trim() || result.stdout.trim() || 'Failed to pull from remote');
|
throw new Error(result.stderr.trim() || result.stdout.trim() || 'Failed to pull from remote');
|
||||||
}
|
}
|
||||||
|
const afterHead = await execGit(['rev-parse', 'HEAD'], directory);
|
||||||
|
const before = beforeHead.exitCode === 0 ? beforeHead.stdout.trim() : '';
|
||||||
|
const after = afterHead.exitCode === 0 ? afterHead.stdout.trim() : '';
|
||||||
|
const changedFiles = before && after && before !== after
|
||||||
|
? await execGit(['diff', '--name-only', before, after], directory)
|
||||||
|
: { stdout: '', stderr: '', exitCode: 0 };
|
||||||
|
const files = changedFiles.exitCode === 0
|
||||||
|
? changedFiles.stdout.split('\n').map((line) => line.trim()).filter(Boolean)
|
||||||
|
: [];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: result.exitCode === 0,
|
success: result.exitCode === 0,
|
||||||
summary: { changes: 0, insertions: 0, deletions: 0 },
|
summary: { changes: files.length, insertions: 0, deletions: 0 },
|
||||||
files: [],
|
files,
|
||||||
insertions: 0,
|
insertions: 0,
|
||||||
deletions: 0,
|
deletions: 0,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user