dsh-ide-git 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/client.js CHANGED
@@ -187,6 +187,54 @@ window.__ModuleLoader__.load({
187
187
  'diff.copy': '复制',
188
188
  'diff.copied': '已复制',
189
189
  'toolbar.refresh': '刷新',
190
+ 'more.sort': '查看和排序',
191
+ 'more.commitGroup': '提交',
192
+ 'more.changesGroup': '更改',
193
+ 'more.pullpushGroup': '拉取,推送',
194
+ 'more.branchGroup': '分支',
195
+ 'more.remoteGroup': '远程',
196
+ 'more.stashGroup': '存储',
197
+ 'more.tagGroup': '标记',
198
+ 'more.commitStaged': '提交已暂存文件...',
199
+ 'more.commitAll': '全部提交...',
200
+ 'more.undoCommit': '撤销上次提交',
201
+ 'more.rebaseAbort': '中止变基',
202
+ 'more.commitStagedAmend': '提交已暂存文件(修改)...',
203
+ 'more.commitAllAmend': '全部提交(修改)...',
204
+ 'more.commitStagedSign': '提交已暂存文件(已签收)...',
205
+ 'more.commitAllSign': '全部提交(已签收)...',
206
+ 'prompt.commitMessage': '提交信息',
207
+ 'more.discardAll': '放弃所有更改...',
208
+ 'more.sync': '同步(拉取并推送)',
209
+ 'more.syncRebase': '同步(变基并推送)',
210
+ 'more.pullRebase': '拉取(变基)',
211
+ 'more.pullFrom': '从远程拉取',
212
+ 'more.pushForce': '推送(强制)...',
213
+ 'more.pushTo': '推送到远程',
214
+ 'more.fetchAll': '从所有远程抓取',
215
+ 'more.deleteRemoteBranch': '删除远程分支...',
216
+ 'more.publish': '发布分支...',
217
+ 'more.addRemote': '添加远程...',
218
+ 'more.removeRemote': '删除远程...',
219
+ 'more.stashTracked': '贮藏(仅已跟踪)',
220
+ 'more.stashStaged': '贮藏已暂存文件',
221
+ 'more.stashApplyPick': '应用贮藏...',
222
+ 'more.stashPopPick': '弹出贮藏...',
223
+ 'more.stashDropAny': '删除贮藏...',
224
+ 'more.stashClear': '删除全部贮藏...',
225
+ 'stash.none': '没有可用的贮藏',
226
+ 'more.tagDeleteRemote': '删除远程标签...',
227
+ 'more.pushTags': '推送标签...',
228
+ 'confirm.undoCommit': '撤销上次提交?提交的改动会保留在暂存区。',
229
+ 'confirm.discardAll': '放弃全部未暂存与未跟踪的更改?可通过撤回浮窗恢复(冲突文件除外)。',
230
+ 'confirm.pushForce': '强制推送会用本地分支覆盖远程(--force-with-lease,他人有新提交时会被拒绝)。继续?',
231
+ 'confirm.deleteRemoteBranch': '删除远程 {remote} 上的分支 {branch}?',
232
+ 'confirm.remoteRemove': '删除远程 {name}?其跟踪配置一并移除。',
233
+ 'confirm.stashClear': '删除全部贮藏?此操作不可撤回。',
234
+ 'confirm.pushTags': '推送全部标签到 {remote}?',
235
+ 'prompt.remoteName': '远程名称',
236
+ 'prompt.remoteUrl': '远程 URL',
237
+ 'prompt.deleteRemoteTag': '要删除的远程标签(将推送到 {remote})',
190
238
  'toolbar.more': '更多操作',
191
239
  'more.sortGit': 'Git 顺序',
192
240
  'more.sortPath': '按路径',
@@ -428,6 +476,54 @@ window.__ModuleLoader__.load({
428
476
  'diff.copy': 'Copy',
429
477
  'diff.copied': 'Copied',
430
478
  'toolbar.refresh': 'Refresh',
479
+ 'more.sort': 'View & Sort',
480
+ 'more.commitGroup': 'Commit',
481
+ 'more.changesGroup': 'Changes',
482
+ 'more.pullpushGroup': 'Pull, Push',
483
+ 'more.branchGroup': 'Branch',
484
+ 'more.remoteGroup': 'Remote',
485
+ 'more.stashGroup': 'Stash',
486
+ 'more.tagGroup': 'Tags',
487
+ 'more.commitStaged': 'Commit Staged...',
488
+ 'more.commitAll': 'Commit All...',
489
+ 'more.undoCommit': 'Undo Last Commit',
490
+ 'more.rebaseAbort': 'Abort Rebase',
491
+ 'more.commitStagedAmend': 'Commit Staged (Amend)...',
492
+ 'more.commitAllAmend': 'Commit All (Amend)...',
493
+ 'more.commitStagedSign': 'Commit Staged (Signed Off)...',
494
+ 'more.commitAllSign': 'Commit All (Signed Off)...',
495
+ 'prompt.commitMessage': 'Commit message',
496
+ 'more.discardAll': 'Discard All Changes...',
497
+ 'more.sync': 'Sync (Pull then Push)',
498
+ 'more.syncRebase': 'Sync (Rebase then Push)',
499
+ 'more.pullRebase': 'Pull (Rebase)',
500
+ 'more.pullFrom': 'Pull from Remote',
501
+ 'more.pushForce': 'Push (Force)...',
502
+ 'more.pushTo': 'Push to Remote',
503
+ 'more.fetchAll': 'Fetch from All Remotes',
504
+ 'more.deleteRemoteBranch': 'Delete Remote Branch...',
505
+ 'more.publish': 'Publish Branch...',
506
+ 'more.addRemote': 'Add Remote...',
507
+ 'more.removeRemote': 'Remove Remote...',
508
+ 'more.stashTracked': 'Stash (Tracked Only)',
509
+ 'more.stashStaged': 'Stash Staged',
510
+ 'more.stashApplyPick': 'Apply Stash...',
511
+ 'more.stashPopPick': 'Pop Stash...',
512
+ 'more.stashDropAny': 'Drop Stash...',
513
+ 'more.stashClear': 'Drop All Stashes...',
514
+ 'stash.none': 'No stashes available',
515
+ 'more.tagDeleteRemote': 'Delete Remote Tag...',
516
+ 'more.pushTags': 'Push Tags...',
517
+ 'confirm.undoCommit': 'Undo the last commit? Its changes stay staged.',
518
+ 'confirm.discardAll': 'Discard ALL unstaged and untracked changes? Recoverable via undo toasts (conflicted files excluded).',
519
+ 'confirm.pushForce': 'Force push overwrites the remote with this branch (--force-with-lease refuses when others pushed). Continue?',
520
+ 'confirm.deleteRemoteBranch': 'Delete branch {branch} on {remote}?',
521
+ 'confirm.remoteRemove': 'Remove remote {name}? Its tracking config goes with it.',
522
+ 'confirm.stashClear': 'Drop ALL stashes? This cannot be undone.',
523
+ 'confirm.pushTags': 'Push all tags to {remote}?',
524
+ 'prompt.remoteName': 'Remote name',
525
+ 'prompt.remoteUrl': 'Remote URL',
526
+ 'prompt.deleteRemoteTag': 'Remote tag to delete (pushed to {remote})',
431
527
  'toolbar.more': 'More actions',
432
528
  'more.sortGit': 'Git order',
433
529
  'more.sortPath': 'By path',
@@ -677,6 +773,54 @@ window.__ModuleLoader__.load({
677
773
  'diff.copy': '複製',
678
774
  'diff.copied': '已複製',
679
775
  'toolbar.refresh': '重新整理',
776
+ 'more.sort': '查看和排序',
777
+ 'more.commitGroup': '提交',
778
+ 'more.changesGroup': '更改',
779
+ 'more.pullpushGroup': '拉取,推送',
780
+ 'more.branchGroup': '分支',
781
+ 'more.remoteGroup': '遠端',
782
+ 'more.stashGroup': '儲存',
783
+ 'more.tagGroup': '標籤',
784
+ 'more.commitStaged': '提交已暫存檔案...',
785
+ 'more.commitAll': '全部提交...',
786
+ 'more.undoCommit': '撤銷上次提交',
787
+ 'more.rebaseAbort': '中止變基',
788
+ 'more.commitStagedAmend': '提交已暫存檔案(修改)...',
789
+ 'more.commitAllAmend': '全部提交(修改)...',
790
+ 'more.commitStagedSign': '提交已暫存檔案(已簽收)...',
791
+ 'more.commitAllSign': '全部提交(已簽收)...',
792
+ 'prompt.commitMessage': '提交資訊',
793
+ 'more.discardAll': '放棄所有變更...',
794
+ 'more.sync': '同步(拉取並推送)',
795
+ 'more.syncRebase': '同步(變基並推送)',
796
+ 'more.pullRebase': '拉取(變基)',
797
+ 'more.pullFrom': '從遠端拉取',
798
+ 'more.pushForce': '推送(強制)...',
799
+ 'more.pushTo': '推送到遠端',
800
+ 'more.fetchAll': '從所有遠端抓取',
801
+ 'more.deleteRemoteBranch': '刪除遠端分支...',
802
+ 'more.publish': '發布分支...',
803
+ 'more.addRemote': '新增遠端...',
804
+ 'more.removeRemote': '刪除遠端...',
805
+ 'more.stashTracked': '儲存(僅已追蹤)',
806
+ 'more.stashStaged': '儲存已暫存檔案',
807
+ 'more.stashApplyPick': '套用儲存...',
808
+ 'more.stashPopPick': '彈出儲存...',
809
+ 'more.stashDropAny': '刪除儲存...',
810
+ 'more.stashClear': '刪除全部儲存...',
811
+ 'stash.none': '沒有可用的儲存',
812
+ 'more.tagDeleteRemote': '刪除遠端標籤...',
813
+ 'more.pushTags': '推送標籤...',
814
+ 'confirm.undoCommit': '撤銷上次提交?提交的變更會保留在暫存區。',
815
+ 'confirm.discardAll': '放棄全部未暫存與未追蹤的變更?可透過復原浮窗恢復(衝突檔案除外)。',
816
+ 'confirm.pushForce': '強制推送會以本地分支覆寫遠端(--force-with-lease,他人有新提交時會被拒絕)。繼續?',
817
+ 'confirm.deleteRemoteBranch': '刪除遠端 {remote} 上的分支 {branch}?',
818
+ 'confirm.remoteRemove': '刪除遠端 {name}?其追蹤設定一併移除。',
819
+ 'confirm.stashClear': '刪除全部儲存?此操作不可復原。',
820
+ 'confirm.pushTags': '推送全部標籤到 {remote}?',
821
+ 'prompt.remoteName': '遠端名稱',
822
+ 'prompt.remoteUrl': '遠端 URL',
823
+ 'prompt.deleteRemoteTag': '要刪除的遠端標籤(將推送到 {remote})',
680
824
  'toolbar.more': '更多操作',
681
825
  'more.sortGit': 'Git 順序',
682
826
  'more.sortPath': '按路徑',
@@ -918,6 +1062,54 @@ window.__ModuleLoader__.load({
918
1062
  'diff.copy': '複製',
919
1063
  'diff.copied': '已複製',
920
1064
  'toolbar.refresh': '重新整理',
1065
+ 'more.sort': '查看和排序',
1066
+ 'more.commitGroup': '提交',
1067
+ 'more.changesGroup': '變更',
1068
+ 'more.pullpushGroup': '拉取,推送',
1069
+ 'more.branchGroup': '分支',
1070
+ 'more.remoteGroup': '遠端',
1071
+ 'more.stashGroup': '擱置',
1072
+ 'more.tagGroup': '標籤',
1073
+ 'more.commitStaged': '提交已暫存檔案...',
1074
+ 'more.commitAll': '全部提交...',
1075
+ 'more.undoCommit': '復原上次提交',
1076
+ 'more.rebaseAbort': '中止變基',
1077
+ 'more.commitStagedAmend': '提交已暫存檔案(修改)...',
1078
+ 'more.commitAllAmend': '全部提交(修改)...',
1079
+ 'more.commitStagedSign': '提交已暫存檔案(已簽核)...',
1080
+ 'more.commitAllSign': '全部提交(已簽核)...',
1081
+ 'prompt.commitMessage': '提交資訊',
1082
+ 'more.discardAll': '捨棄所有變更...',
1083
+ 'more.sync': '同步(拉取並推送)',
1084
+ 'more.syncRebase': '同步(變基並推送)',
1085
+ 'more.pullRebase': '拉取(變基)',
1086
+ 'more.pullFrom': '從遠端拉取',
1087
+ 'more.pushForce': '推送(強制)...',
1088
+ 'more.pushTo': '推送到遠端',
1089
+ 'more.fetchAll': '從所有遠端擷取',
1090
+ 'more.deleteRemoteBranch': '刪除遠端分支...',
1091
+ 'more.publish': '發佈分支...',
1092
+ 'more.addRemote': '新增遠端...',
1093
+ 'more.removeRemote': '移除遠端...',
1094
+ 'more.stashTracked': '擱置(僅已追蹤)',
1095
+ 'more.stashStaged': '擱置已暫存檔案',
1096
+ 'more.stashApplyPick': '套用擱置...',
1097
+ 'more.stashPopPick': '取出擱置...',
1098
+ 'more.stashDropAny': '刪除擱置...',
1099
+ 'more.stashClear': '刪除全部擱置...',
1100
+ 'stash.none': '沒有可用的擱置',
1101
+ 'more.tagDeleteRemote': '刪除遠端標籤...',
1102
+ 'more.pushTags': '推送標籤...',
1103
+ 'confirm.undoCommit': '復原上次提交?提交的變更會保留在暫存區。',
1104
+ 'confirm.discardAll': '捨棄全部未暫存與未追蹤的變更?可透過復原浮窗復原(衝突檔案除外)。',
1105
+ 'confirm.pushForce': '強制推送會以本地分支覆寫遠端(--force-with-lease,他人有新提交時會被拒絕)。繼續?',
1106
+ 'confirm.deleteRemoteBranch': '刪除遠端 {remote} 上的分支 {branch}?',
1107
+ 'confirm.remoteRemove': '移除遠端 {name}?其追蹤設定一併移除。',
1108
+ 'confirm.stashClear': '刪除全部擱置?此作業無法復原。',
1109
+ 'confirm.pushTags': '推送全部標籤到 {remote}?',
1110
+ 'prompt.remoteName': '遠端名稱',
1111
+ 'prompt.remoteUrl': '遠端 URL',
1112
+ 'prompt.deleteRemoteTag': '要刪除的遠端標籤(將推送至 {remote})',
921
1113
  'toolbar.more': '更多操作',
922
1114
  'more.sortGit': 'Git 順序',
923
1115
  'more.sortPath': '按路徑',
@@ -1159,6 +1351,54 @@ window.__ModuleLoader__.load({
1159
1351
  'diff.copy': '複製',
1160
1352
  'diff.copied': '已複製',
1161
1353
  'toolbar.refresh': '重新整理',
1354
+ 'more.sort': '查看和排序',
1355
+ 'more.commitGroup': '提交',
1356
+ 'more.changesGroup': '更改',
1357
+ 'more.pullpushGroup': '拉取,推送',
1358
+ 'more.branchGroup': '分支',
1359
+ 'more.remoteGroup': '遠端',
1360
+ 'more.stashGroup': '儲存',
1361
+ 'more.tagGroup': '標籤',
1362
+ 'more.commitStaged': '提交已暫存檔案...',
1363
+ 'more.commitAll': '全部提交...',
1364
+ 'more.undoCommit': '撤銷上次提交',
1365
+ 'more.rebaseAbort': '中止變基',
1366
+ 'more.commitStagedAmend': '提交已暫存檔案(修改)...',
1367
+ 'more.commitAllAmend': '全部提交(修改)...',
1368
+ 'more.commitStagedSign': '提交已暫存檔案(已簽收)...',
1369
+ 'more.commitAllSign': '全部提交(已簽收)...',
1370
+ 'prompt.commitMessage': '提交資訊',
1371
+ 'more.discardAll': '放棄所有變更...',
1372
+ 'more.sync': '同步(拉取並推送)',
1373
+ 'more.syncRebase': '同步(變基並推送)',
1374
+ 'more.pullRebase': '拉取(變基)',
1375
+ 'more.pullFrom': '從遠端拉取',
1376
+ 'more.pushForce': '推送(強制)...',
1377
+ 'more.pushTo': '推送到遠端',
1378
+ 'more.fetchAll': '從所有遠端抓取',
1379
+ 'more.deleteRemoteBranch': '刪除遠端分支...',
1380
+ 'more.publish': '發布分支...',
1381
+ 'more.addRemote': '新增遠端...',
1382
+ 'more.removeRemote': '刪除遠端...',
1383
+ 'more.stashTracked': '儲存(僅已追蹤)',
1384
+ 'more.stashStaged': '儲存已暫存檔案',
1385
+ 'more.stashApplyPick': '套用儲存...',
1386
+ 'more.stashPopPick': '彈出儲存...',
1387
+ 'more.stashDropAny': '刪除儲存...',
1388
+ 'more.stashClear': '刪除全部儲存...',
1389
+ 'stash.none': '沒有可用的儲存',
1390
+ 'more.tagDeleteRemote': '刪除遠端標籤...',
1391
+ 'more.pushTags': '推送標籤...',
1392
+ 'confirm.undoCommit': '撤銷上次提交?提交的變更會保留在暫存區。',
1393
+ 'confirm.discardAll': '放棄全部未暫存與未追蹤的變更?可透過復原浮窗恢復(衝突檔案除外)。',
1394
+ 'confirm.pushForce': '強制推送會以本地分支覆寫遠端(--force-with-lease,他人有新提交時會被拒絕)。繼續?',
1395
+ 'confirm.deleteRemoteBranch': '刪除遠端 {remote} 上的分支 {branch}?',
1396
+ 'confirm.remoteRemove': '刪除遠端 {name}?其追蹤設定一併移除。',
1397
+ 'confirm.stashClear': '刪除全部儲存?此操作不可復原。',
1398
+ 'confirm.pushTags': '推送全部標籤到 {remote}?',
1399
+ 'prompt.remoteName': '遠端名稱',
1400
+ 'prompt.remoteUrl': '遠端 URL',
1401
+ 'prompt.deleteRemoteTag': '要刪除的遠端標籤(將推送到 {remote})',
1162
1402
  'toolbar.more': '更多操作',
1163
1403
  'more.sortGit': 'Git 順序',
1164
1404
  'more.sortPath': '按路徑',
@@ -1400,6 +1640,54 @@ window.__ModuleLoader__.load({
1400
1640
  'diff.copy': 'コピー',
1401
1641
  'diff.copied': 'コピーしました',
1402
1642
  'toolbar.refresh': '更新',
1643
+ 'more.sort': '表示と並べ替え',
1644
+ 'more.commitGroup': 'コミット',
1645
+ 'more.changesGroup': '変更',
1646
+ 'more.pullpushGroup': 'プル,プッシュ',
1647
+ 'more.branchGroup': 'ブランチ',
1648
+ 'more.remoteGroup': 'リモート',
1649
+ 'more.stashGroup': 'スタッシュ',
1650
+ 'more.tagGroup': 'タグ',
1651
+ 'more.commitStaged': 'ステージ済みをコミット...',
1652
+ 'more.commitAll': 'すべてコミット...',
1653
+ 'more.undoCommit': '最後のコミットを取り消す',
1654
+ 'more.rebaseAbort': 'リベースを中止',
1655
+ 'more.commitStagedAmend': 'ステージ済みをコミット(修正)...',
1656
+ 'more.commitAllAmend': 'すべてコミット(修正)...',
1657
+ 'more.commitStagedSign': 'ステージ済みをコミット(署名)...',
1658
+ 'more.commitAllSign': 'すべてコミット(署名)...',
1659
+ 'prompt.commitMessage': 'コミットメッセージ',
1660
+ 'more.discardAll': 'すべての変更を破棄...',
1661
+ 'more.sync': '同期(プルしてプッシュ)',
1662
+ 'more.syncRebase': '同期(リベースしてプッシュ)',
1663
+ 'more.pullRebase': 'プル(リベース)',
1664
+ 'more.pullFrom': 'リモートからプル',
1665
+ 'more.pushForce': '強制プッシュ...',
1666
+ 'more.pushTo': 'リモートへプッシュ',
1667
+ 'more.fetchAll': '全リモートからフェッチ',
1668
+ 'more.deleteRemoteBranch': 'リモートブランチを削除...',
1669
+ 'more.publish': 'ブランチを公開...',
1670
+ 'more.addRemote': 'リモートを追加...',
1671
+ 'more.removeRemote': 'リモートを削除...',
1672
+ 'more.stashTracked': 'スタッシュ(追跡済みのみ)',
1673
+ 'more.stashStaged': 'ステージ済みをスタッシュ',
1674
+ 'more.stashApplyPick': 'スタッシュを適用...',
1675
+ 'more.stashPopPick': 'スタッシュをポップ...',
1676
+ 'more.stashDropAny': 'スタッシュを削除...',
1677
+ 'more.stashClear': 'すべてのスタッシュを削除...',
1678
+ 'stash.none': '利用可能なスタッシュはありません',
1679
+ 'more.tagDeleteRemote': 'リモートタグを削除...',
1680
+ 'more.pushTags': 'タグをプッシュ...',
1681
+ 'confirm.undoCommit': '最後のコミットを取り消しますか?変更はステージに残ります。',
1682
+ 'confirm.discardAll': 'ステージ外と未追跡のすべての変更を破棄しますか?元に戻すトーストで復元できます(競合ファイルを除く)。',
1683
+ 'confirm.pushForce': '強制プッシュはリモートをこのブランチで上書きします(--force-with-lease により他者の更新時は拒否)。続行しますか?',
1684
+ 'confirm.deleteRemoteBranch': '{remote} のブランチ {branch} を削除しますか?',
1685
+ 'confirm.remoteRemove': 'リモート {name} を削除しますか?追跡設定も削除されます。',
1686
+ 'confirm.stashClear': 'すべてのスタッシュを削除しますか?この操作は元に戻せません。',
1687
+ 'confirm.pushTags': 'すべてのタグを {remote} にプッシュしますか?',
1688
+ 'prompt.remoteName': 'リモート名',
1689
+ 'prompt.remoteUrl': 'リモート URL',
1690
+ 'prompt.deleteRemoteTag': '削除するリモートタグ({remote} にプッシュ)',
1403
1691
  'toolbar.more': 'その他の操作',
1404
1692
  'more.sortGit': 'Git の順序',
1405
1693
  'more.sortPath': 'パス順',
@@ -1641,6 +1929,54 @@ window.__ModuleLoader__.load({
1641
1929
  'diff.copy': '복사',
1642
1930
  'diff.copied': '복사됨',
1643
1931
  'toolbar.refresh': '새로 고침',
1932
+ 'more.sort': '보기 및 정렬',
1933
+ 'more.commitGroup': '커밋',
1934
+ 'more.changesGroup': '변경',
1935
+ 'more.pullpushGroup': '풀, 푸시',
1936
+ 'more.branchGroup': '브랜치',
1937
+ 'more.remoteGroup': '원격',
1938
+ 'more.stashGroup': '스태시',
1939
+ 'more.tagGroup': '태그',
1940
+ 'more.commitStaged': '스테이지된 파일 커밋...',
1941
+ 'more.commitAll': '모두 커밋...',
1942
+ 'more.undoCommit': '마지막 커밋 취소',
1943
+ 'more.rebaseAbort': '리베이스 중단',
1944
+ 'more.commitStagedAmend': '스테이지된 파일 커밋(수정)...',
1945
+ 'more.commitAllAmend': '모두 커밋(수정)...',
1946
+ 'more.commitStagedSign': '스테이지된 파일 커밋(서명)...',
1947
+ 'more.commitAllSign': '모두 커밋(서명)...',
1948
+ 'prompt.commitMessage': '커밋 메시지',
1949
+ 'more.discardAll': '모든 변경 내용 취소...',
1950
+ 'more.sync': '동기화(풀 후 푸시)',
1951
+ 'more.syncRebase': '동기화(리베이스 후 푸시)',
1952
+ 'more.pullRebase': '풀(리베이스)',
1953
+ 'more.pullFrom': '원격에서 풀',
1954
+ 'more.pushForce': '강제 푸시...',
1955
+ 'more.pushTo': '원격으로 푸시',
1956
+ 'more.fetchAll': '모든 원격에서 페치',
1957
+ 'more.deleteRemoteBranch': '원격 브랜치 삭제...',
1958
+ 'more.publish': '브랜치 게시...',
1959
+ 'more.addRemote': '원격 추가...',
1960
+ 'more.removeRemote': '원격 제거...',
1961
+ 'more.stashTracked': '스태시(추적된 파일만)',
1962
+ 'more.stashStaged': '스테이지된 파일 스태시',
1963
+ 'more.stashApplyPick': '스태시 적용...',
1964
+ 'more.stashPopPick': '스태시 팝...',
1965
+ 'more.stashDropAny': '스태시 삭제...',
1966
+ 'more.stashClear': '모든 스태시 삭제...',
1967
+ 'stash.none': '사용 가능한 스태시가 없습니다',
1968
+ 'more.tagDeleteRemote': '원격 태그 삭제...',
1969
+ 'more.pushTags': '태그 푸시...',
1970
+ 'confirm.undoCommit': '마지막 커밋을 취소할까요?변경 사항은 스테이지에 유지됩니다.',
1971
+ 'confirm.discardAll': '스테이지되지 않은 모든 변경과 추적되지 않는 파일을 취소할까요?실행 취소 토스트로 복구할 수 있습니다(충돌 파일 제외).',
1972
+ 'confirm.pushForce': '강제 푸시는 원격을 이 브랜치로 덮어씁니다(--force-with-lease, 다른 사람이 푸시했으면 거부됨).계속할까요?',
1973
+ 'confirm.deleteRemoteBranch': '{remote}의 브랜치 {branch}를 삭제할까요?',
1974
+ 'confirm.remoteRemove': '원격 {name}을(를) 제거할까요?추적 설정도 함께 제거됩니다.',
1975
+ 'confirm.stashClear': '모든 스태시를 삭제할까요?이 작업은 되돌릴 수 없습니다.',
1976
+ 'confirm.pushTags': '모든 태그를 {remote}에 푸시할까요?',
1977
+ 'prompt.remoteName': '원격 이름',
1978
+ 'prompt.remoteUrl': '원격 URL',
1979
+ 'prompt.deleteRemoteTag': '삭제할 원격 태그({remote}로 푸시됨)',
1644
1980
  'toolbar.more': '더 보기',
1645
1981
  'more.sortGit': 'Git 순서',
1646
1982
  'more.sortPath': '경로순',
@@ -1882,6 +2218,54 @@ window.__ModuleLoader__.load({
1882
2218
  'diff.copy': 'Kopieren',
1883
2219
  'diff.copied': 'Kopiert',
1884
2220
  'toolbar.refresh': 'Aktualisieren',
2221
+ 'more.sort': 'Anzeigen & Sortieren',
2222
+ 'more.commitGroup': 'Commit',
2223
+ 'more.changesGroup': 'Änderungen',
2224
+ 'more.pullpushGroup': 'Pull, Push',
2225
+ 'more.branchGroup': 'Branch',
2226
+ 'more.remoteGroup': 'Remote',
2227
+ 'more.stashGroup': 'Stash',
2228
+ 'more.tagGroup': 'Tags',
2229
+ 'more.commitStaged': 'Staged committen...',
2230
+ 'more.commitAll': 'Alles committen...',
2231
+ 'more.undoCommit': 'Letzten Commit zurücknehmen',
2232
+ 'more.rebaseAbort': 'Rebase abbrechen',
2233
+ 'more.commitStagedAmend': 'Staged committen (Amend)...',
2234
+ 'more.commitAllAmend': 'Alles committen (Amend)...',
2235
+ 'more.commitStagedSign': 'Staged committen (Signed Off)...',
2236
+ 'more.commitAllSign': 'Alles committen (Signed Off)...',
2237
+ 'prompt.commitMessage': 'Commit-Nachricht',
2238
+ 'more.discardAll': 'Alle Änderungen verwerfen...',
2239
+ 'more.sync': 'Synchronisieren (Pull, dann Push)',
2240
+ 'more.syncRebase': 'Synchronisieren (Rebase, dann Push)',
2241
+ 'more.pullRebase': 'Pull (Rebase)',
2242
+ 'more.pullFrom': 'Von Remote pullen',
2243
+ 'more.pushForce': 'Push (Erzwingen)...',
2244
+ 'more.pushTo': 'Auf Remote pushen',
2245
+ 'more.fetchAll': 'Von allen Remotes holen',
2246
+ 'more.deleteRemoteBranch': 'Remote-Branch löschen...',
2247
+ 'more.publish': 'Branch veröffentlichen...',
2248
+ 'more.addRemote': 'Remote hinzufügen...',
2249
+ 'more.removeRemote': 'Remote entfernen...',
2250
+ 'more.stashTracked': 'Stash (nur getrackt)',
2251
+ 'more.stashStaged': 'Staged stashed',
2252
+ 'more.stashApplyPick': 'Stash anwenden...',
2253
+ 'more.stashPopPick': 'Stash poppen...',
2254
+ 'more.stashDropAny': 'Stash löschen...',
2255
+ 'more.stashClear': 'Alle Stashes löschen...',
2256
+ 'stash.none': 'Keine Stashes vorhanden',
2257
+ 'more.tagDeleteRemote': 'Remote-Tag löschen...',
2258
+ 'more.pushTags': 'Tags pushen...',
2259
+ 'confirm.undoCommit': 'Letzten Commit zurücknehmen? Die Änderungen bleiben gestaged.',
2260
+ 'confirm.discardAll': 'ALLE ungestageden und ungetrackten Änderungen verwerfen? Über Undo-Toasts wiederherstellbar (Konfliktdateien ausgenommen).',
2261
+ 'confirm.pushForce': 'Force-Push überschreibt das Remote mit diesem Branch (--force-with-lease lehnt ab, wenn andere gepusht haben). Fortfahren?',
2262
+ 'confirm.deleteRemoteBranch': 'Branch {branch} auf {remote} löschen?',
2263
+ 'confirm.remoteRemove': 'Remote {name} entfernen? Die Tracking-Konfiguration wird mitentfernt.',
2264
+ 'confirm.stashClear': 'ALLE Stashes löschen? Das kann nicht rückgängig gemacht werden.',
2265
+ 'confirm.pushTags': 'Alle Tags auf {remote} pushen?',
2266
+ 'prompt.remoteName': 'Remote-Name',
2267
+ 'prompt.remoteUrl': 'Remote-URL',
2268
+ 'prompt.deleteRemoteTag': 'Zu löschendes Remote-Tag (wird nach {remote} gepusht)',
1885
2269
  'toolbar.more': 'Weitere Aktionen',
1886
2270
  'more.sortGit': 'Git-Reihenfolge',
1887
2271
  'more.sortPath': 'Nach Pfad',
@@ -2123,6 +2507,54 @@ window.__ModuleLoader__.load({
2123
2507
  'diff.copy': 'Copier',
2124
2508
  'diff.copied': 'Copié',
2125
2509
  'toolbar.refresh': 'Rafraîchir',
2510
+ 'more.sort': 'Afficher & trier',
2511
+ 'more.commitGroup': 'Commit',
2512
+ 'more.changesGroup': 'Modifications',
2513
+ 'more.pullpushGroup': 'Pull, Push',
2514
+ 'more.branchGroup': 'Branche',
2515
+ 'more.remoteGroup': 'Distant',
2516
+ 'more.stashGroup': 'Remisage',
2517
+ 'more.tagGroup': 'Étiquettes',
2518
+ 'more.commitStaged': 'Commit des fichiers indexés...',
2519
+ 'more.commitAll': 'Tout committer...',
2520
+ 'more.undoCommit': 'Annuler le dernier commit',
2521
+ 'more.rebaseAbort': 'Abandonner le rebase',
2522
+ 'more.commitStagedAmend': 'Commit indexé (Amend)...',
2523
+ 'more.commitAllAmend': 'Tout committer (Amend)...',
2524
+ 'more.commitStagedSign': 'Commit indexé (Signé)...',
2525
+ 'more.commitAllSign': 'Tout committer (Signé)...',
2526
+ 'prompt.commitMessage': 'Message de commit',
2527
+ 'more.discardAll': 'Abandonner toutes les modifications...',
2528
+ 'more.sync': 'Synchroniser (pull puis push)',
2529
+ 'more.syncRebase': 'Synchroniser (rebase puis push)',
2530
+ 'more.pullRebase': 'Pull (Rebase)',
2531
+ 'more.pullFrom': 'Pull depuis un dépôt distant',
2532
+ 'more.pushForce': 'Push (Forcer)...',
2533
+ 'more.pushTo': 'Push vers un distant',
2534
+ 'more.fetchAll': 'Récupérer de tous les distants',
2535
+ 'more.deleteRemoteBranch': 'Supprimer la branche distante...',
2536
+ 'more.publish': 'Publier la branche...',
2537
+ 'more.addRemote': 'Ajouter un distant...',
2538
+ 'more.removeRemote': 'Supprimer le distant...',
2539
+ 'more.stashTracked': 'Remisage (suivis seulement)',
2540
+ 'more.stashStaged': 'Remiser les fichiers indexés',
2541
+ 'more.stashApplyPick': 'Appliquer un remisage...',
2542
+ 'more.stashPopPick': 'Dépiler un remisage...',
2543
+ 'more.stashDropAny': 'Supprimer un remisage...',
2544
+ 'more.stashClear': 'Supprimer tous les remisages...',
2545
+ 'stash.none': 'Aucun remisage disponible',
2546
+ 'more.tagDeleteRemote': 'Supprimer l\'étiquette distante...',
2547
+ 'more.pushTags': 'Pousser les étiquettes...',
2548
+ 'confirm.undoCommit': 'Annuler le dernier commit ? Ses modifications restent indexées.',
2549
+ 'confirm.discardAll': 'Abandonner TOUTES les modifications non indexées et non suivies ? Récupérable via les toasts d\'annulation (fichiers en conflit exclus).',
2550
+ 'confirm.pushForce': 'Le forçage du push écrasera le distant avec cette branche (--force-with-lease refuse si d\'autres ont poussé). Continuer ?',
2551
+ 'confirm.deleteRemoteBranch': 'Supprimer la branche {branch} sur {remote} ?',
2552
+ 'confirm.remoteRemove': 'Supprimer le distant {name} ? Sa configuration de suivi part avec lui.',
2553
+ 'confirm.stashClear': 'Supprimer TOUS les remisages ? Irréversible.',
2554
+ 'confirm.pushTags': 'Pousser toutes les étiquettes vers {remote} ?',
2555
+ 'prompt.remoteName': 'Nom du distant',
2556
+ 'prompt.remoteUrl': 'URL du distant',
2557
+ 'prompt.deleteRemoteTag': 'Étiquette distante à supprimer (poussée vers {remote})',
2126
2558
  'toolbar.more': 'Actions supplémentaires',
2127
2559
  'more.sortGit': 'Ordre Git',
2128
2560
  'more.sortPath': 'Par chemin',
@@ -2364,6 +2796,54 @@ window.__ModuleLoader__.load({
2364
2796
  'diff.copy': 'Копировать',
2365
2797
  'diff.copied': 'Скопировано',
2366
2798
  'toolbar.refresh': 'Обновить',
2799
+ 'more.sort': 'Просмотр и сортировка',
2800
+ 'more.commitGroup': 'Фиксация',
2801
+ 'more.changesGroup': 'Изменения',
2802
+ 'more.pullpushGroup': 'Изъять, отправить',
2803
+ 'more.branchGroup': 'Ветвь',
2804
+ 'more.remoteGroup': 'Сервер',
2805
+ 'more.stashGroup': 'Отложить',
2806
+ 'more.tagGroup': 'Метки',
2807
+ 'more.commitStaged': 'Фиксация индексированного...',
2808
+ 'more.commitAll': 'Фиксация всего...',
2809
+ 'more.undoCommit': 'Отменить последнюю фиксацию',
2810
+ 'more.rebaseAbort': 'Прервать перебазирование',
2811
+ 'more.commitStagedAmend': 'Фиксация индексированного (Amend)...',
2812
+ 'more.commitAllAmend': 'Фиксация всего (Amend)...',
2813
+ 'more.commitStagedSign': 'Фиксация индексированного (С подписью)...',
2814
+ 'more.commitAllSign': 'Фиксация всего (С подписью)...',
2815
+ 'prompt.commitMessage': 'Сообщение фиксации',
2816
+ 'more.discardAll': 'Отменить все изменения...',
2817
+ 'more.sync': 'Синхронизировать (изъять, затем отправить)',
2818
+ 'more.syncRebase': 'Синхронизировать (перебазировать, затем отправить)',
2819
+ 'more.pullRebase': 'Изъять (перебазирование)',
2820
+ 'more.pullFrom': 'Изъять с сервера',
2821
+ 'more.pushForce': 'Отправить (принудительно)...',
2822
+ 'more.pushTo': 'Отправить на сервер',
2823
+ 'more.fetchAll': 'Изъять со всех серверов',
2824
+ 'more.deleteRemoteBranch': 'Удалить ветвь на сервере...',
2825
+ 'more.publish': 'Опубликовать ветвь...',
2826
+ 'more.addRemote': 'Добавить сервер...',
2827
+ 'more.removeRemote': 'Удалить сервер...',
2828
+ 'more.stashTracked': 'Отложить (только отслеживаемое)',
2829
+ 'more.stashStaged': 'Отложить индексированное',
2830
+ 'more.stashApplyPick': 'Применить отложенное...',
2831
+ 'more.stashPopPick': 'Снять отложенное...',
2832
+ 'more.stashDropAny': 'Удалить отложенное...',
2833
+ 'more.stashClear': 'Удалить всё отложенное...',
2834
+ 'stash.none': 'Нет отложенных изменений',
2835
+ 'more.tagDeleteRemote': 'Удалить метку на сервере...',
2836
+ 'more.pushTags': 'Отправить метки...',
2837
+ 'confirm.undoCommit': 'Отменить последнюю фиксацию? Её изменения останутся в индексе.',
2838
+ 'confirm.discardAll': 'Отменить ВСЕ непроиндексированные и неотслеживаемые изменения? Можно восстановить через уведомления (кроме конфликтных файлов).',
2839
+ 'confirm.pushForce': 'Принудительная отправка перезапишет сервер этой ветвью (--force-with-lease отклонит при чужих отправках). Продолжить?',
2840
+ 'confirm.deleteRemoteBranch': 'Удалить ветвь {branch} на {remote}?',
2841
+ 'confirm.remoteRemove': 'Удалить сервер {name}? Конфигурация отслеживания будет удалена.',
2842
+ 'confirm.stashClear': 'Удалить ВСЁ отложенное? Это необратимо.',
2843
+ 'confirm.pushTags': 'Отправить все метки на {remote}?',
2844
+ 'prompt.remoteName': 'Имя сервера',
2845
+ 'prompt.remoteUrl': 'URL сервера',
2846
+ 'prompt.deleteRemoteTag': 'Метка для удаления (будет удалена с {remote})',
2367
2847
  'toolbar.more': 'Дополнительные действия',
2368
2848
  'more.sortGit': 'Порядок Git',
2369
2849
  'more.sortPath': 'По пути',
@@ -2605,6 +3085,54 @@ window.__ModuleLoader__.load({
2605
3085
  'diff.copy': 'Copiar',
2606
3086
  'diff.copied': 'Copiado',
2607
3087
  'toolbar.refresh': 'Atualizar',
3088
+ 'more.sort': 'Ver & ordenar',
3089
+ 'more.commitGroup': 'Commit',
3090
+ 'more.changesGroup': 'Alterações',
3091
+ 'more.pullpushGroup': 'Pull, Push',
3092
+ 'more.branchGroup': 'Ramificação',
3093
+ 'more.remoteGroup': 'Remoto',
3094
+ 'more.stashGroup': 'Stash',
3095
+ 'more.tagGroup': 'Etiquetas',
3096
+ 'more.commitStaged': 'Commit dos ficheiros em staging...',
3097
+ 'more.commitAll': 'Commit de tudo...',
3098
+ 'more.undoCommit': 'Desfazer último commit',
3099
+ 'more.rebaseAbort': 'Abortar rebase',
3100
+ 'more.commitStagedAmend': 'Commit em staging (Amend)...',
3101
+ 'more.commitAllAmend': 'Commit de tudo (Amend)...',
3102
+ 'more.commitStagedSign': 'Commit em staging (Assinado)...',
3103
+ 'more.commitAllSign': 'Commit de tudo (Assinado)...',
3104
+ 'prompt.commitMessage': 'Mensagem de commit',
3105
+ 'more.discardAll': 'Descartar todas as alterações...',
3106
+ 'more.sync': 'Sincronizar (pull e push)',
3107
+ 'more.syncRebase': 'Sincronizar (rebase e push)',
3108
+ 'more.pullRebase': 'Pull (Rebase)',
3109
+ 'more.pullFrom': 'Pull de remoto',
3110
+ 'more.pushForce': 'Push (Forçado)...',
3111
+ 'more.pushTo': 'Push para remoto',
3112
+ 'more.fetchAll': 'Fetch de todos os remotos',
3113
+ 'more.deleteRemoteBranch': 'Eliminar ramo remoto...',
3114
+ 'more.publish': 'Publicar ramificação...',
3115
+ 'more.addRemote': 'Adicionar remoto...',
3116
+ 'more.removeRemote': 'Remover remoto...',
3117
+ 'more.stashTracked': 'Stash (apenas rastreados)',
3118
+ 'more.stashStaged': 'Stash de ficheiros em staging',
3119
+ 'more.stashApplyPick': 'Aplicar stash...',
3120
+ 'more.stashPopPick': 'Pop stash...',
3121
+ 'more.stashDropAny': 'Eliminar stash...',
3122
+ 'more.stashClear': 'Eliminar todos os stashes...',
3123
+ 'stash.none': 'Sem stashes disponíveis',
3124
+ 'more.tagDeleteRemote': 'Eliminar etiqueta remota...',
3125
+ 'more.pushTags': 'Enviar etiquetas...',
3126
+ 'confirm.undoCommit': 'Desfazer o último commit? As alterações ficam em staging.',
3127
+ 'confirm.discardAll': 'Descartar TODAS as alterações não em staging e não rastreadas? Recuperável pelos avisos de desfazer (ficheiros em conflito excluídos).',
3128
+ 'confirm.pushForce': 'O push forçado sobrescreve o remoto com esta ramificação (--force-with-lease recusa se outros enviaram). Continuar?',
3129
+ 'confirm.deleteRemoteBranch': 'Eliminar o ramo {branch} em {remote}?',
3130
+ 'confirm.remoteRemove': 'Remover o remoto {name}? A configuração de tracking vai junto.',
3131
+ 'confirm.stashClear': 'Eliminar TODOS os stashes? Isto não pode ser desfeito.',
3132
+ 'confirm.pushTags': 'Enviar todas as etiquetas para {remote}?',
3133
+ 'prompt.remoteName': 'Nome do remoto',
3134
+ 'prompt.remoteUrl': 'URL do remoto',
3135
+ 'prompt.deleteRemoteTag': 'Etiqueta remota a eliminar (enviada para {remote})',
2608
3136
  'toolbar.more': 'Mais ações',
2609
3137
  'more.sortGit': 'Ordem do Git',
2610
3138
  'more.sortPath': 'Por caminho',
@@ -2846,6 +3374,54 @@ window.__ModuleLoader__.load({
2846
3374
  'diff.copy': 'Copia',
2847
3375
  'diff.copied': 'Copiato',
2848
3376
  'toolbar.refresh': 'Aggiorna',
3377
+ 'more.sort': 'Visualizza e ordina',
3378
+ 'more.commitGroup': 'Commit',
3379
+ 'more.changesGroup': 'Modifiche',
3380
+ 'more.pullpushGroup': 'Pull, Push',
3381
+ 'more.branchGroup': 'Branch',
3382
+ 'more.remoteGroup': 'Remoto',
3383
+ 'more.stashGroup': 'Stash',
3384
+ 'more.tagGroup': 'Tag',
3385
+ 'more.commitStaged': 'Commit dei file in staging...',
3386
+ 'more.commitAll': 'Esegui commit di tutto...',
3387
+ 'more.undoCommit': 'Annulla ultimo commit',
3388
+ 'more.rebaseAbort': 'Interrompi rebase',
3389
+ 'more.commitStagedAmend': 'Commit in staging (Amend)...',
3390
+ 'more.commitAllAmend': 'Commit di tutto (Amend)...',
3391
+ 'more.commitStagedSign': 'Commit in staging (Firmato)...',
3392
+ 'more.commitAllSign': 'Commit di tutto (Firmato)...',
3393
+ 'prompt.commitMessage': 'Messaggio di commit',
3394
+ 'more.discardAll': 'Scarta tutte le modifiche...',
3395
+ 'more.sync': 'Sincronizza (pull e push)',
3396
+ 'more.syncRebase': 'Sincronizza (rebase e push)',
3397
+ 'more.pullRebase': 'Pull (Rebase)',
3398
+ 'more.pullFrom': 'Pull da remoto',
3399
+ 'more.pushForce': 'Push (Forza)...',
3400
+ 'more.pushTo': 'Push su remoto',
3401
+ 'more.fetchAll': 'Fetch da tutti i remoti',
3402
+ 'more.deleteRemoteBranch': 'Elimina branch remoto...',
3403
+ 'more.publish': 'Pubblica branch...',
3404
+ 'more.addRemote': 'Aggiungi remoto...',
3405
+ 'more.removeRemote': 'Rimuovi remoto...',
3406
+ 'more.stashTracked': 'Stash (solo tracciati)',
3407
+ 'more.stashStaged': 'Stash dei file in staging',
3408
+ 'more.stashApplyPick': 'Applica stash...',
3409
+ 'more.stashPopPick': 'Pop stash...',
3410
+ 'more.stashDropAny': 'Elimina stash...',
3411
+ 'more.stashClear': 'Elimina tutti gli stash...',
3412
+ 'stash.none': 'Nessuno stash disponibile',
3413
+ 'more.tagDeleteRemote': 'Elimina tag remoto...',
3414
+ 'more.pushTags': 'Esegui push dei tag...',
3415
+ 'confirm.undoCommit': 'Annullare l\'ultimo commit? Le modifiche restano in staging.',
3416
+ 'confirm.discardAll': 'Scartare TUTTE le modifiche non in staging e non tracciate? Recuperabili dai toast di annullamento (file in conflitto esclusi).',
3417
+ 'confirm.pushForce': 'Il push forzato sovrascrive il remoto con questo branch (--force-with-lease rifiuta se altri hanno fatto push). Continuare?',
3418
+ 'confirm.deleteRemoteBranch': 'Eliminare il branch {branch} su {remote}?',
3419
+ 'confirm.remoteRemove': 'Rimuovere il remoto {name}? La configurazione di tracking viene rimossa.',
3420
+ 'confirm.stashClear': 'Eliminare TUTTI gli stash? Operazione irreversibile.',
3421
+ 'confirm.pushTags': 'Eseguire il push di tutti i tag su {remote}?',
3422
+ 'prompt.remoteName': 'Nome remoto',
3423
+ 'prompt.remoteUrl': 'URL remoto',
3424
+ 'prompt.deleteRemoteTag': 'Tag remoto da eliminare (verrà rimosso da {remote})',
2849
3425
  'toolbar.more': 'Altre azioni',
2850
3426
  'more.sortGit': 'Ordine Git',
2851
3427
  'more.sortPath': 'Per percorso',
@@ -3087,6 +3663,54 @@ window.__ModuleLoader__.load({
3087
3663
  'diff.copy': 'Kopiëren',
3088
3664
  'diff.copied': 'Gekopieerd',
3089
3665
  'toolbar.refresh': 'Vernieuwen',
3666
+ 'more.sort': 'Weergeven & sorteren',
3667
+ 'more.commitGroup': 'Commit',
3668
+ 'more.changesGroup': 'Wijzigingen',
3669
+ 'more.pullpushGroup': 'Pull, Push',
3670
+ 'more.branchGroup': 'Branch',
3671
+ 'more.remoteGroup': 'Remote',
3672
+ 'more.stashGroup': 'Stash',
3673
+ 'more.tagGroup': 'Tags',
3674
+ 'more.commitStaged': 'Staged committen...',
3675
+ 'more.commitAll': 'Alles committen...',
3676
+ 'more.undoCommit': 'Laatste commit ongedaan maken',
3677
+ 'more.rebaseAbort': 'Rebase afbreken',
3678
+ 'more.commitStagedAmend': 'Staged committen (Amend)...',
3679
+ 'more.commitAllAmend': 'Alles committen (Amend)...',
3680
+ 'more.commitStagedSign': 'Staged committen (Getekend)...',
3681
+ 'more.commitAllSign': 'Alles committen (Getekend)...',
3682
+ 'prompt.commitMessage': 'Commitbericht',
3683
+ 'more.discardAll': 'Alle wijzigingen verwijderen...',
3684
+ 'more.sync': 'Synchroniseren (pull, dan push)',
3685
+ 'more.syncRebase': 'Synchroniseren (rebase, dan push)',
3686
+ 'more.pullRebase': 'Pull (Rebase)',
3687
+ 'more.pullFrom': 'Pull van remote',
3688
+ 'more.pushForce': 'Push (Forceer)...',
3689
+ 'more.pushTo': 'Naar remote pushen',
3690
+ 'more.fetchAll': 'Van alle remotes halen',
3691
+ 'more.deleteRemoteBranch': 'Remote branch verwijderen...',
3692
+ 'more.publish': 'Branch publiceren...',
3693
+ 'more.addRemote': 'Remote toevoegen...',
3694
+ 'more.removeRemote': 'Remote verwijderen...',
3695
+ 'more.stashTracked': 'Stash (alleen gevolgd)',
3696
+ 'more.stashStaged': 'Staged stashen',
3697
+ 'more.stashApplyPick': 'Stash toepassen...',
3698
+ 'more.stashPopPick': 'Stash poppen...',
3699
+ 'more.stashDropAny': 'Stash verwijderen...',
3700
+ 'more.stashClear': 'Alle stashes verwijderen...',
3701
+ 'stash.none': 'Geen stashes beschikbaar',
3702
+ 'more.tagDeleteRemote': 'Remote tag verwijderen...',
3703
+ 'more.pushTags': 'Tags pushen...',
3704
+ 'confirm.undoCommit': 'Laatste commit ongedaan maken? De wijzigingen blijven staged.',
3705
+ 'confirm.discardAll': 'ALLE niet-staged en niet-gevolgde wijzigingen verwijderen? Herstelbaar via undo-toasts (conflictbestanden uitgezonderd).',
3706
+ 'confirm.pushForce': 'Force push overschrijft de remote met deze branch (--force-with-lease weigert bij en en ander zijn push). Doorgaan?',
3707
+ 'confirm.deleteRemoteBranch': 'Branch {branch} op {remote} verwijderen?',
3708
+ 'confirm.remoteRemove': 'Remote {name} verwijderen? De trackingconfiguratie gaat mee.',
3709
+ 'confirm.stashClear': 'ALLE stashes verwijderen? Dit kan niet ongedaan worden gemaakt.',
3710
+ 'confirm.pushTags': 'Alle tags naar {remote} pushen?',
3711
+ 'prompt.remoteName': 'Remote-naam',
3712
+ 'prompt.remoteUrl': 'Remote-URL',
3713
+ 'prompt.deleteRemoteTag': 'Te verwijderen remote tag (wordt naar {remote} gepusht)',
3090
3714
  'toolbar.more': 'Meer acties',
3091
3715
  'more.sortGit': 'Git-volgorde',
3092
3716
  'more.sortPath': 'Op pad',
@@ -3328,6 +3952,54 @@ window.__ModuleLoader__.load({
3328
3952
  'diff.copy': 'Kopiuj',
3329
3953
  'diff.copied': 'Skopiowano',
3330
3954
  'toolbar.refresh': 'Odśwież',
3955
+ 'more.sort': 'Widok i sortowanie',
3956
+ 'more.commitGroup': 'Zatwierdź',
3957
+ 'more.changesGroup': 'Zmiany',
3958
+ 'more.pullpushGroup': 'Pobierz, wyślij',
3959
+ 'more.branchGroup': 'Gałąź',
3960
+ 'more.remoteGroup': 'Zdalne',
3961
+ 'more.stashGroup': 'Schowaj',
3962
+ 'more.tagGroup': 'Tagi',
3963
+ 'more.commitStaged': 'Zatwierdź przechowane...',
3964
+ 'more.commitAll': 'Zatwierdź wszystko...',
3965
+ 'more.undoCommit': 'Cofnij ostatnie zatwierdzenie',
3966
+ 'more.rebaseAbort': 'Przerwij rebase',
3967
+ 'more.commitStagedAmend': 'Zatwierdź przechowane (Amend)...',
3968
+ 'more.commitAllAmend': 'Zatwierdź wszystko (Amend)...',
3969
+ 'more.commitStagedSign': 'Zatwierdź przechowane (Podpisane)...',
3970
+ 'more.commitAllSign': 'Zatwierdź wszystko (Podpisane)...',
3971
+ 'prompt.commitMessage': 'Opis zatwierdzenia',
3972
+ 'more.discardAll': 'Odrzuć wszystkie zmiany...',
3973
+ 'more.sync': 'Synchronizuj (pobierz, potem wyślij)',
3974
+ 'more.syncRebase': 'Synchronizuj (rebase, potem wyślij)',
3975
+ 'more.pullRebase': 'Pobierz (Rebase)',
3976
+ 'more.pullFrom': 'Pobierz z zdalnego',
3977
+ 'more.pushForce': 'Wyślij (Wymuszone)...',
3978
+ 'more.pushTo': 'Wyślij do zdalnego',
3979
+ 'more.fetchAll': 'Pobierz ze wszystkich zdalnych',
3980
+ 'more.deleteRemoteBranch': 'Usuń zdalną gałąź...',
3981
+ 'more.publish': 'Opublikuj gałąź...',
3982
+ 'more.addRemote': 'Dodaj zdalne...',
3983
+ 'more.removeRemote': 'Usuń zdalne...',
3984
+ 'more.stashTracked': 'Schowaj (tylko śledzone)',
3985
+ 'more.stashStaged': 'Schowaj przechowane',
3986
+ 'more.stashApplyPick': 'Zastosuj schowek...',
3987
+ 'more.stashPopPick': 'Zdejmij schowek...',
3988
+ 'more.stashDropAny': 'Usuń schowek...',
3989
+ 'more.stashClear': 'Usuń wszystkie schowki...',
3990
+ 'stash.none': 'Brak dostępnych schowków',
3991
+ 'more.tagDeleteRemote': 'Usuń zdalny tag...',
3992
+ 'more.pushTags': 'Wyślij tagi...',
3993
+ 'confirm.undoCommit': 'Cofnąć ostatnie zatwierdzenie? Zmiany pozostaną przechowane.',
3994
+ 'confirm.discardAll': 'Odrzucić WSZYSTKIE nieprzechowane i nieśledzone zmiany? Do odzyskania przez powiadomienia (pliki konfliktowe wyłączone).',
3995
+ 'confirm.pushForce': 'Wymuszone wysłanie nadpisze zdalne tą gałęzią (--force-with-lease odmówi, gdy inni wysłali). Kontynuować?',
3996
+ 'confirm.deleteRemoteBranch': 'Usunąć gałąź {branch} na {remote}?',
3997
+ 'confirm.remoteRemove': 'Usunąć zdalne {name}? Konfiguracja śledzenia zostanie usunięta.',
3998
+ 'confirm.stashClear': 'Usunąć WSZYSTKIE schowki? Tego nie da się cofnąć.',
3999
+ 'confirm.pushTags': 'Wysłać wszystkie tagi do {remote}?',
4000
+ 'prompt.remoteName': 'Nazwa zdalnego',
4001
+ 'prompt.remoteUrl': 'URL zdalnego',
4002
+ 'prompt.deleteRemoteTag': 'Zdalny tag do usunięcia (zostanie usunięty z {remote})',
3331
4003
  'toolbar.more': 'Więcej akcji',
3332
4004
  'more.sortGit': 'Kolejność Gita',
3333
4005
  'more.sortPath': 'Według ścieżki',
@@ -3569,6 +4241,54 @@ window.__ModuleLoader__.load({
3569
4241
  'diff.copy': 'Kopiera',
3570
4242
  'diff.copied': 'Kopierat',
3571
4243
  'toolbar.refresh': 'Uppdatera',
4244
+ 'more.sort': 'Visa & sortera',
4245
+ 'more.commitGroup': 'Checka in',
4246
+ 'more.changesGroup': 'Ändringar',
4247
+ 'more.pullpushGroup': 'Hämta, skicka',
4248
+ 'more.branchGroup': 'Gren',
4249
+ 'more.remoteGroup': 'Fjärr',
4250
+ 'more.stashGroup': 'Stash',
4251
+ 'more.tagGroup': 'Taggar',
4252
+ 'more.commitStaged': 'Checka in stagingade...',
4253
+ 'more.commitAll': 'Checka in allt...',
4254
+ 'more.undoCommit': 'Ångra senaste incheckning',
4255
+ 'more.rebaseAbort': 'Avbryt rebase',
4256
+ 'more.commitStagedAmend': 'Checka in stagingade (Amend)...',
4257
+ 'more.commitAllAmend': 'Checka in allt (Amend)...',
4258
+ 'more.commitStagedSign': 'Checka in stagingade (Signerat)...',
4259
+ 'more.commitAllSign': 'Checka in allt (Signerat)...',
4260
+ 'prompt.commitMessage': 'Incheckningsmeddelande',
4261
+ 'more.discardAll': 'Kasta alla ändringar...',
4262
+ 'more.sync': 'Synka (hämta, sedan skicka)',
4263
+ 'more.syncRebase': 'Synka (rebase, sedan skicka)',
4264
+ 'more.pullRebase': 'Hämta (Rebase)',
4265
+ 'more.pullFrom': 'Hämta från fjärr',
4266
+ 'more.pushForce': 'Skicka (Tvinga)...',
4267
+ 'more.pushTo': 'Skicka till fjärr',
4268
+ 'more.fetchAll': 'Hämta från alla fjärrar',
4269
+ 'more.deleteRemoteBranch': 'Ta bort fjärrgren...',
4270
+ 'more.publish': 'Publicera gren...',
4271
+ 'more.addRemote': 'Lägg till fjärr...',
4272
+ 'more.removeRemote': 'Ta bort fjärr...',
4273
+ 'more.stashTracked': 'Stash (endast spårade)',
4274
+ 'more.stashStaged': 'Stasha stagingade',
4275
+ 'more.stashApplyPick': 'Använd stash...',
4276
+ 'more.stashPopPick': 'Poppa stash...',
4277
+ 'more.stashDropAny': 'Ta bort stash...',
4278
+ 'more.stashClear': 'Ta bort alla stash:ar...',
4279
+ 'stash.none': 'Inga stash:ar tillgängliga',
4280
+ 'more.tagDeleteRemote': 'Ta bort fjärrtagg...',
4281
+ 'more.pushTags': 'Skicka taggar...',
4282
+ 'confirm.undoCommit': 'Ångra senaste incheckningen? Ändringarna stannar i staging.',
4283
+ 'confirm.discardAll': 'Kasta ALLA ostagingade och ospårade ändringar? Återställningsbara via ångra-toasts (konfliktfiler undantagna).',
4284
+ 'confirm.pushForce': 'Tvingad sändning skriver över fjärren med denna gren (--force-with-lease nekar om andra skickat). Fortsätta?',
4285
+ 'confirm.deleteRemoteBranch': 'Ta bort grenen {branch} på {remote}?',
4286
+ 'confirm.remoteRemove': 'Ta bort fjärren {name}? Spårningskonfigurationen tas bort med den.',
4287
+ 'confirm.stashClear': 'Ta bort ALLA stash:ar? Detta går inte att ångra.',
4288
+ 'confirm.pushTags': 'Skicka alla taggar till {remote}?',
4289
+ 'prompt.remoteName': 'Fjärrnamn',
4290
+ 'prompt.remoteUrl': 'Fjärr-URL',
4291
+ 'prompt.deleteRemoteTag': 'Fjärrtagg att ta bort (skickas till {remote})',
3572
4292
  'toolbar.more': 'Fler åtgärder',
3573
4293
  'more.sortGit': 'Git-ordning',
3574
4294
  'more.sortPath': 'Efter sökväg',
@@ -3810,6 +4530,54 @@ window.__ModuleLoader__.load({
3810
4530
  'diff.copy': 'Kopyala',
3811
4531
  'diff.copied': 'Kopyalandı',
3812
4532
  'toolbar.refresh': 'Yenile',
4533
+ 'more.sort': 'Görüntüle & sırala',
4534
+ 'more.commitGroup': 'İşle',
4535
+ 'more.changesGroup': 'Değişiklikler',
4536
+ 'more.pullpushGroup': 'Çek, Gönder',
4537
+ 'more.branchGroup': 'Dal',
4538
+ 'more.remoteGroup': 'Uzak',
4539
+ 'more.stashGroup': 'Stash',
4540
+ 'more.tagGroup': 'Etiket',
4541
+ 'more.commitStaged': 'Staged dosyaları işle...',
4542
+ 'more.commitAll': 'Tümünü işle...',
4543
+ 'more.undoCommit': 'Son işlemi geri al',
4544
+ 'more.rebaseAbort': 'Rebase\'i durdur',
4545
+ 'more.commitStagedAmend': 'Staged dosyaları işle (Düzelt)...',
4546
+ 'more.commitAllAmend': 'Tümünü işle (Düzelt)...',
4547
+ 'more.commitStagedSign': 'Staged dosyaları işle (İmzalı)...',
4548
+ 'more.commitAllSign': 'Tümünü işle (İmzalı)...',
4549
+ 'prompt.commitMessage': 'İşleme mesajı',
4550
+ 'more.discardAll': 'TÜM değişiklikleri at...',
4551
+ 'more.sync': 'Eşitle (çek, sonra gönder)',
4552
+ 'more.syncRebase': 'Eşitle (rebase, sonra gönder)',
4553
+ 'more.pullRebase': 'Çek (Rebase)',
4554
+ 'more.pullFrom': 'Uzaktan çek',
4555
+ 'more.pushForce': 'Gönder (Zorla)...',
4556
+ 'more.pushTo': 'Uzağa gönder',
4557
+ 'more.fetchAll': 'Tüm uzaklardan al',
4558
+ 'more.deleteRemoteBranch': 'Uzak dalı sil...',
4559
+ 'more.publish': 'Dalı yayınla...',
4560
+ 'more.addRemote': 'Uzak ekle...',
4561
+ 'more.removeRemote': 'Uzağı kaldır...',
4562
+ 'more.stashTracked': 'Stash (yalnızca izlenen)',
4563
+ 'more.stashStaged': 'Staged dosyaları stash\'le',
4564
+ 'more.stashApplyPick': 'Stash uygula...',
4565
+ 'more.stashPopPick': 'Stash pop yap...',
4566
+ 'more.stashDropAny': 'Stash sil...',
4567
+ 'more.stashClear': 'Tüm stash\'leri sil...',
4568
+ 'stash.none': 'Kullanılabilir stash yok',
4569
+ 'more.tagDeleteRemote': 'Uzak etiketi sil...',
4570
+ 'more.pushTags': 'Etiketleri gönder...',
4571
+ 'confirm.undoCommit': 'Son işlem geri alınsın mı? Değişiklikler staged olarak kalır.',
4572
+ 'confirm.discardAll': 'Staged OLMAYAN ve izlenmeyen TÜM değişiklikler atılsın mı? Geri alma bildirimlerinden kurtarılabilir (çakışan dosyalar hariç).',
4573
+ 'confirm.pushForce': 'Zorla gönderme, uzakta olanı bu dalla üzerine yazar (--force-with-lease, başkası göndermişse reddeder).Devam edilsin mi?',
4574
+ 'confirm.deleteRemoteBranch': '{remote} üzerindeki {branch} dalı silinsin mi?',
4575
+ 'confirm.remoteRemove': '{name} uzaklığı kaldırılsın mı? Takip yapılandırması da kaldırılır.',
4576
+ 'confirm.stashClear': 'TÜM stash\'ler silinsin mi? Bu geri alınamaz.',
4577
+ 'confirm.pushTags': 'Tüm etiketler {remote} üzerine gönderilsin mi?',
4578
+ 'prompt.remoteName': 'Uzak adı',
4579
+ 'prompt.remoteUrl': 'Uzak URL',
4580
+ 'prompt.deleteRemoteTag': 'Silinecek uzak etiket ({remote} üzerine gönderilir)',
3813
4581
  'toolbar.more': 'Diğer eylemler',
3814
4582
  'more.sortGit': 'Git sırası',
3815
4583
  'more.sortPath': 'Yola göre',
@@ -4051,6 +4819,54 @@ window.__ModuleLoader__.load({
4051
4819
  'diff.copy': 'Salin',
4052
4820
  'diff.copied': 'Tersalin',
4053
4821
  'toolbar.refresh': 'Segarkan',
4822
+ 'more.sort': 'Lihat & urutkan',
4823
+ 'more.commitGroup': 'Commit',
4824
+ 'more.changesGroup': 'Perubahan',
4825
+ 'more.pullpushGroup': 'Pull, Push',
4826
+ 'more.branchGroup': 'Cabang',
4827
+ 'more.remoteGroup': 'Remote',
4828
+ 'more.stashGroup': 'Stash',
4829
+ 'more.tagGroup': 'Tag',
4830
+ 'more.commitStaged': 'Commit file yang di-stage...',
4831
+ 'more.commitAll': 'Commit semua...',
4832
+ 'more.undoCommit': 'Batalkan commit terakhir',
4833
+ 'more.rebaseAbort': 'Batalkan rebase',
4834
+ 'more.commitStagedAmend': 'Commit stage (Amend)...',
4835
+ 'more.commitAllAmend': 'Commit semua (Amend)...',
4836
+ 'more.commitStagedSign': 'Commit stage (Ditandatangani)...',
4837
+ 'more.commitAllSign': 'Commit semua (Ditandatangani)...',
4838
+ 'prompt.commitMessage': 'Pesan commit',
4839
+ 'more.discardAll': 'Buang semua perubahan...',
4840
+ 'more.sync': 'Sinkronkan (pull lalu push)',
4841
+ 'more.syncRebase': 'Sinkronkan (rebase lalu push)',
4842
+ 'more.pullRebase': 'Pull (Rebase)',
4843
+ 'more.pullFrom': 'Pull dari remote',
4844
+ 'more.pushForce': 'Push (Paksa)...',
4845
+ 'more.pushTo': 'Push ke remote',
4846
+ 'more.fetchAll': 'Fetch dari semua remote',
4847
+ 'more.deleteRemoteBranch': 'Hapus cabang remote...',
4848
+ 'more.publish': 'Publikasikan cabang...',
4849
+ 'more.addRemote': 'Tambah remote...',
4850
+ 'more.removeRemote': 'Hapus remote...',
4851
+ 'more.stashTracked': 'Stash (hanya yang dilacak)',
4852
+ 'more.stashStaged': 'Stage yang di-stash',
4853
+ 'more.stashApplyPick': 'Terapkan stash...',
4854
+ 'more.stashPopPick': 'Pop stash...',
4855
+ 'more.stashDropAny': 'Buang stash...',
4856
+ 'more.stashClear': 'Buang semua stash...',
4857
+ 'stash.none': 'Tidak ada stash tersedia',
4858
+ 'more.tagDeleteRemote': 'Hapus tag remote...',
4859
+ 'more.pushTags': 'Kirim tag...',
4860
+ 'confirm.undoCommit': 'Batalkan commit terakhir? Perubahannya tetap di stage.',
4861
+ 'confirm.discardAll': 'Buang SEMUA perubahan yang tidak di-stage dan tidak dilacak? Dapat dipulihkan lewat toast undo (file konflik dikecualikan).',
4862
+ 'confirm.pushForce': 'Push paksa menimpa remote dengan cabang ini (--force-with-lease menolak jika orang lain sudah push).Lanjutkan?',
4863
+ 'confirm.deleteRemoteBranch': 'Hapus cabang {branch} di {remote}?',
4864
+ 'confirm.remoteRemove': 'Hapus remote {name}? Konfigurasi trackingnya ikut terhapus.',
4865
+ 'confirm.stashClear': 'Buang SEMUA stash? Ini tidak bisa dibatalkan.',
4866
+ 'confirm.pushTags': 'Kirim semua tag ke {remote}?',
4867
+ 'prompt.remoteName': 'Nama remote',
4868
+ 'prompt.remoteUrl': 'URL remote',
4869
+ 'prompt.deleteRemoteTag': 'Tag remote yang akan dihapus (didorong ke {remote})',
4054
4870
  'toolbar.more': 'Tindakan lainnya',
4055
4871
  'more.sortGit': 'Urutan Git',
4056
4872
  'more.sortPath': 'Menurut jalur',
@@ -4292,6 +5108,54 @@ window.__ModuleLoader__.load({
4292
5108
  'diff.copy': 'Sao chép',
4293
5109
  'diff.copied': 'Đã sao chép',
4294
5110
  'toolbar.refresh': 'Làm mới',
5111
+ 'more.sort': 'Xem & sắp xếp',
5112
+ 'more.commitGroup': 'Commit',
5113
+ 'more.changesGroup': 'Thay đổi',
5114
+ 'more.pullpushGroup': 'Pull, Push',
5115
+ 'more.branchGroup': 'Nhánh',
5116
+ 'more.remoteGroup': 'Remote',
5117
+ 'more.stashGroup': 'Stash',
5118
+ 'more.tagGroup': 'Thẻ',
5119
+ 'more.commitStaged': 'Commit các tệp đã stage...',
5120
+ 'more.commitAll': 'Commit tất cả...',
5121
+ 'more.undoCommit': 'Hoàn tác commit cuối',
5122
+ 'more.rebaseAbort': 'Hủy rebase',
5123
+ 'more.commitStagedAmend': 'Commit đã stage (Sửa)...',
5124
+ 'more.commitAllAmend': 'Commit tất cả (Sửa)...',
5125
+ 'more.commitStagedSign': 'Commit đã stage (Ký)...',
5126
+ 'more.commitAllSign': 'Commit tất cả (Ký)...',
5127
+ 'prompt.commitMessage': 'Thông điệp commit',
5128
+ 'more.discardAll': 'Bỏ TẤT CẢ thay đổi...',
5129
+ 'more.sync': 'Đồng bộ (pull rồi push)',
5130
+ 'more.syncRebase': 'Đồng bộ (rebase rồi push)',
5131
+ 'more.pullRebase': 'Pull (Rebase)',
5132
+ 'more.pullFrom': 'Pull từ remote',
5133
+ 'more.pushForce': 'Push (Ép)...',
5134
+ 'more.pushTo': 'Push lên remote',
5135
+ 'more.fetchAll': 'Fetch từ mọi remote',
5136
+ 'more.deleteRemoteBranch': 'Xóa nhánh remote...',
5137
+ 'more.publish': 'Công bố nhánh...',
5138
+ 'more.addRemote': 'Thêm remote...',
5139
+ 'more.removeRemote': 'Xóa remote...',
5140
+ 'more.stashTracked': 'Stash (chỉ theo dõi)',
5141
+ 'more.stashStaged': 'Stash các tệp đã stage',
5142
+ 'more.stashApplyPick': 'Áp dụng stash...',
5143
+ 'more.stashPopPick': 'Pop stash...',
5144
+ 'more.stashDropAny': 'Xóa stash...',
5145
+ 'more.stashClear': 'Xóa tất cả stash...',
5146
+ 'stash.none': 'Không có stash nào',
5147
+ 'more.tagDeleteRemote': 'Xóa thẻ remote...',
5148
+ 'more.pushTags': 'Đẩy thẻ...',
5149
+ 'confirm.undoCommit': 'Hoàn tác commit cuối? Các thay đổi vẫn giữ trong stage.',
5150
+ 'confirm.discardAll': 'Bỏ TẤT CẢ thay đổi chưa stage và chưa theo dõi? Có thể khôi phục qua toast hoàn tác (trừ tệp xung đột).',
5151
+ 'confirm.pushForce': 'Push ép sẽ ghi đè remote bằng nhánh này (--force-with-lease từ chối nếu người khác đã đẩy).Tiếp tục?',
5152
+ 'confirm.deleteRemoteBranch': 'Xóa nhánh {branch} trên {remote}?',
5153
+ 'confirm.remoteRemove': 'Xóa remote {name}? Cấu hình theo dõi cũng bị xóa.',
5154
+ 'confirm.stashClear': 'Xóa TẤT CẢ stash? Không thể hoàn tác.',
5155
+ 'confirm.pushTags': 'Đẩy tất cả thẻ lên {remote}?',
5156
+ 'prompt.remoteName': 'Tên remote',
5157
+ 'prompt.remoteUrl': 'URL remote',
5158
+ 'prompt.deleteRemoteTag': 'Thẻ remote cần xóa (sẽ đẩy lên {remote})',
4295
5159
  'toolbar.more': 'Thao tác khác',
4296
5160
  'more.sortGit': 'Thứ tự Git',
4297
5161
  'more.sortPath': 'Theo đường dẫn',
@@ -4533,6 +5397,54 @@ window.__ModuleLoader__.load({
4533
5397
  'diff.copy': 'نسخ',
4534
5398
  'diff.copied': 'تم النسخ',
4535
5399
  'toolbar.refresh': 'تحديث',
5400
+ 'more.sort': 'عرض وفرز',
5401
+ 'more.commitGroup': 'إيداع',
5402
+ 'more.changesGroup': 'التغييرات',
5403
+ 'more.pullpushGroup': 'سحب، دفع',
5404
+ 'more.branchGroup': 'فرع',
5405
+ 'more.remoteGroup': 'جهاز بعيد',
5406
+ 'more.stashGroup': 'خبئ',
5407
+ 'more.tagGroup': 'وسوم',
5408
+ 'more.commitStaged': 'إيداع الملفات المجهزة...',
5409
+ 'more.commitAll': 'إيداع الكل...',
5410
+ 'more.undoCommit': 'تراجع عن آخر إيداع',
5411
+ 'more.rebaseAbort': 'إلغاء إعادة الأساس',
5412
+ 'more.commitStagedAmend': 'إيداع المجهز (تعديل)...',
5413
+ 'more.commitAllAmend': 'إيداع الكل (تعديل)...',
5414
+ 'more.commitStagedSign': 'إيداع المجهز (موقع)...',
5415
+ 'more.commitAllSign': 'إيداع الكل (موقع)...',
5416
+ 'prompt.commitMessage': 'رسالة الإيداع',
5417
+ 'more.discardAll': 'تجاهل جميع التغييرات...',
5418
+ 'more.sync': 'مزامنة (سحب ثم دفع)',
5419
+ 'more.syncRebase': 'مزامنة (إعادة أساس ثم دفع)',
5420
+ 'more.pullRebase': 'سحب (إعادة أساس)',
5421
+ 'more.pullFrom': 'سحب من الجهاز البعيد',
5422
+ 'more.pushForce': 'دفع (قسري)...',
5423
+ 'more.pushTo': 'دفع إلى جهاز بعيد',
5424
+ 'more.fetchAll': 'جلب من كل الأجهزة البعيدة',
5425
+ 'more.deleteRemoteBranch': 'حذف فرع بعيد...',
5426
+ 'more.publish': 'نشر الفرع...',
5427
+ 'more.addRemote': 'إضافة جهاز بعيد...',
5428
+ 'more.removeRemote': 'إزالة جهاز بعيد...',
5429
+ 'more.stashTracked': 'خبئ (المتتبع فقط)',
5430
+ 'more.stashStaged': 'خبئ الملفات المجهزة',
5431
+ 'more.stashApplyPick': 'تطبيق مخبأ...',
5432
+ 'more.stashPopPick': 'فرقغ مخبأ...',
5433
+ 'more.stashDropAny': 'حذف مخبأ...',
5434
+ 'more.stashClear': 'حذف جميع المخبآء...',
5435
+ 'stash.none': 'لا توجد مخبآء متاحة',
5436
+ 'more.tagDeleteRemote': 'حذف وسم بعيد...',
5437
+ 'more.pushTags': 'دفع الوسوم...',
5438
+ 'confirm.undoCommit': 'التراجع عن آخر إيداع؟تبقى تغييراته في منطقة التجهيز.',
5439
+ 'confirm.discardAll': 'تجاهل كل التغييرات غير المجهزة وغير المتتبعة؟يمكن استعادتها من إشعارات التراجع (ملفات التعارض مستثناة).',
5440
+ 'confirm.pushForce': 'الدفع القسري سيستبدل البعيد بهذا الفرع(--force-with-lease يرفض إن دفع غيرك).المتابعة؟',
5441
+ 'confirm.deleteRemoteBranch': 'حذف الفرع {branch} على {remote}؟',
5442
+ 'confirm.remoteRemove': 'إزالة البعيد {name}؟ستُزال إعدادات التتبع معه.',
5443
+ 'confirm.stashClear': 'حذف جميع المخبآء؟لا يمكن التراجع.',
5444
+ 'confirm.pushTags': 'دفع كل الوسوم إلى {remote}؟',
5445
+ 'prompt.remoteName': 'اسم البعيد',
5446
+ 'prompt.remoteUrl': 'رابط البعيد',
5447
+ 'prompt.deleteRemoteTag': 'الوسم البعيد المراد حذفه(سيُدفع إلى {remote})',
4536
5448
  'toolbar.more': 'مزيد من الإجراءات',
4537
5449
  'more.sortGit': 'ترتيب Git',
4538
5450
  'more.sortPath': 'حسب المسار',
@@ -4774,6 +5686,54 @@ window.__ModuleLoader__.load({
4774
5686
  'diff.copy': 'कॉपी करें',
4775
5687
  'diff.copied': 'कॉपी हो गया',
4776
5688
  'toolbar.refresh': 'ताज़ा करें',
5689
+ 'more.sort': 'देखें और क्रमबद्ध करें',
5690
+ 'more.commitGroup': 'कमिट',
5691
+ 'more.changesGroup': 'बदलाव',
5692
+ 'more.pullpushGroup': 'पुल, पुश',
5693
+ 'more.branchGroup': 'ब्रांच',
5694
+ 'more.remoteGroup': 'रिमोट',
5695
+ 'more.stashGroup': 'स्टैश',
5696
+ 'more.tagGroup': 'टैग',
5697
+ 'more.commitStaged': 'स्टेज्ड फ़ाइलें कमिट करें...',
5698
+ 'more.commitAll': 'सभी कमिट करें...',
5699
+ 'more.undoCommit': 'अंतिम कमिट रद्द करें',
5700
+ 'more.rebaseAbort': 'रिबेस रोकें',
5701
+ 'more.commitStagedAmend': 'स्टेज्ड कमिट (संशोधन)...',
5702
+ 'more.commitAllAmend': 'सभी कमिट (संशोधन)...',
5703
+ 'more.commitStagedSign': 'स्टेज्ड कमिट (हस्ताक्षरित)...',
5704
+ 'more.commitAllSign': 'सभी कमिट (हस्ताक्षरित)...',
5705
+ 'prompt.commitMessage': 'कमिट संदेश',
5706
+ 'more.discardAll': 'सभी बदलाव छोड़ें...',
5707
+ 'more.sync': 'सिंक (पुल फिर पुश)',
5708
+ 'more.syncRebase': 'सिंक (रिबेस फिर पुश)',
5709
+ 'more.pullRebase': 'पुल (रिबेस)',
5710
+ 'more.pullFrom': 'रिमोट से पुल',
5711
+ 'more.pushForce': 'पुश (बलपूर्वक)...',
5712
+ 'more.pushTo': 'रिमोट पर पुश',
5713
+ 'more.fetchAll': 'सभी रिमोट से फ़ेच',
5714
+ 'more.deleteRemoteBranch': 'रिमोट ब्रांच हटाएँ...',
5715
+ 'more.publish': 'ब्रांच प्रकाशित करें...',
5716
+ 'more.addRemote': 'रिमोट जोड़ें...',
5717
+ 'more.removeRemote': 'रिमोट हटाएँ...',
5718
+ 'more.stashTracked': 'स्टैश (केवल ट्रैक की गई)',
5719
+ 'more.stashStaged': 'स्टेज्ड स्टैश करें',
5720
+ 'more.stashApplyPick': 'स्टैश लागू करें...',
5721
+ 'more.stashPopPick': 'स्टैश पॉप करें...',
5722
+ 'more.stashDropAny': 'स्टैश हटाएँ...',
5723
+ 'more.stashClear': 'सभी स्टैश हटाएँ...',
5724
+ 'stash.none': 'कोई स्टैश उपलब्ध नहीं',
5725
+ 'more.tagDeleteRemote': 'रिमोट टैग हटाएँ...',
5726
+ 'more.pushTags': 'टैग पुश करें...',
5727
+ 'confirm.undoCommit': 'अंतिम कमिट रद्द करें?इसके बदलाव स्टेज पर रहेंगे।',
5728
+ 'confirm.discardAll': 'सभी अन-स्टेज्ड और अन-ट्रैक्ड बदलाव छोड़ें?अन्डू टोस्ट से पुनर्प्राप्त संभव (कॉन्फ्लिक्ट फ़ाइलें छोड़कर)।',
5729
+ 'confirm.pushForce': 'फोर्स पुश रिमोट को इस ब्रांच से अधिलेखित करेगा(--force-with-lease अस्वीकार करेगा यदि दूसरों ने पुश किया)।जारी रखें?',
5730
+ 'confirm.deleteRemoteBranch': '{remote} पर ब्रांच {branch} हटाएँ?',
5731
+ 'confirm.remoteRemove': 'रिमोट {name} हटाएँ?इसकी ट्रैकिंग सेटिंग भी हट जाएगी।',
5732
+ 'confirm.stashClear': 'सभी स्टैश हटाएँ?यह पूर्ववत नहीं हो सकता।',
5733
+ 'confirm.pushTags': 'सभी टैग {remote} पर पुश करें?',
5734
+ 'prompt.remoteName': 'रिमोट नाम',
5735
+ 'prompt.remoteUrl': 'रिमोट URL',
5736
+ 'prompt.deleteRemoteTag': 'हटाने के लिए रिमोट टैग ({remote} पर पुश होगा)',
4777
5737
  'toolbar.more': 'अधिक क्रियाएँ',
4778
5738
  'more.sortGit': 'Git क्रम',
4779
5739
  'more.sortPath': 'पथ से',
@@ -5015,6 +5975,54 @@ window.__ModuleLoader__.load({
5015
5975
  'diff.copy': 'คัดลอก',
5016
5976
  'diff.copied': 'คัดลอกแล้ว',
5017
5977
  'toolbar.refresh': 'รีเฟรช',
5978
+ 'more.sort': 'ดู & เรียงลำดับ',
5979
+ 'more.commitGroup': 'คอมมิต',
5980
+ 'more.changesGroup': 'การเปลี่ยนแปลง',
5981
+ 'more.pullpushGroup': 'พูล, พุช',
5982
+ 'more.branchGroup': 'บรานช์',
5983
+ 'more.remoteGroup': 'รีโมต',
5984
+ 'more.stashGroup': 'สแตช',
5985
+ 'more.tagGroup': 'แท็ก',
5986
+ 'more.commitStaged': 'คอมมิตไฟล์ที่สเตจ...',
5987
+ 'more.commitAll': 'คอมมิตทั้งหมด...',
5988
+ 'more.undoCommit': 'ยกเลิกคอมมิตล่าสุด',
5989
+ 'more.rebaseAbort': 'ยกเลิกรีเบส',
5990
+ 'more.commitStagedAmend': 'คอมมิตไฟล์ที่สเตจ(แก้ไข)...',
5991
+ 'more.commitAllAmend': 'คอมมิตทั้งหมด(แก้ไข)...',
5992
+ 'more.commitStagedSign': 'คอมมิตไฟล์ที่สเตจ(ลงนาม)...',
5993
+ 'more.commitAllSign': 'คอมมิตทั้งหมด(ลงนาม)...',
5994
+ 'prompt.commitMessage': 'ข้อความคอมมิต',
5995
+ 'more.discardAll': 'ทิ้งการเปลี่ยนแปลงทั้งหมด...',
5996
+ 'more.sync': 'ซิงก์(พูลแล้วพุช)',
5997
+ 'more.syncRebase': 'ซิงก์(รีเบสแล้วพุช)',
5998
+ 'more.pullRebase': 'พูล(รีเบส)',
5999
+ 'more.pullFrom': 'พูลจากรีโมต',
6000
+ 'more.pushForce': 'พุช(บังคับ)...',
6001
+ 'more.pushTo': 'พุชไปรีโมต',
6002
+ 'more.fetchAll': 'ฟีตช์จากทุกรีโมต',
6003
+ 'more.deleteRemoteBranch': 'ลบบรานช์รีโมต...',
6004
+ 'more.publish': 'เผยแพร่บรานช์...',
6005
+ 'more.addRemote': 'เพิ่มรีโมต...',
6006
+ 'more.removeRemote': 'ลบรีโมต...',
6007
+ 'more.stashTracked': 'สแตช(เฉพาะไฟล์ที่ติดตาม)',
6008
+ 'more.stashStaged': 'สแตชไฟล์ที่สเตจ',
6009
+ 'more.stashApplyPick': 'ใช้สแตช...',
6010
+ 'more.stashPopPick': 'ป๊อปสแตช...',
6011
+ 'more.stashDropAny': 'ลบสแตช...',
6012
+ 'more.stashClear': 'ลบสแตชทั้งหมด...',
6013
+ 'stash.none': 'ไม่มีสแตชที่ใช้ได้',
6014
+ 'more.tagDeleteRemote': 'ลบแท็กรีโมต...',
6015
+ 'more.pushTags': 'พุชแท็ก...',
6016
+ 'confirm.undoCommit': 'ยกเลิกคอมมิตล่าสุด?การเปลี่ยนแปลงจะอยู่ในสเตจ',
6017
+ 'confirm.discardAll': 'ทิ้งการเปลี่ยนแปลงที่ไม่ได้สเตจและไม่ได้ติดตามทั้งหมด?กู้คืนได้จาก toast เลิกทำ(ยกเว้นไฟล์ขัดแย้ง)',
6018
+ 'confirm.pushForce': 'พุชแบบบังคับจะเขียนทับรีโมตด้วยบรานช์นี้(--force-with-lease จะปฏิเสธหากคนอื่นพุชแล้ว)ดำเนินการต่อ?',
6019
+ 'confirm.deleteRemoteBranch': 'ลบบรานช์ {branch} บน {remote}?',
6020
+ 'confirm.remoteRemove': 'ลบรีโมต {name}?การตั้งค่าติดตามจะถูกลบด้วย',
6021
+ 'confirm.stashClear': 'ลบสแตชทั้งหมด?ทำไม่ได้ที่จะย้อนกลับ',
6022
+ 'confirm.pushTags': 'พุชแท็กทั้งหมดไปยัง {remote}?',
6023
+ 'prompt.remoteName': 'ชื่อรีโมต',
6024
+ 'prompt.remoteUrl': 'URL รีโมต',
6025
+ 'prompt.deleteRemoteTag': 'แท็กรีโมตที่จะลบ(จะพุชไปยัง {remote})',
5018
6026
  'toolbar.more': 'การกระทำเพิ่มเติม',
5019
6027
  'more.sortGit': 'ลำดับ Git',
5020
6028
  'more.sortPath': 'ตามเส้นทาง',
@@ -5573,21 +6581,24 @@ window.__ModuleLoader__.load({
5573
6581
  { id: 'float', icon: 'float', key: 'action.float', tone: 'accent' },
5574
6582
  { id: 'split', icon: 'split', key: 'action.split', tone: 'secondary' },
5575
6583
  { id: 'fullscreen', icon: 'fullscreen', key: 'action.fullscreen', tone: 'secondary' },
5576
- { id: 'newBranch', icon: 'plus', key: 'toolbar.newBranch', tone: 'success' },
6584
+ { id: 'newBranch', icon: 'branchCreate', key: 'toolbar.newBranch', tone: 'success' },
5577
6585
  { id: 'checkout', icon: 'checkout', key: 'action.checkout', tone: 'accent' },
5578
6586
  { id: 'delete', icon: 'trash', key: 'action.delete', tone: 'danger' },
5579
6587
  { id: 'compare', icon: 'compare', key: 'action.compare', tone: 'violet' },
5580
- { id: 'diff', icon: 'file', key: 'action.showDiff', tone: 'secondary' },
6588
+ { id: 'diff', icon: 'diff', key: 'action.showDiff', tone: 'secondary' },
5581
6589
  { id: 'stash', icon: 'stash', key: 'action.stash', tone: 'cyan' },
5582
6590
  { id: 'tag', icon: 'tag', key: 'action.newTagHere', tone: 'warn' },
5583
6591
  { id: 'favorite', icon: 'star', key: 'action.favorite', tone: 'warn' },
6592
+ /* fetch keeps its own button (user walked back the removal, 2026-10-10);
6593
+ the refresh button ALSO fetches when clicked manually — refresh means
6594
+ "see whether the remote has anything new", and the dedicated fetch is
6595
+ still there for the explicit gesture. */
5584
6596
  { id: 'fetch', icon: 'fetch', key: 'toolbar.fetch', tone: 'cyan' },
5585
6597
  { id: 'pull', icon: 'pull', key: 'toolbar.pull', tone: 'accent' },
5586
6598
  { id: 'push', icon: 'push', key: 'toolbar.push', tone: 'success' },
5587
- /* VS Code-style "..." menu: view mode, sort, and every repository action
5588
- that has no rail button of its own. A rail action (not a chrome
5589
- button) so the user can hide/move it like any other, per invariant 14. */
5590
- { id: 'more', icon: 'more', key: 'toolbar.more', tone: 'secondary' },
6599
+ /* The ⋯ menu moved to the changes-section header (user correction,
6600
+ 2026-10-10: the SCM ▸ menu lives where the changes live, not on the
6601
+ rail). Nothing else about the menu changed. */
5591
6602
  ]
5592
6603
  const RAIL_IDS = RAIL_SPECS.map((spec) => spec.id)
5593
6604
  /* Actions that arrange the view rather than touch the repository, so a running
@@ -7225,12 +8236,16 @@ window.__ModuleLoader__.load({
7225
8236
  branch: ['M4 3.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z', 'M12 3.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z', 'M4 6.5v3a3 3 0 0 0 3 3h2', 'M12 6.5v1a3 3 0 0 1-3 3'],
7226
8237
  commit: ['M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5Z', 'M8 1.5v4', 'M8 10.5v4'],
7227
8238
  refresh: ['M13 8a5 5 0 1 1-1.6-3.7', 'M13 3v3h-3'],
7228
- fetch: ['M8 2v8', 'M4.5 6.5 8 10l3.5-3.5', 'M3 13h10'],
7229
- // pull mirrors push: arrow INTO the local side (down) with the rail on top,
7230
- // where fetch keeps its arrow against the bottom rail. Both used to point up,
7231
- // so pull read as "push" in the rail (reported on v0.3.9).
7232
- pull: ['M8 3v8', 'M4.5 7.5 8 11l3.5-3.5', 'M3 2h10'],
7233
- push: ['M8 2v8', 'M4.5 5.5 8 2l3.5 3.5', 'M3 13h10'],
8239
+ /* Sync icons redrawn after the VS Code SCM trio (user request, 2026-10-10:
8240
+ the colour-coding alone was too abstract). All three share the SAME
8241
+ ground rail at the bottom (the local side) and differ only in the
8242
+ arrow, so the shape alone tells the actions apart:
8243
+ fetch — a BROKEN stem: the references come down, nothing is merged;
8244
+ pull — a solid stem pointing down: the remote lands here;
8245
+ push — a solid stem pointing up: the local goes out. */
8246
+ fetch: ['M8 2v1.6', 'M8 4.8v1.6', 'M8 7.7v1.6', 'M4.6 6.4 8 9.8l3.4-3.4', 'M3 13h10'],
8247
+ pull: ['M8 2v7.8', 'M4.6 6.4 8 9.8l3.4-3.4', 'M3 13h10'],
8248
+ push: ['M8 9.8V2.2', 'M4.6 5.6 8 2.2l3.4 3.4', 'M3 13h10'],
7234
8249
  plus: ['M8 3v10', 'M3 8h10'],
7235
8250
  minus: ['M3 8h10'],
7236
8251
  undo: ['M5 6H2V3', 'M2.5 6.5a5.5 5.5 0 1 1 1.8 5'],
@@ -7239,6 +8254,12 @@ window.__ModuleLoader__.load({
7239
8254
  star: ['M8 2.2l1.8 3.8 4 .5-2.9 2.7.8 4-3.7-2.1-3.7 2.1.8-4L2.2 6.5l4-.5z'],
7240
8255
  folder: ['M2 4.5h4l1.2 1.5H14v6.5H2z'],
7241
8256
  file: ['M4 2h5l3 3v9H4z', 'M9 2v3h3'],
8257
+ /* diff follows the codicon-diff anatomy: a document whose right half
8258
+ carries a + above a −, so it reads as "what changed" and not just
8259
+ "a file". newBranch is the branch glyph with a small + at the new
8260
+ growth tip (codicon git-branch-create's idea at 16px). */
8261
+ diff: ['M3.5 2h6l3.5 3.5V14h-9.5z', 'M9.5 2v3.5H13', 'M8 6.2v3', 'M6.5 7.7h3', 'M6.5 11h3'],
8262
+ branchCreate: ['M4 3.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z', 'M11.5 3.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Z', 'M4 6.5v3a3 3 0 0 0 3 3h2.2', 'M11.5 6.5v1.5', 'M13.2 10.6v3.8', 'M11.3 12.5h3.8'],
7242
8263
  trash: ['M3 5h10', 'M6.5 5V3.5h3V5', 'M4.5 5l.6 8.5h5.8L11.5 5', 'M6.8 7v4', 'M9.2 7v4'],
7243
8264
  checkout: ['M3 8h7', 'M7.5 5.5 10 8l-2.5 2.5', 'M13 3.5v9'],
7244
8265
  compare: ['M4 4h7', 'M4 12h7', 'M6.5 1.5 4 4l2.5 2.5', 'M9.5 9.5 12 12l-2.5 2.5'],
@@ -7290,13 +8311,18 @@ window.__ModuleLoader__.load({
7290
8311
  the panel box, and the menu scrolls when it is taller than the room left. */
7291
8312
  function ContextMenu(props) {
7292
8313
  const ref = useRef(null)
8314
+ const cardRef = useRef(null)
7293
8315
  const closeRef = useRef(props.onClose)
7294
8316
  const [position, setPosition] = useState({ left: props.anchor.x, top: props.anchor.y })
8317
+ /* The open submenu: { items, top, flip } or null. Hover-driven — moving
8318
+ onto a different parent row swaps or closes it, so no timers are
8319
+ needed. Horizontal placement is pure CSS against the wrapper. */
8320
+ const [sub, setSub] = useState(null)
7295
8321
  useEffect(() => { closeRef.current = props.onClose })
7296
8322
  // Layout effect: the clamp below runs before the browser paints, so the menu
7297
8323
  // never flashes at its raw (possibly out-of-panel) anchor position.
7298
8324
  useLayoutEffect(() => {
7299
- const element = ref.current
8325
+ const element = cardRef.current
7300
8326
  if (element === null) return
7301
8327
  const rect = element.getBoundingClientRect()
7302
8328
  const width = props.boundsWidth === undefined ? 0 : props.boundsWidth
@@ -7321,37 +8347,65 @@ window.__ModuleLoader__.load({
7321
8347
  document.removeEventListener('keydown', onKey)
7322
8348
  }
7323
8349
  }, [])
8350
+ /* Hover onto a parent row opens its submenu flush with the row's right
8351
+ edge (VS Code's SCM ▸ pattern); when the panel has no room to the
8352
+ right the submenu flips to the left edge. Only the TOP level opens
8353
+ submenus — hovering rows inside the submenu never re-enters here. */
8354
+ const openSub = (item, inSub, event) => {
8355
+ if (inSub === true || Array.isArray(item.items) !== true || item.items.length === 0) return
8356
+ const card = cardRef.current
8357
+ if (card === null) return
8358
+ const cardRect = card.getBoundingClientRect()
8359
+ const itemRect = event.currentTarget.getBoundingClientRect()
8360
+ const bounds = props.boundsWidth === undefined ? 0 : props.boundsWidth
8361
+ /* Direction only — the flush offset is CSS (`left:100%` / `right:100%`
8362
+ against the wrapper, whose width IS the parent card), so the seam is
8363
+ zero no matter how wide the submenu actually renders. */
8364
+ const flip = bounds > 0 && position.left + cardRect.width + 220 > bounds - 4
8365
+ setSub({ items: item.items, flip: flip, top: Math.max(0, itemRect.top - cardRect.top - 4) })
8366
+ }
8367
+ const renderItem = (item, index, inSub) => {
8368
+ if (item === null) return E('div', { key: 'sep-' + index, className: 'dig-menu-sep' })
8369
+ const hasSub = inSub !== true && Array.isArray(item.items) === true && item.items.length > 0
8370
+ return E('button', {
8371
+ key: item.id + '-' + index + (inSub === true ? '-sub' : ''),
8372
+ type: 'button',
8373
+ title: item.disabled === true && item.reason !== undefined ? item.reason : '',
8374
+ className: 'dig-menu-item'
8375
+ + (item.danger === true ? ' dig-menu-danger' : '')
8376
+ + (item.disabled === true ? ' dig-menu-disabled' : '')
8377
+ + (item.active === true ? ' dig-menu-item-active' : ''),
8378
+ // The row keeps its id on the DOM so a `⋯ 更多` entry is addressable
8379
+ // (the rail's own buttons do the same; probes click through either).
8380
+ 'data-action': item.id === undefined ? undefined : item.id,
8381
+ disabled: item.disabled === true,
8382
+ onMouseEnter: (event) => openSub(item, inSub, event),
8383
+ onClick: (event) => {
8384
+ if (hasSub === true) return // a submenu parent opens on hover; the click must not close the menu
8385
+ closeRef.current(); item.run(event)
8386
+ },
8387
+ },
8388
+ item.icon === undefined ? null : E('span', { className: 'dig-menu-icon dig-tone-' + (item.tone === undefined ? 'secondary' : item.tone) }, E(Icon, { name: item.icon, size: 13 })),
8389
+ E('span', { className: 'dig-menu-label' }, item.label),
8390
+ hasSub === true ? E('span', { className: 'dig-menu-chevron' }, E(Icon, { name: 'chevron', size: 10 })) : null)
8391
+ }
7324
8392
  /* Two boxes on purpose (dsh 0.1.7-rc.2 menu-material contract): the outer
7325
8393
  card owns the material (a `::before` painted on its own layer, so the
7326
8394
  backdrop filter never becomes the containing block or backdrop root of
7327
8395
  the rows) and the inner box owns the scroll. `data-menu-material` is the
7328
8396
  theme's hook for the dark-menu stroke rebind — the same hook the shipped
7329
- MenuSurface sets. The card must stay a plain `position: absolute` box
8397
+ MenuSurface sets. Everything stays a plain `position: absolute` box
7330
8398
  inside `.dig-root`: panel-internal positioning is an invariant (13), and
7331
- a portal to `document.body` would land outside the panel. */
7332
- return E('div', {
7333
- className: 'dig-menu', ref: ref, 'data-menu-material': 'translucent',
7334
- style: { left: position.left + 'px', top: position.top + 'px' },
7335
- },
7336
- E('div', { className: 'dig-menu-scroll' },
7337
- props.items.map((item, index) => (item === null
7338
- ? E('div', { key: 'sep-' + index, className: 'dig-menu-sep' })
7339
- : E('button', {
7340
- key: item.id + '-' + index,
7341
- type: 'button',
7342
- title: item.disabled === true && item.reason !== undefined ? item.reason : '',
7343
- className: 'dig-menu-item'
7344
- + (item.danger === true ? ' dig-menu-danger' : '')
7345
- + (item.disabled === true ? ' dig-menu-disabled' : '')
7346
- + (item.active === true ? ' dig-menu-item-active' : ''),
7347
- // The row keeps its id on the DOM so a `⋯ 更多` entry is addressable
7348
- // (the rail's own buttons do the same; probes click through either).
7349
- 'data-action': item.id === undefined ? undefined : item.id,
7350
- disabled: item.disabled === true,
7351
- onClick: (event) => { closeRef.current(); item.run(event) },
7352
- },
7353
- item.icon === undefined ? null : E('span', { className: 'dig-menu-icon dig-tone-' + (item.tone === undefined ? 'secondary' : item.tone) }, E(Icon, { name: item.icon, size: 13 })),
7354
- E('span', { className: 'dig-menu-label' }, item.label))))))
8399
+ a portal to `document.body` would land outside the panel. The submenu is
8400
+ a second card inside the same wrapper, so outside-click and Escape cover
8401
+ both without extra wiring. */
8402
+ return E('div', { className: 'dig-menu-wrap', ref: ref, style: { left: position.left + 'px', top: position.top + 'px' } },
8403
+ E('div', { className: 'dig-menu', ref: cardRef, 'data-menu-material': 'translucent' },
8404
+ E('div', { className: 'dig-menu-scroll' },
8405
+ props.items.map((item, index) => renderItem(item, index, false)))),
8406
+ sub === null ? null : E('div', { className: 'dig-menu dig-menu-sub', 'data-menu-material': 'translucent', style: sub.flip === true ? { right: '100%', top: sub.top + 'px' } : { left: '100%', top: sub.top + 'px' } },
8407
+ E('div', { className: 'dig-menu-scroll' },
8408
+ sub.items.map((item, index) => renderItem(item, index, true)))))
7355
8409
  }
7356
8410
 
7357
8411
  /* Lets the user choose which actions the rail shows and in which order. The
@@ -8387,7 +9441,11 @@ window.__ModuleLoader__.load({
8387
9441
  const groupBy = props.groupBy === 'dir' ? 'dir' : 'flat'
8388
9442
  const setGroupBy = props.onGroupBy
8389
9443
  const sortKey = props.sortKey === undefined ? 'git' : props.sortKey
8390
- const [foldedDirs, setFoldedDirs] = useState({})
9444
+ /* foldedDirs lifted too (v0.16.1): the header row lost its four buttons —
9445
+ everything they did lives in the ⋯ menu now, so the menu drives this
9446
+ state directly through props. */
9447
+ const foldedDirs = props.foldedDirs === undefined ? {} : props.foldedDirs
9448
+ const setFoldedDirs = props.onFoldedDirs
8391
9449
  const changes = summary === null ? null : summary.changes
8392
9450
  const conflicted = changes === null ? [] : changes.conflicted
8393
9451
  const staged = changes === null ? [] : changes.staged
@@ -8515,14 +9573,6 @@ window.__ModuleLoader__.load({
8515
9573
  let used = 0
8516
9574
  while (winLast < changeItems.length && used < winLimit) { used += changeItems[winLast].h; winLast += 1 }
8517
9575
  const visibleItems = changeItems.slice(winFirst, winLast)
8518
- const foldAll = (value) => {
8519
- const next = {}
8520
- if (value === true) {
8521
- const groups = [['conflicted', conflicted], ['staged', staged], ['unstaged', unstaged], ['untracked', untracked], ['ignored', ignored]]
8522
- for (const pair of groups) for (const item of pair[1]) next[pair[0] + '|' + folderOf(item)] = true
8523
- }
8524
- setFoldedDirs(next)
8525
- }
8526
9576
  const aiConfirmDialog = aiAsk !== true ? null : E(ConfirmDialog, {
8527
9577
  t: t,
8528
9578
  title: t('changes.aiOverwriteTitle'),
@@ -8601,28 +9651,18 @@ window.__ModuleLoader__.load({
8601
9651
  E('span', null, t('changes.title')),
8602
9652
  E('span', { className: 'dig-count' }, String(total))),
8603
9653
  E('span', { className: 'dig-topbar-spacer' }),
8604
- E('button', {
8605
- type: 'button',
8606
- className: 'dig-icon-btn dig-icon-btn-small' + (groupBy === 'dir' ? ' dig-icon-btn-active' : ''),
8607
- title: t('changes.groupBy') + ': ' + (groupBy === 'dir' ? t('changes.groupDir') : t('changes.groupFlat')),
8608
- onClick: () => setGroupBy((value) => (value === 'dir' ? 'flat' : 'dir')),
8609
- }, E(Icon, { name: 'folder', size: 13 })),
8610
- E('button', {
8611
- type: 'button', className: 'dig-icon-btn dig-icon-btn-small',
8612
- title: t('changes.expandAll'), disabled: groupBy !== 'dir',
8613
- onClick: () => foldAll(false),
8614
- }, E(Icon, { name: 'expand', size: 13 })),
8615
- E('button', {
8616
- type: 'button', className: 'dig-icon-btn dig-icon-btn-small',
8617
- title: t('changes.foldAll'), disabled: groupBy !== 'dir',
8618
- onClick: () => foldAll(true),
8619
- }, E(Icon, { name: 'collapse', size: 13 })),
8620
- E('button', {
9654
+ /* The four header toggles (group-by / expand / fold / ignored) moved
9655
+ INTO the ⋯ menu (v0.16.1, user request): one consistent entry point
9656
+ instead of five small buttons, same actions, same state. */
9657
+ props.onMoreMenu === undefined ? null : E('button', {
8621
9658
  type: 'button',
8622
- className: 'dig-icon-btn dig-icon-btn-small' + (props.showIgnored === true ? ' dig-icon-btn-active' : ''),
8623
- title: t('changes.showIgnored'),
8624
- onClick: () => props.onToggleIgnored(),
8625
- }, E(Icon, { name: props.showIgnored === true ? 'eye' : 'eyeOff', size: 13 })))
9659
+ /* Same 24px footprint and 15px glyph as the rail buttons above — the
9660
+ user asked for one consistent size across both rows. */
9661
+ className: 'dig-icon-btn',
9662
+ title: t('toolbar.more'),
9663
+ 'data-action': 'more',
9664
+ onClick: (event) => props.onMoreMenu(event),
9665
+ }, E(Icon, { name: 'more', size: 15 })))
8626
9666
  return E('div', { className: 'dig-changes' },
8627
9667
  aiConfirmDialog,
8628
9668
  head,
@@ -9438,18 +10478,44 @@ window.__ModuleLoader__.load({
9438
10478
  return data
9439
10479
  }, [base, pathFilter])
9440
10480
 
9441
- const refresh = useCallback(async () => {
10481
+ /* `fetchRemote` turns the refresh into what the rail button means: "see
10482
+ whether the remote has anything new to pull" — a `git fetch --prune`
10483
+ runs first so ahead/behind land with the fresh summary. Only the
10484
+ MANUAL refresh passes it: the network call is the slow part, so the
10485
+ automatic refreshes (12s poll, post-action, mount) stay off it, and a
10486
+ failed fetch degrades silently — a refresh must not turn into an
10487
+ error banner just because the network is down. While it runs the rail
10488
+ icon spins: fetching is allowed to take a moment, and the spin says
10489
+ the wait is real while blocking a second click. */
10490
+ /* Declared before refresh (hooks dep TDZ rule): the manual refresh
10491
+ fetches only when a remote exists. */
10492
+ const remoteReady = branches !== null && Array.isArray(branches.remotes) && branches.remotes.length > 0
10493
+ const [refreshSpinning, setRefreshSpinning] = useState(false)
10494
+ /* Fold state of the per-directory groups, lifted from ChangesPanel so the
10495
+ ⋯ menu's 展开全部/折叠全部 entries drive the same map the folder
10496
+ headers toggle. */
10497
+ const [foldedDirs, setFoldedDirs] = useState({})
10498
+ const refresh = useCallback(async (opts) => {
9442
10499
  if (repoRoot === null) return
9443
- await guard(async () => {
9444
- const [summaryData, branchesData, page] = await Promise.all([loadSummary(), loadBranches(), loadCommits(0)])
9445
- /* The write side of the first-paint cache: exactly the FIRST page
9446
- (a paged fetch never reaches this path), replaced on every
9447
- refresh — the auto-refresh included — so a session switch through
9448
- the same workspace seeds fresh data, not the mount-time
9449
- snapshot. */
9450
- writePaintPage(repoRoot, { summary: summaryData, branches: branchesData, commits: page.commits, hasMore: page.hasMore })
9451
- })
9452
- }, [guard, loadSummary, loadBranches, loadCommits, repoRoot])
10500
+ const withFetch = opts !== null && typeof opts === 'object' && opts.fetchRemote === true && remoteReady === true
10501
+ if (withFetch === true) setRefreshSpinning(true)
10502
+ try {
10503
+ await guard(async () => {
10504
+ if (withFetch === true) {
10505
+ try { await request('fetch', Object.assign({}, base, { prune: true })) } catch (error) { void error }
10506
+ }
10507
+ const [summaryData, branchesData, page] = await Promise.all([loadSummary(), loadBranches(), loadCommits(0)])
10508
+ /* The write side of the first-paint cache: exactly the FIRST page
10509
+ (a paged fetch never reaches this path), replaced on every
10510
+ refresh — the auto-refresh included — so a session switch through
10511
+ the same workspace seeds fresh data, not the mount-time
10512
+ snapshot. */
10513
+ writePaintPage(repoRoot, { summary: summaryData, branches: branchesData, commits: page.commits, hasMore: page.hasMore })
10514
+ })
10515
+ } finally {
10516
+ if (withFetch === true) setRefreshSpinning(false)
10517
+ }
10518
+ }, [guard, loadSummary, loadBranches, loadCommits, repoRoot, remoteReady, base])
9453
10519
 
9454
10520
  useEffect(() => {
9455
10521
  if (repoRoot === null) return undefined
@@ -9914,6 +10980,16 @@ window.__ModuleLoader__.load({
9914
10980
  if (state.kind === 'renameBranch') { await run('branchRename', { from: state.from, to: value }); return }
9915
10981
  if (state.kind === 'newTag') { await run('tagCreate', { name: value, hash: state.hash }); return }
9916
10982
  if (state.kind === 'deleteTag') { await run('tagDelete', { name: value }); return }
10983
+ /* SCM ▸ Commit ▸ variants: one dialog, four (all/staged × amend/sign)
10984
+ shapes. `all` stages every visible change first — the paths go in
10985
+ explicitly, never '.', so the host's root guard stays shut. */
10986
+ if (state.kind === 'commitMsg') {
10987
+ const paths = state.all === true
10988
+ ? summary === null ? [] : summary.changes.staged.concat(summary.changes.unstaged, summary.changes.untracked).map((entry) => entry.path)
10989
+ : undefined
10990
+ await run('commit', { message: value, paths: paths, amend: state.amend === true, signoff: state.sign === true })
10991
+ return
10992
+ }
9917
10993
  }, [run])
9918
10994
 
9919
10995
  /* ---------- toasts + undo ---------- */
@@ -9956,6 +11032,26 @@ window.__ModuleLoader__.load({
9956
11032
  })
9957
11033
  }, [run, pushToast, undoAction, t])
9958
11034
 
11035
+ /* SCM ▸ Changes ▸ Discard All Changes: tracked paths go through
11036
+ `checkout --`, untracked through `clean -fd`. Conflicted entries are
11037
+ deliberately NOT touched — a merge conflict needs a decision, not a
11038
+ silent side-taking; the dialog says so. */
11039
+ const discardAllChanges = useCallback(async () => {
11040
+ const changes = summary === null ? null : summary.changes
11041
+ if (changes === null) return
11042
+ const tracked = changes.unstaged.map((entry) => entry.path)
11043
+ const untracked = changes.untracked.map((entry) => entry.path)
11044
+ if (tracked.length > 0) await run('discard', { paths: tracked, confirm: true })
11045
+ if (untracked.length > 0) await run('discard', { paths: untracked, untracked: true, confirm: true })
11046
+ }, [run, summary])
11047
+
11048
+ /* SCM ▸ Commit ▸ Undo Last Commit: a soft reset to HEAD~1 keeps the
11049
+ commit's work staged, exactly like VS Code's undo. The commit leaves
11050
+ the branch but stays in the reflog — no undo handle needed. */
11051
+ const undoLastCommit = useCallback(async () => {
11052
+ await run('reset', { hash: 'HEAD~1', mode: 'soft', confirm: true })
11053
+ }, [run])
11054
+
9959
11055
  // A discard really overwrote the working tree, so it hands back the same
9960
11056
  // kind of handle a delete does: the host snapshotted the bytes first.
9961
11057
  const discardChanges = useCallback(async (item, group) => {
@@ -10063,27 +11159,6 @@ window.__ModuleLoader__.load({
10063
11159
  E('span', { className: 'dig-banner-text' }, note),
10064
11160
  E('button', { type: 'button', className: 'dig-link', onClick: () => setNote(null) }, t('error.dismiss')))
10065
11161
 
10066
- const commitSettings = readCommitSettings()
10067
- const changesPane = E(ChangesPanel, {
10068
- t: t, summary: summary, busy: busy, compact: compact, hideHeader: compact,
10069
- groupBy: groupBy, sortKey: sortKey, onGroupBy: setGroupBy,
10070
- request: request, cwd: cwd, sessionId: sessionId, commitSettings: commitSettings, base: base,
10071
- showIgnored: showIgnored,
10072
- onToggleIgnored: () => setShowIgnored((value) => !value),
10073
- // Commit-and-push carries the confirm flag with it: the button already
10074
- // says exactly what it will publish, so the host guard is satisfied by
10075
- // the click itself rather than by a second dialog.
10076
- onCommit: (message, amend, push) => {
10077
- void run('commit', { message: message, amend: amend, push: push === true, confirm: push === true })
10078
- },
10079
- onStage: (item) => { void run('stage', { paths: [item.path] }) },
10080
- onUnstage: (item) => { void run('unstage', { paths: [item.path] }) },
10081
- onStageAll: (entries) => { void run('stage', { paths: entries.map((entry) => entry.path) }) },
10082
- onUnstageAll: () => { void run('unstage', { paths: (summary === null ? [] : summary.changes.staged).map((entry) => entry.path) }) },
10083
- onDiscard: (item, group) => setDialog({ kind: 'discard', item: item, group: group }),
10084
- onDiff: (item, group) => { showDiff({ path: item.path, staged: group === 'staged', untracked: group === 'untracked' }) },
10085
- onChangeMenu: changeMenu,
10086
- })
10087
11162
 
10088
11163
  const historyPane = view === 'detail'
10089
11164
  ? E(CommitDetail, {
@@ -10131,11 +11206,34 @@ window.__ModuleLoader__.load({
10131
11206
  run: () => {
10132
11207
  if (kind === 'checkout') { void run('checkout', { branch: entry.name }); return }
10133
11208
  if (kind === 'delete') { setDialog({ kind: 'deleteBranch', name: entry.name }); return }
11209
+ if (kind === 'merge') { void run('merge', { branch: entry.name }); return }
11210
+ if (kind === 'rebase') { void run('rebase', { onto: entry.name }); return }
10134
11211
  void compareWith(current, entry.name)
10135
11212
  },
10136
11213
  })))
10137
11214
  }
10138
11215
 
11216
+ /* Remote branches (origin/main…): a flat menu, each entry pre-split into
11217
+ its remote and branch halves for the destructive confirm. */
11218
+ const remoteBranches = branches === null ? [] : branches.remote
11219
+ const pickRemoteBranchMenu = (event) => {
11220
+ if (remoteBranches.length === 0) { setNote(t('note.noBranches')); return }
11221
+ openMenuAt(event, remoteBranches.map((entry) => {
11222
+ const slash = entry.name.indexOf('/')
11223
+ const remote = slash >= 0 ? entry.name.slice(0, slash) : entry.name
11224
+ const branch = slash >= 0 ? entry.name.slice(slash + 1) : entry.name
11225
+ return {
11226
+ id: 'remote-delete:' + entry.name,
11227
+ icon: 'trash', tone: 'danger', danger: true,
11228
+ label: entry.name,
11229
+ run: () => setDialog({ kind: 'deleteRemoteBranch', remote: remote, branch: branch }),
11230
+ }
11231
+ }))
11232
+ }
11233
+
11234
+ /* Remotes themselves, for "pull from" / "push to" style entries. */
11235
+ const remoteNames = branches === null ? [] : branches.remotes.map((entry) => entry.name === undefined ? String(entry) : entry.name)
11236
+
10139
11237
  const showWorkingDiff = () => {
10140
11238
  const changes = summary === null ? null : summary.changes
10141
11239
  if (changes === null) return
@@ -10164,7 +11262,6 @@ window.__ModuleLoader__.load({
10164
11262
 
10165
11263
  /* favorites/toggleFavoriteBranch live above branchMenu: a useCallback dep array is evaluated during render. */
10166
11264
  const headBranch = branches === null ? '' : branches.branch
10167
- const remoteReady = branches !== null && Array.isArray(branches.remotes) && branches.remotes.length > 0
10168
11265
  const tracked = summary !== null && summary.upstream !== null
10169
11266
  const stashCount = summary === null ? 0 : summary.stashCount
10170
11267
  const reason = t('action.unavailable')
@@ -10173,43 +11270,183 @@ window.__ModuleLoader__.load({
10173
11270
  changes, branch/stash/tag shortcuts, and the Git-output view at the
10174
11271
  bottom. Every entry reuses the very handlers the rail rows and group
10175
11272
  heads already run, so the menu can never disagree with them. */
11273
+ /* The ⋯ menu, restructured to the FULL VS Code SCM ▸ tree (issue: the
11274
+ flat 22-item list ignored the submenu anatomy the user asked for).
11275
+ Groups are real submenus now (ContextMenu.items[]); every entry maps
11276
+ onto an action that already exists elsewhere in the panel, and the
11277
+ few new backend verbs (rebaseAbort / remoteAdd / remoteRemove /
11278
+ branchDeleteRemote / tagDeleteRemote / pushTags / stashClear) back
11279
+ their VS Code counterparts one-to-one. */
10176
11280
  const moreMenu = (event) => {
10177
11281
  const tagCount = branches === null || Array.isArray(branches.tags) !== true ? 0 : branches.tags.length
10178
11282
  const stageable = summary === null ? [] : summary.changes.unstaged.concat(summary.changes.untracked)
10179
11283
  const stagedPaths = summary === null ? [] : summary.changes.staged.map((entry) => entry.path)
11284
+ const allChangePaths = stagedPaths.concat(stageable.map((entry) => entry.path))
10180
11285
  const sort = (key) => () => setSortKey(key)
11286
+ const operation = summary === null ? null : summary.operation
11287
+ const pickRemote = (run) => (ev) => openMenuAt(ev, remoteNames.map((name) => ({
11288
+ id: 'remote:' + name, icon: 'fetch', tone: 'violet', label: name,
11289
+ run: () => run(name),
11290
+ })))
11291
+ const pickStash = (verb) => async (ev) => {
11292
+ try {
11293
+ const data = await request('stashList', base)
11294
+ const list = Array.isArray(data.stashes) ? data.stashes : []
11295
+ if (list.length === 0) { setNote(t('stash.none')); return }
11296
+ openMenuAt(ev, list.map((entry) => ({
11297
+ id: 'stash:' + entry.ref, icon: 'stash', tone: 'violet',
11298
+ label: entry.ref + ' · ' + entry.subject,
11299
+ run: () => { void run('stashApply', { ref: entry.ref, pop: verb === 'pop' }) },
11300
+ })))
11301
+ } catch (error) { void error }
11302
+ }
10181
11303
  openMenuAt(event, [
11304
+ /* —— view (VS Code: 以列表形式查看 / 查看和排序 ▸) —— */
10182
11305
  { id: 'view-flat', icon: 'commit', tone: 'secondary', label: t('changes.groupFlat'), active: groupBy === 'flat', run: () => setGroupBy('flat') },
10183
11306
  { id: 'view-dir', icon: 'folder', tone: 'secondary', label: t('changes.groupDir'), active: groupBy === 'dir', run: () => setGroupBy('dir') },
11307
+ { id: 'view-sort', icon: 'compare', tone: 'secondary', label: t('more.sort'), items: [
11308
+ { id: 'sort-git', label: t('more.sortGit'), active: sortKey === 'git', run: sort('git') },
11309
+ { id: 'sort-path', label: t('more.sortPath'), active: sortKey === 'path', run: sort('path') },
11310
+ { id: 'sort-name', label: t('more.sortName'), active: sortKey === 'name', run: sort('name') },
11311
+ { id: 'sort-status', label: t('more.sortStatus'), active: sortKey === 'status', run: sort('status') },
11312
+ null,
11313
+ /* The old header toggles live here now (v0.16.1): fold/unfold need
11314
+ the directory map, which only exists when grouping is on. */
11315
+ { id: 'view-expand', label: t('changes.expandAll'), disabled: groupBy !== 'dir', reason, run: () => setFoldedDirs({}) },
11316
+ { id: 'view-fold', label: t('changes.foldAll'), disabled: groupBy !== 'dir', reason, run: () => {
11317
+ const next = {}
11318
+ const changes = summary === null ? null : summary.changes
11319
+ if (changes !== null) {
11320
+ const groups = [['conflicted', changes.conflicted], ['staged', changes.staged], ['unstaged', changes.unstaged], ['untracked', changes.untracked], ['ignored', changes.ignored === undefined ? [] : changes.ignored]]
11321
+ for (const pair of groups) {
11322
+ for (const item of pair[1]) {
11323
+ const dir = dirName(item.path)
11324
+ next[pair[0] + '|' + (dir === '' ? t('changes.rootDir') : dir)] = true
11325
+ }
11326
+ }
11327
+ }
11328
+ setFoldedDirs(next)
11329
+ } },
11330
+ null,
11331
+ { id: 'view-ignored', label: t('changes.showIgnored'), active: showIgnored === true, run: () => setShowIgnored(showIgnored !== true) },
11332
+ ] },
10184
11333
  null,
10185
- { id: 'sort-git', icon: 'commit', tone: 'secondary', label: t('more.sortGit'), active: sortKey === 'git', run: sort('git') },
10186
- { id: 'sort-path', icon: 'commit', tone: 'secondary', label: t('more.sortPath'), active: sortKey === 'path', run: sort('path') },
10187
- { id: 'sort-name', icon: 'commit', tone: 'secondary', label: t('more.sortName'), active: sortKey === 'name', run: sort('name') },
10188
- { id: 'sort-status', icon: 'commit', tone: 'secondary', label: t('more.sortStatus'), active: sortKey === 'status', run: sort('status') },
10189
- null,
11334
+ /* —— top-level sync (VS Code header row) —— */
10190
11335
  { id: 'mm-pull', icon: 'pull', tone: 'accent', label: t('toolbar.pull'), disabled: remoteReady !== true || tracked !== true || blocked, reason, run: () => { void run('pull', { mode: 'ff-only' }) } },
10191
11336
  { id: 'mm-push', icon: 'push', tone: 'success', label: t('toolbar.push'), disabled: remoteReady !== true || blocked, reason, run: () => setDialog({ kind: 'push' }) },
10192
- { id: 'mm-fetch', icon: 'fetch', tone: 'cyan', label: t('toolbar.fetch'), disabled: remoteReady !== true, reason, run: () => { void run('fetch', { prune: true }) } },
10193
- { id: 'mm-checkout', icon: 'checkout', tone: 'accent', label: t('action.checkout') + '...', disabled: otherBranches.length === 0 || blocked, reason, run: (ev) => pickBranchMenu(ev, 'checkout') },
10194
11337
  { id: 'mm-clone', icon: 'plus', tone: 'secondary', label: t('more.clone'), run: () => setDialog({ kind: 'clone' }) },
11338
+ { id: 'mm-checkout', icon: 'checkout', tone: 'accent', label: t('action.checkout') + '...', disabled: otherBranches.length === 0 || blocked, reason, run: (ev) => pickBranchMenu(ev, 'checkout') },
11339
+ { id: 'mm-fetch', icon: 'fetch', tone: 'cyan', label: t('toolbar.fetch'), disabled: remoteReady !== true, reason, run: () => { void run('fetch', { prune: true }) } },
10195
11340
  null,
10196
- { id: 'mm-stage-all', icon: 'plus', tone: 'success', label: t('changes.stageAll'), disabled: stageable.length === 0, reason, run: () => { void run('stage', { paths: stageable.map((entry) => entry.path) }) } },
10197
- { id: 'mm-unstage-all', icon: 'minus', tone: 'warn', label: t('changes.unstageAll'), disabled: stagedPaths.length === 0, reason, run: () => { void run('unstage', { paths: stagedPaths }) } },
10198
- null,
10199
- { id: 'mm-new-branch', icon: 'plus', tone: 'success', label: t('toolbar.newBranch'), disabled: blocked, reason, run: () => setDialog({ kind: 'newBranch' }) },
10200
- { id: 'mm-delete-branch', icon: 'trash', tone: 'danger', danger: true, label: t('action.delete'), disabled: otherBranches.length === 0, reason, run: (ev) => pickBranchMenu(ev, 'delete') },
10201
- null,
10202
- { id: 'mm-stash-push', icon: 'stash', tone: 'violet', label: t('stash.push'), disabled: dirty === 0, reason, run: () => { void run('stashPush', { includeUntracked: true }) } },
10203
- { id: 'mm-stash-apply', icon: 'checkout', tone: 'accent', label: t('stash.apply'), disabled: stashCount === 0, reason, run: () => { void run('stashApply', {}) } },
10204
- { id: 'mm-stash-pop', icon: 'stash', tone: 'accent', label: t('more.stashPop'), disabled: stashCount === 0, reason, run: () => { void run('stashApply', { pop: true }) } },
10205
- { id: 'mm-stash-drop', icon: 'trash', tone: 'danger', danger: true, label: t('stash.drop'), disabled: stashCount === 0, reason, run: () => setDialog({ kind: 'stashDrop', ref: 'stash@{0}' }) },
10206
- null,
10207
- { id: 'mm-new-tag', icon: 'tag', tone: 'warn', label: t('action.newTagHere'), disabled: commits.length === 0, reason, run: () => setDialog({ kind: 'newTag' }) },
10208
- { id: 'mm-delete-tag', icon: 'trash', tone: 'danger', danger: true, label: t('more.deleteTag'), disabled: tagCount === 0, reason, run: () => setDialog({ kind: 'deleteTag' }) },
11341
+ /* —— SCM ▸ Commit ▸ —— */
11342
+ { id: 'sub-commit', icon: 'commit', tone: 'accent', label: t('more.commitGroup'), items: [
11343
+ { id: 'c-staged', label: t('more.commitStaged'), disabled: stagedPaths.length === 0, reason, run: () => setDialog({ kind: 'commitMsg', all: false, amend: false, sign: false }) },
11344
+ { id: 'c-all', label: t('more.commitAll'), disabled: allChangePaths.length === 0, reason, run: () => setDialog({ kind: 'commitMsg', all: true, amend: false, sign: false }) },
11345
+ null,
11346
+ { id: 'c-undo', label: t('more.undoCommit'), disabled: commits.length === 0 || blocked, reason, run: () => setDialog({ kind: 'undoCommit' }) },
11347
+ { id: 'c-abort', label: t('more.rebaseAbort'), disabled: operation !== 'rebase', reason, run: () => { void run('rebaseAbort', {}) } },
11348
+ null,
11349
+ { id: 'c-staged-amend', label: t('more.commitStagedAmend'), disabled: stagedPaths.length === 0 || commits.length === 0, reason, run: () => setDialog({ kind: 'commitMsg', all: false, amend: true, sign: false }) },
11350
+ { id: 'c-all-amend', label: t('more.commitAllAmend'), disabled: allChangePaths.length === 0 || commits.length === 0, reason, run: () => setDialog({ kind: 'commitMsg', all: true, amend: true, sign: false }) },
11351
+ null,
11352
+ { id: 'c-staged-sign', label: t('more.commitStagedSign'), disabled: stagedPaths.length === 0, reason, run: () => setDialog({ kind: 'commitMsg', all: false, amend: false, sign: true }) },
11353
+ { id: 'c-all-sign', label: t('more.commitAllSign'), disabled: allChangePaths.length === 0, reason, run: () => setDialog({ kind: 'commitMsg', all: true, amend: false, sign: true }) },
11354
+ ] },
11355
+ /* —— SCM ▸ Changes ▸ —— */
11356
+ { id: 'sub-changes', icon: 'file', tone: 'secondary', label: t('more.changesGroup'), items: [
11357
+ { id: 'ch-stage', label: t('changes.stageAll'), disabled: stageable.length === 0, reason, run: () => { void run('stage', { paths: stageable.map((entry) => entry.path) }) } },
11358
+ { id: 'ch-unstage', label: t('changes.unstageAll'), disabled: stagedPaths.length === 0, reason, run: () => { void run('unstage', { paths: stagedPaths }) } },
11359
+ null,
11360
+ { id: 'ch-discard', label: t('more.discardAll'), danger: true, disabled: dirty === 0, reason, run: () => setDialog({ kind: 'discardAll' }) },
11361
+ ] },
11362
+ /* —— SCM ▸ Pull, Push ▸ —— */
11363
+ { id: 'sub-pullpush', icon: 'pull', tone: 'accent', label: t('more.pullpushGroup'), items: [
11364
+ { id: 'pp-sync', label: t('more.sync'), disabled: remoteReady !== true || tracked !== true || blocked, reason, run: () => { void (async () => { await run('pull', { mode: 'ff-only' }); await run('push', { confirm: true }) })() } },
11365
+ { id: 'pp-sync-rebase', label: t('more.syncRebase'), disabled: remoteReady !== true || tracked !== true || blocked, reason, run: () => { void (async () => { await run('pull', { mode: 'rebase' }); await run('push', { confirm: true }) })() } },
11366
+ null,
11367
+ { id: 'pp-pull', label: t('toolbar.pull'), disabled: remoteReady !== true || tracked !== true || blocked, reason, run: () => { void run('pull', { mode: 'ff-only' }) } },
11368
+ { id: 'pp-pull-rebase', label: t('more.pullRebase'), disabled: remoteReady !== true || tracked !== true || blocked, reason, run: () => { void run('pull', { mode: 'rebase' }) } },
11369
+ { id: 'pp-pull-from', label: t('more.pullFrom'), disabled: remoteNames.length === 0, reason, run: pickRemote((name) => { void run('pull', { mode: 'ff-only', remote: name }) }) },
11370
+ null,
11371
+ { id: 'pp-push', label: t('toolbar.push'), disabled: remoteReady !== true || blocked, reason, run: () => setDialog({ kind: 'push' }) },
11372
+ { id: 'pp-push-force', label: t('more.pushForce'), danger: true, disabled: remoteReady !== true || blocked, reason, run: () => setDialog({ kind: 'pushForce' }) },
11373
+ { id: 'pp-push-to', label: t('more.pushTo'), disabled: remoteNames.length === 0 || blocked, reason, run: pickRemote((name) => { void run('push', { remote: name, confirm: true }) }) },
11374
+ null,
11375
+ { id: 'pp-fetch', label: t('toolbar.fetch'), disabled: remoteReady !== true, reason, run: () => { void run('fetch', { prune: true }) } },
11376
+ { id: 'pp-fetch-all', label: t('more.fetchAll'), disabled: remoteNames.length === 0, reason, run: () => { void run('fetch', { all: true, prune: true }) } },
11377
+ ] },
11378
+ /* —— SCM ▸ Branch ▸ —— */
11379
+ { id: 'sub-branch', icon: 'branch', tone: 'secondary', label: t('more.branchGroup'), items: [
11380
+ { id: 'br-merge', label: t('action.mergeIntoCurrent'), disabled: otherBranches.length === 0 || blocked, reason, run: (ev) => pickBranchMenu(ev, 'merge') },
11381
+ { id: 'br-rebase', label: t('action.rebaseCurrentOnto'), disabled: otherBranches.length === 0 || blocked, reason, run: (ev) => pickBranchMenu(ev, 'rebase') },
11382
+ null,
11383
+ { id: 'br-new', label: t('toolbar.newBranch'), disabled: blocked, reason, run: () => setDialog({ kind: 'newBranch' }) },
11384
+ null,
11385
+ { id: 'br-rename', label: t('action.rename'), disabled: headBranch === '' || blocked, reason, run: () => setDialog({ kind: 'renameBranch', from: headBranch }) },
11386
+ { id: 'br-delete', label: t('action.delete'), danger: true, disabled: otherBranches.length === 0, reason, run: (ev) => pickBranchMenu(ev, 'delete') },
11387
+ { id: 'br-delete-remote', label: t('more.deleteRemoteBranch'), danger: true, disabled: remoteBranches.length === 0 || blocked, reason, run: (ev) => pickRemoteBranchMenu(ev) },
11388
+ null,
11389
+ { id: 'br-publish', label: t('more.publish'), disabled: remoteReady !== true || tracked === true || blocked, reason, run: () => { void run('push', { setUpstream: true, confirm: true }) } },
11390
+ ] },
11391
+ /* —— SCM ▸ Remote ▸ —— */
11392
+ { id: 'sub-remote', icon: 'fetch', tone: 'violet', label: t('more.remoteGroup'), items: [
11393
+ { id: 'rm-add', label: t('more.addRemote'), run: () => setDialog({ kind: 'remoteAdd' }) },
11394
+ { id: 'rm-remove', label: t('more.removeRemote'), danger: true, disabled: remoteNames.length === 0, reason, run: (ev) => openMenuAt(ev, remoteNames.map((name) => ({
11395
+ id: 'rm-del:' + name, icon: 'trash', tone: 'danger', danger: true, label: name,
11396
+ run: () => setDialog({ kind: 'remoteRemove', name: name }),
11397
+ }))) },
11398
+ ] },
11399
+ /* —— SCM ▸ Stash ▸ —— */
11400
+ { id: 'sub-stash', icon: 'stash', tone: 'violet', label: t('more.stashGroup'), items: [
11401
+ { id: 'st-push', label: t('more.stashTracked'), disabled: dirty === 0, reason, run: () => { void run('stashPush', {}) } },
11402
+ { id: 'st-push-all', label: t('stash.push'), disabled: dirty === 0, reason, run: () => { void run('stashPush', { includeUntracked: true }) } },
11403
+ { id: 'st-push-staged', label: t('more.stashStaged'), disabled: stagedPaths.length === 0, reason, run: () => { void run('stashPush', { staged: true }) } },
11404
+ null,
11405
+ { id: 'st-apply', label: t('stash.apply'), disabled: stashCount === 0, reason, run: () => { void run('stashApply', {}) } },
11406
+ { id: 'st-apply-pick', label: t('more.stashApplyPick'), disabled: stashCount === 0, reason, run: pickStash('apply') },
11407
+ null,
11408
+ { id: 'st-pop', label: t('more.stashPop'), disabled: stashCount === 0, reason, run: () => { void run('stashApply', { pop: true }) } },
11409
+ { id: 'st-pop-pick', label: t('more.stashPopPick'), disabled: stashCount === 0, reason, run: pickStash('pop') },
11410
+ null,
11411
+ { id: 'st-drop', label: t('more.stashDropAny'), danger: true, disabled: stashCount === 0, reason, run: (ev) => pickStash('drop')(ev) },
11412
+ { id: 'st-clear', label: t('more.stashClear'), danger: true, disabled: stashCount === 0, reason, run: () => setDialog({ kind: 'stashClear' }) },
11413
+ ] },
11414
+ /* —— SCM ▸ Tags ▸ —— */
11415
+ { id: 'sub-tags', icon: 'tag', tone: 'warn', label: t('more.tagGroup'), items: [
11416
+ { id: 'tg-new', label: t('action.newTagHere'), disabled: commits.length === 0, reason, run: () => setDialog({ kind: 'newTag' }) },
11417
+ { id: 'tg-delete', label: t('more.deleteTag'), danger: true, disabled: tagCount === 0, reason, run: () => setDialog({ kind: 'deleteTag' }) },
11418
+ { id: 'tg-delete-remote', label: t('more.tagDeleteRemote'), danger: true, disabled: tagCount === 0 || remoteNames.length === 0 || blocked, reason, run: () => setDialog({ kind: 'deleteRemoteTag' }) },
11419
+ null,
11420
+ { id: 'tg-push', label: t('more.pushTags'), disabled: tagCount === 0 || remoteNames.length === 0 || blocked, reason, run: () => setDialog({ kind: 'pushTags' }) },
11421
+ ] },
10209
11422
  null,
10210
11423
  { id: 'mm-git-output', icon: 'commit', tone: 'secondary', label: t('more.gitOutput'), run: () => { void openGitOutput() } },
10211
11424
  ])
10212
11425
  }
11426
+ const commitSettings = readCommitSettings()
11427
+ const changesPane = E(ChangesPanel, {
11428
+ t: t, summary: summary, busy: busy, compact: compact, hideHeader: compact,
11429
+ groupBy: groupBy, sortKey: sortKey, onGroupBy: setGroupBy,
11430
+ foldedDirs: foldedDirs, onFoldedDirs: setFoldedDirs,
11431
+ onMoreMenu: moreMenu,
11432
+ request: request, cwd: cwd, sessionId: sessionId, commitSettings: commitSettings, base: base,
11433
+ showIgnored: showIgnored,
11434
+ onToggleIgnored: () => setShowIgnored((value) => !value),
11435
+ // Commit-and-push carries the confirm flag with it: the button already
11436
+ // says exactly what it will publish, so the host guard is satisfied by
11437
+ // the click itself rather than by a second dialog.
11438
+ onCommit: (message, amend, push) => {
11439
+ void run('commit', { message: message, amend: amend, push: push === true, confirm: push === true })
11440
+ },
11441
+ onStage: (item) => { void run('stage', { paths: [item.path] }) },
11442
+ onUnstage: (item) => { void run('unstage', { paths: [item.path] }) },
11443
+ onStageAll: (entries) => { void run('stage', { paths: entries.map((entry) => entry.path) }) },
11444
+ onUnstageAll: () => { void run('unstage', { paths: (summary === null ? [] : summary.changes.staged).map((entry) => entry.path) }) },
11445
+ onDiscard: (item, group) => setDialog({ kind: 'discard', item: item, group: group }),
11446
+ onDiff: (item, group) => { showDiff({ path: item.path, staged: group === 'staged', untracked: group === 'untracked' }) },
11447
+ onChangeMenu: changeMenu,
11448
+ })
11449
+
10213
11450
 
10214
11451
  /* One descriptor per action, with the availability IDEA would use: delete /
10215
11452
  checkout / compare need another local branch, fetch and push need a remote,
@@ -10217,7 +11454,7 @@ window.__ModuleLoader__.load({
10217
11454
  The rail renders a user-chosen subset in a user-chosen order. */
10218
11455
  const railActions = RAIL_SPECS.map((spec) => {
10219
11456
  const entry = { id: spec.id, icon: spec.icon, tone: spec.tone, label: t(spec.key), disabled: false, active: false, run: () => {} }
10220
- if (spec.id === 'refresh') entry.run = () => setTick((value) => value + 1)
11457
+ if (spec.id === 'refresh') { entry.disabled = refreshSpinning === true; entry.spinning = refreshSpinning === true; entry.run = () => { void refresh({ fetchRemote: true }) } }
10221
11458
  else if (spec.id === 'newBranch') entry.run = () => setDialog({ kind: 'newBranch' })
10222
11459
  else if (spec.id === 'checkout') { entry.disabled = otherBranches.length === 0 || blocked; entry.run = (event) => pickBranchMenu(event, 'checkout') }
10223
11460
  else if (spec.id === 'delete') { entry.disabled = otherBranches.length === 0; entry.run = (event) => pickBranchMenu(event, 'delete') }
@@ -10229,7 +11466,6 @@ window.__ModuleLoader__.load({
10229
11466
  else if (spec.id === 'fetch') { entry.disabled = remoteReady !== true; entry.run = () => { void run('fetch', { prune: true }) } }
10230
11467
  else if (spec.id === 'pull') { entry.disabled = remoteReady !== true || tracked !== true || blocked; entry.run = () => { void run('pull', { mode: 'ff-only' }) } }
10231
11468
  else if (spec.id === 'push') { entry.disabled = remoteReady !== true || blocked; entry.run = () => setDialog({ kind: 'push' }) }
10232
- else if (spec.id === 'more') { entry.run = (event) => moreMenu(event) }
10233
11469
  else if (spec.id === 'tree') { entry.active = treeOpen; entry.run = () => foldTree(!treeOpen) }
10234
11470
  else if (spec.id === 'float') {
10235
11471
  // Label AND icon follow where the panel actually is: floating panels get
@@ -10326,7 +11562,7 @@ window.__ModuleLoader__.load({
10326
11562
  const children = railVisible.slice(0, slots).map((action) => E('button', {
10327
11563
  key: action.id,
10328
11564
  type: 'button',
10329
- className: 'dig-rail-btn dig-tone-' + action.tone + (action.active === true ? ' dig-rail-btn-active' : ''),
11565
+ className: 'dig-rail-btn dig-tone-' + action.tone + (action.active === true ? ' dig-rail-btn-active' : '') + (action.spinning === true ? ' dig-spin' : ''),
10330
11566
  'data-action': action.id,
10331
11567
  'aria-pressed': action.active === true ? 'true' : 'false',
10332
11568
  title: action.disabled === true ? action.label + ' · ' + reason : action.label,
@@ -10461,8 +11697,8 @@ window.__ModuleLoader__.load({
10461
11697
  onClose: () => setRailSettings(false),
10462
11698
  }))
10463
11699
  }
10464
- if (dialog !== null && (dialog.kind === 'newBranch' || dialog.kind === 'renameBranch' || dialog.kind === 'newTag' || dialog.kind === 'deleteTag')) {
10465
- const titles = { newBranch: t('prompt.newBranch'), renameBranch: t('prompt.renameBranch'), newTag: t('prompt.newTag'), deleteTag: t('prompt.deleteTag') }
11700
+ if (dialog !== null && (dialog.kind === 'newBranch' || dialog.kind === 'renameBranch' || dialog.kind === 'newTag' || dialog.kind === 'deleteTag' || dialog.kind === 'commitMsg')) {
11701
+ const titles = { newBranch: t('prompt.newBranch'), renameBranch: t('prompt.renameBranch'), newTag: t('prompt.newTag'), deleteTag: t('prompt.deleteTag'), commitMsg: t('prompt.commitMessage') }
10466
11702
  overlays.push(E(PromptDialog, {
10467
11703
  key: 'prompt',
10468
11704
  title: titles[dialog.kind],
@@ -10484,6 +11720,101 @@ window.__ModuleLoader__.load({
10484
11720
  onSubmit: (url, dir) => { setDialog(null); void run('clone', { url: url, dir: dir }) },
10485
11721
  }))
10486
11722
  }
11723
+ /* SCM ▸ additions (v0.15): each destructive one is a ConfirmDialog whose
11724
+ text names the exact target; the tag/remote ones carry the picked
11725
+ remote through. */
11726
+ if (dialog !== null && dialog.kind === 'undoCommit') {
11727
+ overlays.push(E(ConfirmDialog, {
11728
+ key: 'undoCommit', t: t,
11729
+ title: t('confirm.title'),
11730
+ text: t('confirm.undoCommit'),
11731
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11732
+ onCancel: () => setDialog(null),
11733
+ onConfirm: () => { setDialog(null); void undoLastCommit() },
11734
+ }))
11735
+ }
11736
+ if (dialog !== null && dialog.kind === 'discardAll') {
11737
+ overlays.push(E(ConfirmDialog, {
11738
+ key: 'discardAll', t: t,
11739
+ title: t('confirm.title'),
11740
+ text: t('confirm.discardAll'),
11741
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11742
+ onCancel: () => setDialog(null),
11743
+ onConfirm: () => { setDialog(null); void discardAllChanges() },
11744
+ }))
11745
+ }
11746
+ if (dialog !== null && dialog.kind === 'pushForce') {
11747
+ overlays.push(E(ConfirmDialog, {
11748
+ key: 'pushForce', t: t,
11749
+ title: t('confirm.title'),
11750
+ text: t('confirm.pushForce'),
11751
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11752
+ onCancel: () => setDialog(null),
11753
+ onConfirm: () => { setDialog(null); void run('push', { force: true, confirm: true }) },
11754
+ }))
11755
+ }
11756
+ if (dialog !== null && dialog.kind === 'deleteRemoteBranch') {
11757
+ overlays.push(E(ConfirmDialog, {
11758
+ key: 'deleteRemoteBranch', t: t,
11759
+ title: t('confirm.title'),
11760
+ text: fill(t('confirm.deleteRemoteBranch'), { remote: dialog.remote, branch: dialog.branch }),
11761
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11762
+ onCancel: () => setDialog(null),
11763
+ onConfirm: () => { const r = dialog.remote; const b = dialog.branch; setDialog(null); void run('branchDeleteRemote', { remote: r, branch: b, confirm: true }) },
11764
+ }))
11765
+ }
11766
+ if (dialog !== null && dialog.kind === 'remoteAdd') {
11767
+ overlays.push(E(CloneDialog, {
11768
+ key: 'remoteAdd',
11769
+ title: t('more.addRemote'),
11770
+ urlPlaceholder: t('prompt.remoteName'),
11771
+ dirPlaceholder: t('prompt.remoteUrl'),
11772
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11773
+ onCancel: () => setDialog(null),
11774
+ onSubmit: (name, url) => { setDialog(null); void run('remoteAdd', { name: name, url: url }) },
11775
+ }))
11776
+ }
11777
+ if (dialog !== null && dialog.kind === 'remoteRemove') {
11778
+ overlays.push(E(ConfirmDialog, {
11779
+ key: 'remoteRemove', t: t,
11780
+ title: t('confirm.title'),
11781
+ text: fill(t('confirm.remoteRemove'), { name: dialog.name }),
11782
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11783
+ onCancel: () => setDialog(null),
11784
+ onConfirm: () => { const n = dialog.name; setDialog(null); void run('remoteRemove', { name: n, confirm: true }) },
11785
+ }))
11786
+ }
11787
+ if (dialog !== null && dialog.kind === 'stashClear') {
11788
+ overlays.push(E(ConfirmDialog, {
11789
+ key: 'stashClear', t: t,
11790
+ title: t('confirm.title'),
11791
+ text: t('confirm.stashClear'),
11792
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11793
+ onCancel: () => setDialog(null),
11794
+ onConfirm: () => { setDialog(null); void run('stashClear', { confirm: true }) },
11795
+ }))
11796
+ }
11797
+ if (dialog !== null && dialog.kind === 'deleteRemoteTag') {
11798
+ overlays.push(E(PromptDialog, {
11799
+ key: 'deleteRemoteTag',
11800
+ title: t('more.tagDeleteRemote'),
11801
+ placeholder: fill(t('prompt.deleteRemoteTag'), { remote: remoteNames[0] === undefined ? 'origin' : remoteNames[0] }),
11802
+ initialValue: '',
11803
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11804
+ onCancel: () => setDialog(null),
11805
+ onSubmit: (name) => { setDialog(null); void run('tagDeleteRemote', { remote: remoteNames[0] === undefined ? 'origin' : remoteNames[0], name: name, confirm: true }) },
11806
+ }))
11807
+ }
11808
+ if (dialog !== null && dialog.kind === 'pushTags') {
11809
+ overlays.push(E(ConfirmDialog, {
11810
+ key: 'pushTags', t: t,
11811
+ title: t('confirm.title'),
11812
+ text: fill(t('confirm.pushTags'), { remote: remoteNames[0] === undefined ? 'origin' : remoteNames[0] }),
11813
+ okLabel: t('confirm.ok'), cancelLabel: t('confirm.cancel'),
11814
+ onCancel: () => setDialog(null),
11815
+ onConfirm: () => { setDialog(null); void run('pushTags', { remote: remoteNames[0] === undefined ? 'origin' : remoteNames[0], confirm: true }) },
11816
+ }))
11817
+ }
10487
11818
  if (dialog !== null && dialog.kind === 'deleteBranch') {
10488
11819
  const guarded = isProtectedBranch(dialog.name)
10489
11820
  overlays.push(E(ConfirmDialog, {
@@ -10611,6 +11942,9 @@ window.__ModuleLoader__.load({
10611
11942
  )
10612
11943
  }
10613
11944
  LANE_TRACE_RULES.push('.dig-graph line,.dig-graph path,.dig-graph circle{transition:stroke-opacity .15s,fill-opacity .15s}')
11945
+ /* The rail refresh button spins while its fetch+refresh round-trip runs. */
11946
+ LANE_TRACE_RULES.push('.dig-spin svg{animation:dig-spin-rotate .9s linear infinite}')
11947
+ LANE_TRACE_RULES.push('@keyframes dig-spin-rotate{to{transform:rotate(360deg)}}')
10614
11948
 
10615
11949
  const CSS = [
10616
11950
  '.dig-root{position:relative;display:flex;flex-direction:column;height:100%;min-height:0;background:transparent;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family,system-ui,sans-serif);font-size:13px;line-height:1.5;font-weight:600;overflow:hidden}',
@@ -10913,10 +12247,19 @@ window.__ModuleLoader__.load({
10913
12247
  '.dig-dialog-text{color:var(--dsw-alias-label-secondary);white-space:pre-wrap}',
10914
12248
  '.dig-dialog-actions{display:flex;justify-content:flex-end;gap:8px}',
10915
12249
  '.dig-dialog-actions .dig-btn-primary{margin-left:0}',
10916
- '.dig-menu{position:absolute;z-index:70;box-sizing:border-box;min-width:min(200px,calc(100% - 8px));max-width:calc(100% - 8px);max-height:calc(100% - 8px);padding:4px;border:0;border-radius:var(--dsw-radius-md,12px);background:transparent;box-shadow:var(--dsw-elevation-prominent,0 10px 28px rgba(0,0,0,.35));--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);isolation:isolate;display:flex;flex-direction:column}',
12250
+ /* The wrapper carries the panel-relative anchor and the outside-click ref,
12251
+ plus the ONLY percentage widths (its containing block is .dig-root, so
12252
+ `max-width` resolves against the panel — on the card it would resolve
12253
+ against the shrink-to-fit wrapper and collapse the menu, cutting labels).
12254
+ The submenu is a second card offset to the parent card's edge, flipping
12255
+ left when the panel runs out of room (see ContextMenu.openSub). */
12256
+ '.dig-menu-wrap{position:absolute;z-index:70;width:max-content;max-width:calc(100% - 8px)}',
12257
+ '.dig-menu{box-sizing:border-box;min-width:200px;max-height:calc(100% - 8px);padding:4px;border:0;border-radius:var(--dsw-radius-md,12px);background:transparent;box-shadow:var(--dsw-elevation-prominent,0 10px 28px rgba(0,0,0,.35));--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);isolation:isolate;display:flex;flex-direction:column}',
12258
+ '.dig-menu-sub{position:absolute;min-width:180px;max-width:300px;z-index:71}',
10917
12259
  '.dig-menu::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--dsw-specific-menu,var(--dsw-alias-bg-layer-2,var(--dsw-alias-bg-layer-1)));-webkit-backdrop-filter:var(--dsw-menu-backdrop-filter,blur(14px) saturate(1.2));backdrop-filter:var(--dsw-menu-backdrop-filter,blur(14px) saturate(1.2));pointer-events:none}',
10918
12260
  '.dig-menu-scroll{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;display:flex;flex-direction:column}',
10919
12261
  '.dig-menu-item{display:flex;align-items:center;gap:8px;padding:4px 8px;border:none;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-weight:500;text-align:left;border-radius:var(--dsw-radius-sm,8px);cursor:pointer;white-space:nowrap;overflow:hidden}',
12262
+ '.dig-menu-chevron{margin-left:auto;opacity:.6;flex:none;display:inline-flex}',
10920
12263
  '.dig-menu-icon{display:inline-flex;flex:none}',
10921
12264
  '.dig-menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis}',
10922
12265
  '.dig-menu-item:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}',