diff --git a/README.md b/README.md index d63886ed..aacf222e 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ * Supports Windows/macOS/Linux * Opensource/Free * Fast -* Deutsch/English/Español/Français/Italiano/Português/Русский/简体中文/繁體中文 +* Deutsch/English/Español/Français/Italiano/Português/Русский/简体中文/繁體中文/日本語 * Built-in light/dark themes * Customize theme * Visual commit graph diff --git a/TRANSLATION.md b/TRANSLATION.md index 341fdce0..b344e6a3 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -24,23 +24,9 @@ This document shows the translation status of each locale file in the repository -### ![es__ES](https://img.shields.io/badge/es__ES-99.87%25-yellow) +### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen) -
-Missing keys in es_ES.axaml - -- Text.CopyFullPath - -
- -### ![fr__FR](https://img.shields.io/badge/fr__FR-99.87%25-yellow) - -
-Missing keys in fr_FR.axaml - -- Text.CopyFullPath - -
+### ![fr__FR](https://img.shields.io/badge/fr__FR-%E2%88%9A-brightgreen) ### ![it__IT](https://img.shields.io/badge/it__IT-99.73%25-yellow) @@ -52,6 +38,16 @@ This document shows the translation status of each locale file in the repository +### ![ja__JP](https://img.shields.io/badge/ja__JP-99.73%25-yellow) + +
+Missing keys in ja_JP.axaml + +- Text.Repository.FilterCommits +- Text.Repository.Tags.OrderByNameDes + +
+ ### ![pt__BR](https://img.shields.io/badge/pt__BR-90.98%25-yellow)
diff --git a/VERSION b/VERSION index 75c26f38..8283ecf3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2025.11 \ No newline at end of file +2025.12 \ No newline at end of file diff --git a/src/App.axaml b/src/App.axaml index 76d4baa8..fdfa8e07 100644 --- a/src/App.axaml +++ b/src/App.axaml @@ -20,6 +20,7 @@ + diff --git a/src/Commands/CompareRevisions.cs b/src/Commands/CompareRevisions.cs index e311a88e..c3206767 100644 --- a/src/Commands/CompareRevisions.cs +++ b/src/Commands/CompareRevisions.cs @@ -6,8 +6,10 @@ namespace SourceGit.Commands { public partial class CompareRevisions : Command { - [GeneratedRegex(@"^([MADRC])\s+(.+)$")] + [GeneratedRegex(@"^([MADC])\s+(.+)$")] private static partial Regex REG_FORMAT(); + [GeneratedRegex(@"^R[0-9]{0,4}\s+(.+)$")] + private static partial Regex REG_RENAME_FORMAT(); public CompareRevisions(string repo, string start, string end) { @@ -38,7 +40,17 @@ namespace SourceGit.Commands { var match = REG_FORMAT().Match(line); if (!match.Success) + { + match = REG_RENAME_FORMAT().Match(line); + if (match.Success) + { + var renamed = new Models.Change() { Path = match.Groups[1].Value }; + renamed.Set(Models.ChangeState.Renamed); + _changes.Add(renamed); + } + return; + } var change = new Models.Change() { Path = match.Groups[2].Value }; var status = match.Groups[1].Value; @@ -57,10 +69,6 @@ namespace SourceGit.Commands change.Set(Models.ChangeState.Deleted); _changes.Add(change); break; - case 'R': - change.Set(Models.ChangeState.Renamed); - _changes.Add(change); - break; case 'C': change.Set(Models.ChangeState.Copied); _changes.Add(change); diff --git a/src/Commands/QueryStashChanges.cs b/src/Commands/QueryStashChanges.cs index 7fc27ea3..92240569 100644 --- a/src/Commands/QueryStashChanges.cs +++ b/src/Commands/QueryStashChanges.cs @@ -9,8 +9,10 @@ namespace SourceGit.Commands /// public partial class QueryStashChanges : Command { - [GeneratedRegex(@"^([MADRC])\s+(.+)$")] + [GeneratedRegex(@"^([MADC])\s+(.+)$")] private static partial Regex REG_FORMAT(); + [GeneratedRegex(@"^R[0-9]{0,4}\s+(.+)$")] + private static partial Regex REG_RENAME_FORMAT(); public QueryStashChanges(string repo, string stash) { @@ -31,7 +33,17 @@ namespace SourceGit.Commands { var match = REG_FORMAT().Match(line); if (!match.Success) + { + match = REG_RENAME_FORMAT().Match(line); + if (match.Success) + { + var renamed = new Models.Change() { Path = match.Groups[1].Value }; + renamed.Set(Models.ChangeState.Renamed); + outs.Add(renamed); + } + continue; + } var change = new Models.Change() { Path = match.Groups[2].Value }; var status = match.Groups[1].Value; @@ -50,10 +62,6 @@ namespace SourceGit.Commands change.Set(Models.ChangeState.Deleted); outs.Add(change); break; - case 'R': - change.Set(Models.ChangeState.Renamed); - outs.Add(change); - break; case 'C': change.Set(Models.ChangeState.Copied); outs.Add(change); diff --git a/src/Models/DateTimeFormat.cs b/src/Models/DateTimeFormat.cs index 4e71a74f..4e8aa550 100644 --- a/src/Models/DateTimeFormat.cs +++ b/src/Models/DateTimeFormat.cs @@ -32,17 +32,17 @@ namespace SourceGit.Models public static readonly List Supported = new List { - new DateTimeFormat("yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss"), - new DateTimeFormat("yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss"), - new DateTimeFormat("yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss"), - new DateTimeFormat("MM/dd/yyyy", "MM/dd/yyyy HH:mm:ss"), - new DateTimeFormat("MM.dd.yyyy", "MM.dd.yyyy HH:mm:ss"), - new DateTimeFormat("MM-dd-yyyy", "MM-dd-yyyy HH:mm:ss"), - new DateTimeFormat("dd/MM/yyyy", "dd/MM/yyyy HH:mm:ss"), - new DateTimeFormat("dd.MM.yyyy", "dd.MM.yyyy HH:mm:ss"), - new DateTimeFormat("dd-MM-yyyy", "dd-MM-yyyy HH:mm:ss"), - new DateTimeFormat("MMM d yyyy", "MMM d yyyy HH:mm:ss"), - new DateTimeFormat("d MMM yyyy", "d MMM yyyy HH:mm:ss"), + new DateTimeFormat("yyyy/MM/dd", "yyyy/MM/dd, HH:mm:ss"), + new DateTimeFormat("yyyy.MM.dd", "yyyy.MM.dd, HH:mm:ss"), + new DateTimeFormat("yyyy-MM-dd", "yyyy-MM-dd, HH:mm:ss"), + new DateTimeFormat("MM/dd/yyyy", "MM/dd/yyyy, HH:mm:ss"), + new DateTimeFormat("MM.dd.yyyy", "MM.dd.yyyy, HH:mm:ss"), + new DateTimeFormat("MM-dd-yyyy", "MM-dd-yyyy, HH:mm:ss"), + new DateTimeFormat("dd/MM/yyyy", "dd/MM/yyyy, HH:mm:ss"), + new DateTimeFormat("dd.MM.yyyy", "dd.MM.yyyy, HH:mm:ss"), + new DateTimeFormat("dd-MM-yyyy", "dd-MM-yyyy, HH:mm:ss"), + new DateTimeFormat("MMM d yyyy", "MMM d yyyy, HH:mm:ss"), + new DateTimeFormat("d MMM yyyy", "d MMM yyyy, HH:mm:ss"), }; private static readonly DateTime _example = new DateTime(2025, 1, 31, 8, 0, 0, DateTimeKind.Local); diff --git a/src/Models/Locales.cs b/src/Models/Locales.cs index d5e1534c..802e88ef 100644 --- a/src/Models/Locales.cs +++ b/src/Models/Locales.cs @@ -17,6 +17,7 @@ namespace SourceGit.Models new Locale("Русский", "ru_RU"), new Locale("简体中文", "zh_CN"), new Locale("繁體中文", "zh_TW"), + new Locale("日本語", "ja_JP"), }; public Locale(string name, string key) diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 5ff1e3a4..61140173 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -719,6 +719,7 @@ Trigger click event Commit (Edit) Stage all changes and commit + You have staged {0} file(s) but only {1} file(s) displayed ({2} files are filtered out). Do you want to continue? Empty commit detected! Do you want to continue (--allow-empty)? CONFLICTS DETECTED FILE CONFLICTS ARE RESOLVED diff --git a/src/Resources/Locales/es_ES.axaml b/src/Resources/Locales/es_ES.axaml index d8018097..8b4c350f 100644 --- a/src/Resources/Locales/es_ES.axaml +++ b/src/Resources/Locales/es_ES.axaml @@ -189,6 +189,7 @@ Copiar Copiar Todo el Texto Copiar Ruta + Copiar Ruta Completa Crear Rama... Basado En: Checkout de la rama creada diff --git a/src/Resources/Locales/fr_FR.axaml b/src/Resources/Locales/fr_FR.axaml index 70d0af22..bf238aa2 100644 --- a/src/Resources/Locales/fr_FR.axaml +++ b/src/Resources/Locales/fr_FR.axaml @@ -16,13 +16,19 @@ Suivre la branche : Suivi de la branche distante Assistant IA + RE-GÉNERER Utiliser l'IA pour générer un message de commit + APPLIQUER COMME MESSAGE DE COMMIT Appliquer Fichier de patch : Selectionner le fichier .patch à appliquer Ignorer les changements d'espaces blancs Appliquer le patch Espaces blancs : + Appliquer le Stash + Supprimer après application + Rétablir les changements de l'index + Stash: Archiver... Enregistrer l'archive sous : Sélectionnez le chemin du fichier d'archive @@ -39,6 +45,7 @@ Comparer avec HEAD Comparer avec le worktree Copier le nom de la branche + Action personnalisée Supprimer ${0}$... Supprimer {0} branches sélectionnées Rejeter tous les changements @@ -54,6 +61,7 @@ Renommer ${0}$... Définir la branche de suivi... Comparer les branches + Branche amont invalide ! Octets ANNULER Réinitialiser à la révision parente @@ -92,6 +100,7 @@ Récupérer ce commit Cherry-Pick ce commit Cherry-Pick ... + Checkout Commit Comparer avec HEAD Comparer avec le worktree Copier les informations @@ -150,10 +159,10 @@ Ajouter une règle d'exemple Gitee Ajouter une règle d'exemple pour Pull Request Gitee Ajouter une règle d'exemple Github - Ajouter une règle d'exemple Jira - Ajouter une règle d'exemple Azure DevOps Ajouter une règle d'exemple pour Incidents GitLab Ajouter une règle d'exemple pour Merge Request GitLab + Ajouter une règle d'exemple Jira + Ajouter une règle d'exemple Azure DevOps Nouvelle règle Issue Regex Expression: Nom de règle : @@ -179,6 +188,7 @@ Copier Copier tout le texte Copier le chemin + Copier le chemin complet Créer une branche... Basé sur : Récupérer la branche créée @@ -187,6 +197,7 @@ Stash & Réappliquer Nom de la nouvelle branche : Entrez le nom de la branche. + Les espaces seront remplacés par des tirets. Créer une branche locale Créer un tag... Nouveau tag à : @@ -583,13 +594,20 @@ Passer cette version Mise à jour du logiciel Il n'y a pas de mise à jour pour le moment. + Définir la branche de suivi + Branche : + Escamoter la branche amont + Branche amont: Copier le SHA - Squash Commits + Aller à + Squash les commits Dans : Clé privée SSH : Chemin du magasin de clés privées SSH START Stash + Auto-restauration après le stash + Vos fichiers de travail sont inchangés, mais un stash a été sauvegardé. Inclure les fichiers non-suivis Garder les fichiers indexés Message : @@ -599,6 +617,7 @@ Stash les changements locaux Appliquer Effacer + Sauver comme Patch... Effacer le Stash Effacer : Stashes diff --git a/src/Resources/Locales/ja_JP.axaml b/src/Resources/Locales/ja_JP.axaml new file mode 100644 index 00000000..21255221 --- /dev/null +++ b/src/Resources/Locales/ja_JP.axaml @@ -0,0 +1,747 @@ + + + + + 概要 + SourceGitについて + オープンソース & フリーなGit GUIクライアント + ワークツリーを追加 + チェックアウトする内容: + 既存のブランチ + 新しいブランチを作成 + 場所: + ワークツリーのパスを入力してください。相対パスも使用することができます。 + ブランチの名前: + 任意。デフォルトでは宛先フォルダ名が使用されます。 + 追跡するブランチ: + 追跡中のリモートブランチ + OpenAI アシスタント + 再生成 + OpenAIを使用してコミットメッセージを生成 + コミットメッセージとして適用 + 適用 + パッチファイル: + 適用する .patchファイルを選択 + 空白文字の変更を無視 + パッチを適用 + 空白文字: + スタッシュを適用 + 適用後に削除 + インデックスの変更を復元 + スタッシュ: + アーカイブ... + アーカイブの保存先: + アーカイブファイルのパスを選択 + リビジョン: + アーカイブ + SourceGit Askpass + 変更されていないとみなされるファイル + 変更されていないとみなされるファイルはありません + 削除 + バイナリファイルはサポートされていません!!! + Blame + BLAMEではこのファイルはサポートされていません!!! + ${0}$ をチェックアウトする... + HEADと比較 + ワークツリーと比較 + ブランチ名をコピー + カスタムアクション + ${0}$を削除... + 選択中の{0}個のブランチを削除 + すべての変更を破棄 + ${0}$ へ早送りする + ${0}$ から ${1}$ へフェッチする + Git Flow - Finish ${0}$ + ${0}$ を ${1}$ にマージする... + 選択中の{0}個のブランチを現在のブランチにマージする + ${0}$ をプルする + ${0}$ を ${1}$ にプルする... + ${0}$ をプッシュする + ${0}$ を ${1}$ でリベースする... + ${0}$ をリネームする... + トラッキングブランチを設定... + ブランチの比較 + 無効な上流ブランチ! + バイト + キャンセル + このリビジョンにリセット + 親リビジョンにリセット + コミットメッセージを生成 + 変更表示の切り替え + ファイルとディレクトリのリストを表示 + パスのリストを表示 + ファイルシステムのツリーを表示 + ブランチをチェックアウト + コミットをチェックアウト + 警告: コミットをチェックアウトするとHEADが切断されます + コミット: + ブランチ: + ローカルの変更: + 破棄 + スタッシュして再適用 + チェリーピック + ソースをコミットメッセージに追加 + コミット(複数可): + すべての変更をコミット + メインライン: + 通常、マージをチェリーピックすることはできません。どちらのマージ元をメインラインとして扱うべきかが分からないためです。このオプションを使用すると、指定した親に対して変更を再適用する形でチェリーピックを実行できます。 + スタッシュをクリア + すべてのスタッシュをクリアします。続行しますか? + リモートリポジトリをクローン + 追加の引数: + リポジトリをクローンする際の追加パラメータ(任意)。 + ローカル名: + リポジトリの名前(任意)。 + 親フォルダ: + サブモジュールを初期化して更新 + リポジトリのURL: + 閉じる + エディタ + このコミットをチェリーピック + チェリーピック... + コミットをチェックアウト + HEADと比較 + ワークツリーと比較 + 情報をコピー + SHAをコピー + カスタムアクション + ${0}$ ブランチをここにインタラクティブリベース + ${0}$ にマージ + マージ... + ${0}$ をここにリベース + ${0}$ ブランチをここにリセット + コミットを戻す + 書き直す + パッチとして保存... + 親にスカッシュ + 子コミットをここにスカッシュ + 変更 + 変更を検索... + ファイル + LFSファイル + ファイルを検索... + サブモジュール + コミットの情報 + 著者 + 変更 + + コミッター + このコミットを含む参照を確認 + コミットが含まれるか確認 + 最初の100件の変更のみが表示されています。すべての変更は'変更'タブで確認できます。 + メッセージ + + 参照 + SHA + ブラウザで開く + コミットのタイトルを入力 + 説明 + リポジトリの設定 + コミットテンプレート + テンプレート名: + テンプレート内容: + カスタムアクション + 引数: + ${REPO} - リポジトリのパス; ${BRANCH} - 選択中のブランチ; ${SHA} - 選択中のコミットのSHA + 実行ファイル: + 名前: + スコープ: + ブランチ + コミット + リポジトリ + アクションの終了を待機 + Eメールアドレス + Eメールアドレス + GIT + 自動的にリモートからフェッチ 間隔: + 分(s) + リモートの初期値 + ISSUEトラッカー + サンプルのGitee Issueルールを追加 + サンプルのGiteeプルリクエストルールを追加 + サンプルのGithubルールを追加 + サンプルのGitLab Issueルールを追加 + サンプルのGitLabマージリクエストルールを追加 + サンプルのJiraルールを追加 + サンプルのAzure DevOpsルールを追加 + 新しいルール + Issueの正規表現: + ルール名: + リザルトURL: + 正規表現のグループ値に$1, $2を使用してください。 + AI + 優先するサービス: + 優先するサービスが設定されている場合、SourceGitはこのリポジトリでのみそれを使用します。そうでない場合で複数サービスが利用できる場合は、そのうちの1つを選択するためのコンテキストメニューが表示されます。 + HTTP プロキシ + このリポジトリで使用するHTTPプロキシ + ユーザー名 + このリポジトリにおけるユーザー名 + ワークスペース + + 起動時にタブを復元 + Conventional Commitヘルパー + 破壊的変更: + 閉じたIssue: + 詳細な変更: + スコープ: + 短い説明: + 変更の種類: + コピー + すべてのテキストをコピー + パスをコピー + 絶対パスをコピー + ブランチを作成... + 派生元: + 作成したブランチにチェックアウト + ローカルの変更: + 破棄 + スタッシュして再適用 + 新しいブランチの名前: + ブランチの名前を入力 + スペースはダッシュに置き換えられます。 + ローカルブランチを作成 + タグを作成... + 付与されるコミット: + GPG署名を使用 + タグメッセージ: + 任意。 + タグの名前: + 推奨フォーマット: v1.0.0-alpha + 作成後にすべてのリモートにプッシュ + 新しいタグを作成 + 種類: + 注釈付き + 軽量 + Ctrlキーを押しながらクリックで実行 + 切り取り + ブランチを削除 + ブランチ: + リモートブランチを削除しようとしています!!! + もしリモートブランチを削除する場合、${0}$も削除します。 + 複数のブランチを削除 + 一度に複数のブランチを削除しようとしています! 操作を行う前に再度確認してください! + リモートを削除 + リモート: + パス: + 対象: + すべての子ノードがリストから削除されます。 + グループを削除 + これはリストからのみ削除され、ディスクには保存されません! + リポジトリを削除 + サブモジュールを削除 + サブモジュールのパス: + タグを削除 + タグ: + リモートリポジトリから削除 + バイナリの差分 + NEW + OLD + コピー + ファイルモードが変更されました + 先頭の差分 + 空白の変更を無視 + 最後の差分 + LFSオブジェクトの変更 + 次の差分 + 変更がない、もしくはEOLの変更のみ + 前の差分 + パッチとして保存 + 隠されたシンボルを表示 + 差分の分割表示 + サブモジュール + 新規 + スワップ + シンタックスハイライト + 行の折り返し + ブロックナビゲーションを有効化 + マージツールで開く + すべての行を表示 + 表示する行数を減らす + 表示する行数を増やす + ファイルを選択すると、変更内容が表示されます + マージツールで開く + 変更を破棄 + ワーキングディレクトリのすべての変更を破棄 + 変更: + 無視したファイルを含める + {0}個の変更を破棄します。 + この操作を元に戻すことはできません!!! + ブックマーク: + 新しい名前: + 対象: + 選択中のグループを編集 + 選択中のリポジトリを編集 + カスタムアクションを実行 + アクション名: + (チェックアウトせずに)ブランチを早送りする + フェッチ + すべてのリモートをフェッチ + ローカル参照を強制的に上書き + タグなしでフェッチ + リモート: + リモートの変更をフェッチ + 変更されていないとみなされる + 破棄... + {0}個のファイルを破棄... + 選択された行の変更を破棄 + 外部マージツールで開く + ${0}$ を使用して解決 + パッチとして保存... + ステージ + {0}個のファイルをステージ... + 選択された行の変更をステージ + スタッシュ... + {0}個のファイルをスタッシュ... + アンステージ + {0}個のファイルをアンステージ... + 選択された行の変更をアンステージ + 相手の変更を使用 (checkout --theirs) + 自分の変更を使用 (checkout --ours) + ファイルの履歴 + コンテンツ + 変更 + Git-Flow + 開発ブランチ: + Feature: + Feature プレフィックス: + FLOW - Finish Feature + FLOW - Finish Hotfix + FLOW - Finish Release + 対象: + Hotfix: + Hotfix プレフィックス: + Git-Flowを初期化 + ブランチを保持 + プロダクション ブランチ: + Release: + Release プレフィックス: + Start Feature... + FLOW - Start Feature + Start Hotfix... + FLOW - Start Hotfix + 名前を入力 + Start Release... + FLOW - Start Release + Versionタグ プレフィックス: + Git LFS + トラックパターンを追加... + パターンをファイル名として扱う + カスタム パターン: + Git LFSにトラックパターンを追加 + フェッチ + LFSオブジェクトをフェッチ + `git lfs fetch`を実行して、Git LFSオブジェクトをダウンロードします。ワーキングコピーは更新されません。 + Git LFSフックをインストール + ロックを表示 + ロックされているファイルはありません + ロック + 私のロックのみ表示 + LFSロック + ロック解除 + 強制的にロック解除 + 削除 + `git lfs prune`を実行して、ローカルの保存領域から古いLFSファイルを削除します。 + プル + LFSオブジェクトをプル + `git lfs pull`を実行して、現在の参照とチェックアウトのすべてのGit LFSファイルをダウンロードします。 + プッシュ + LFSオブジェクトをプッシュ + キュー内の大容量ファイルをGit LFSエンドポイントにプッシュします。 + リモート: + {0}という名前のファイルをトラック + すべての*{0}ファイルをトラック + 履歴 + 著者 + 著者時間 + グラフ & コミットのタイトル + SHA + 日時 + {0} コミットを選択しました + 'Ctrl'キーまたは'Shift'キーを押すと、複数のコミットを選択できます。 + ⌘ または ⇧ キーを押して複数のコミットを選択します。 + TIPS: + キーボードショートカットを確認 + 総合 + 現在のポップアップをキャンセル + 新しくリポジトリをクローン + 現在のページを閉じる + 前のページに移動 + 次のページに移動 + 新しいページを作成 + 設定ダイアログを開く + リポジトリ + ステージ済みの変更をコミット + ステージ済みの変更をコミットしてプッシュ + 全ての変更をステージしてコミット + 選択中のコミットから新たなブランチを作成 + 選択した変更を破棄 + 直接フェッチを実行 + ダッシュボードモード (初期値) + 直接プルを実行 + 直接プッシュを実行 + 現在のリポジトリを強制的に再読み込み + 選択中の変更をステージ/アンステージ + コミット検索モード + '変更'に切り替える + '履歴'に切り替える + 'スタッシュ'に切り替える + テキストエディタ + 検索パネルを閉じる + 次のマッチを検索 + 前のマッチを検索 + 検索パネルを開く + ステージ + アンステージ + 破棄 + リポジトリの初期化 + パス: + チェリーピックが進行中です。'中止'を押すと元のHEADが復元されます。 + コミットを処理中 + マージリクエストが進行中です。'中止'を押すと元のHEADが復元されます。 + マージ中 + リベースが進行中です。'中止'を押すと元のHEADが復元されます。 + 停止しました + 元に戻す処理が進行中です。'中止'を押すと元のHEADが復元されます。 + コミットを元に戻しています + インタラクティブ リベース + 対象のブランチ: + On: + ブラウザで開く + リンクをコピー + エラー + 通知 + ブランチのマージ + 宛先: + マージオプション: + ソースブランチ: + マージ (複数) + すべての変更をコミット + マージ戦略: + 対象: + リポジトリノードの移動 + 親ノードを選択: + 名前: + Gitが設定されていません。まず[設定]に移動して設定を行ってください。 + アプリケーションデータのディレクトリを開く + 外部ツールで開く... + 任意。 + 新しいページを開く + ブックマーク + タブを閉じる + 他のタブを閉じる + 右のタブを閉じる + リポジトリパスをコピー + リポジトリ + 貼り付け + たった今 + {0} 分前 + 1 時間前 + {0} 時間前 + 昨日 + {0} 日前 + 先月 + {0} ヶ月前 + 昨年 + {0} 年前 + 設定 + AI + 差分分析プロンプト + APIキー + タイトル生成プロンプト + モデル + 名前 + サーバー + ストリーミングを有効化 + 外観 + デフォルトのフォント + エディタのタブ幅 + フォントサイズ + デフォルト + エディタ + 等幅フォント + テキストエディタでは等幅フォントのみを使用する + テーマ + テーマの上書き + タイトルバーの固定タブ幅を使用 + ネイティブウィンドウフレームを使用 + 差分/マージ ツール + インストール パス + 差分/マージ ツールのパスを入力 + ツール + 総合 + 起動時にアップデートを確認 + 日時のフォーマット + 言語 + コミット履歴 + グラフにコミット時間の代わりに著者の時間を表示する + コミット詳細に子コミットを表示 + コミットグラフにタグを表示 + コミットタイトル枠の大きさ + GIT + 自動CRLFを有効化 + デフォルトのクローンディレクトリ + ユーザー Eメールアドレス + グローバルgitのEメールアドレス + フェッチ時に--pruneを有効化 + インストール パス + HTTP SSL 検証を有効にする + ユーザー名 + グローバルのgitユーザー名 + Gitバージョン + Git (>= 2.23.0) はこのアプリで必要です + GPG 署名 + コミットにGPG署名を行う + タグにGPG署名を行う + GPGフォーマット + プログラムのインストールパス + インストールされたgpgプログラムのパスを入力 + ユーザー署名キー + ユーザーのGPG署名キー + 統合 + シェル/ターミナル + シェル/ターミナル + パス + リモートを削除 + 対象: + 作業ツリーを削除 + `$GIT_DIR/worktrees` の作業ツリー情報を削除 + プル + ブランチ: + すべてのブランチをフェッチ + 宛先: + ローカルの変更: + 破棄 + スタッシュして再適用 + タグなしでフェッチ + リモート: + プル (フェッチ & マージ) + マージの代わりにリベースを使用 + プッシュ + サブモジュールがプッシュされていることを確認 + 強制的にプッシュ + ローカル ブランチ: + リモート: + 変更をリモートにプッシュ + リモート ブランチ: + 追跡ブランチとして設定 + すべてのタグをプッシュ + リモートにタグをプッシュ + すべてのリモートにプッシュ + リモート: + タグ: + 終了 + 現在のブランチをリベース + ローカルの変更をスタッシュして再適用 + On: + リベース: + 更新 + リモートを追加 + リモートを編集 + 名前: + リモートの名前 + リポジトリのURL: + リモートのgitリポジトリのURL + URLをコピー + 削除... + 編集... + フェッチ + ブラウザで開く + 削除 + ワークツリーの削除を確認 + `--force` オプションを有効化 + 対象: + ブランチの名前を編集 + 新しい名前: + このブランチにつける一意な名前 + ブランチ: + 中止 + リモートから変更を自動取得中... + クリーンアップ(GC & Prune) + このリポジトリに対して`git gc`コマンドを実行します。 + すべてのフィルターをクリア + リポジトリの設定 + 続ける + カスタムアクション + カスタムアクションがありません + `--reflog` オプションを有効化 + ファイルブラウザーで開く + ブランチ/タグ/サブモジュールを検索 + 解除 + コミットグラフで非表示 + コミットグラフでフィルター + `--first-parent` オプションを有効化 + レイアウト + 水平 + 垂直 + コミットの並び順 + 日時 + トポロジカルソート + ローカル ブランチ + HEADに移動 + ブランチを作成 + 通知をクリア + グラフで現在のブランチを強調表示 + {0} で開く + 外部ツールで開く + 更新 + リモート + リモートを追加 + コミットを検索 + 著者 + コミッター + ファイル + メッセージ + SHA + 現在のブランチ + タグをツリーとして表示 + スキップ + 統計 + サブモジュール + サブモジュールを追加 + サブモジュールを更新 + タグ + 新しいタグを作成 + 作成者日時 + 名前 (昇順) + 名前 (降順) + ソート + ターミナルで開く + 履歴に相対時間を使用 + ワークツリー + ワークツリーを追加 + 削除 + GitリポジトリのURL + 現在のブランチをリビジョンにリセット + リセットモード: + 移動先: + 現在のブランチ: + ファイルエクスプローラーで表示 + コミットを戻す + コミット: + コミットの変更を戻す + コミットメッセージを書き直す + 改行には'Shift+Enter'キーを使用します。 'Enter"はOKボタンのホットキーとして機能します。 + 実行中です。しばらくお待ちください... + 保存 + 名前を付けて保存... + パッチが正常に保存されました! + リポジトリをスキャン + ルートディレクトリ: + 更新を確認 + 新しいバージョンのソフトウェアが利用可能です: + 更新の確認に失敗しました! + ダウンロード + このバージョンをスキップ + ソフトウェアの更新 + 利用可能なアップデートはありません + トラッキングブランチを設定 + ブランチ: + 上流ブランチを解除 + 上流ブランチ: + SHAをコピー + Go to + スカッシュコミット + 宛先: + SSH プライベートキー: + プライベートSSHキーストアのパス + スタート + スタッシュ + スタッシュ後に自動で復元 + 作業ファイルは変更されず、スタッシュが保存されます。 + 追跡されていないファイルを含める + ステージされたファイルを保持 + メッセージ: + オプション. このスタッシュの名前を入力 + ステージされた変更のみ + 選択したファイルの、ステージされた変更とステージされていない変更の両方がスタッシュされます!!! + ローカルの変更をスタッシュ + 適用 + 破棄 + パッチとして保存 + スタッシュを破棄 + 破棄: + スタッシュ + 変更 + スタッシュ + 統計 + コミット + コミッター + 月間 + 週間 + コミット: + 著者: + 概要 + サブモジュール + サブモジュールを追加 + 相対パスをコピー + ネストされたサブモジュールを取得する + サブモジュールのリポジトリを開く + 相対パス: + このモジュールを保存するフォルダの相対パス + サブモジュールを削除 + OK + タグ名をコピー + タグメッセージをコピー + ${0}$ を削除... + ${0}$ を ${1}$ にマージ... + ${0}$ をプッシュ... + URL: + サブモジュールを更新 + すべてのサブモジュール + 必要に応じて初期化 + 再帰的に更新 + サブモジュール: + --remoteオプションを使用 + 警告 + ようこそ + グループを作成 + サブグループを作成 + リポジトリをクローンする + 削除 + ドラッグ & ドロップでフォルダを追加できます. グループを作成したり、変更したりできます。 + 編集 + 別のグループに移動 + すべてのリポジトリを開く + リポジトリを開く + ターミナルを開く + デフォルトのクローンディレクトリ内のリポジトリを再スキャン + リポジトリを検索... + ソート + 変更 + Git Ignore + すべての*{0}ファイルを無視 + 同じフォルダ内の*{0}ファイルを無視 + 同じフォルダ内のファイルを無視 + このファイルのみを無視 + Amend + このファイルを今すぐステージできます。 + コミット + コミットしてプッシュ + メッセージのテンプレート/履歴 + クリックイベントをトリガー + コミット (Edit) + すべての変更をステージしてコミット + 空のコミットが検出されました。続行しますか? (--allow-empty) + 競合が検出されました + ファイルの競合は解決されました + 追跡されていないファイルを含める + 最近の入力メッセージはありません + コミットテンプレートはありません + サインオフ + ステージしたファイル + ステージを取り消し + すべてステージを取り消し + 未ステージのファイル + ステージへ移動 + すべてステージへ移動 + 変更されていないとみなしたものを表示 + テンプレート: ${0}$ + 選択したファイルを右クリックし、競合を解決する操作を選択してください。 + ワークスペース: + ワークスペースを設定... + ワークツリー + パスをコピー + ロック + 削除 + ロック解除 + diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 8d2b4f1e..fec5c780 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -723,6 +723,7 @@ 触发点击事件 提交(修改原始提交) 自动暂存所有变更并提交 + 当前有 {0} 个文件在暂存区中,但仅显示了 {1} 个文件({2} 个文件被过滤掉了),是否继续提交? 提交未包含变更文件!是否继续(--allow-empty)? 检测到冲突 文件冲突已解决 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 8e823f68..66bcc33a 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -722,6 +722,7 @@ 觸發點擊事件 提交 (修改原始提交) 自動暫存全部變更並提交 + 您已暫存 {0} 檔案,但只顯示 {1} 檔案 ({2} 檔案被篩選器隱藏)。您要繼續嗎? 未包含任何檔案變更! 您是否仍要提交 (--allow-empty)? 檢測到衝突 檔案衝突已解決 diff --git a/src/ViewModels/ConfirmCommit.cs b/src/ViewModels/ConfirmCommit.cs new file mode 100644 index 00000000..cea56948 --- /dev/null +++ b/src/ViewModels/ConfirmCommit.cs @@ -0,0 +1,26 @@ +using System; + +namespace SourceGit.ViewModels +{ + public class ConfirmCommit + { + public string Message + { + get; + private set; + } + + public ConfirmCommit(string message, Action onSure) + { + Message = message; + _onSure = onSure; + } + + public void Continue() + { + _onSure?.Invoke(); + } + + private Action _onSure; + } +} diff --git a/src/ViewModels/ConfirmCommitWithoutFiles.cs b/src/ViewModels/ConfirmCommitWithoutFiles.cs deleted file mode 100644 index 3249fba8..00000000 --- a/src/ViewModels/ConfirmCommitWithoutFiles.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace SourceGit.ViewModels -{ - public class ConfirmCommitWithoutFiles - { - public ConfirmCommitWithoutFiles(WorkingCopy wc, bool autoPush) - { - _wc = wc; - _autoPush = autoPush; - } - - public void Continue() - { - _wc.CommitWithoutFiles(_autoPush); - } - - private readonly WorkingCopy _wc; - private bool _autoPush; - } -} diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index 6ea41e04..6b1e439e 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -2513,30 +2513,37 @@ namespace SourceGit.ViewModels private void AutoFetchImpl(object sender) { - if (!_settings.EnableAutoFetch || _isAutoFetching) - return; - - var lockFile = Path.Combine(_gitDir, "index.lock"); - if (File.Exists(lockFile)) - return; - - var now = DateTime.Now; - var desire = _lastFetchTime.AddMinutes(_settings.AutoFetchInterval); - if (desire > now) - return; - - var remotes = new List(); - lock (_lockRemotes) + try { - foreach (var remote in _remotes) - remotes.Add(remote.Name); - } + if (!_settings.EnableAutoFetch || _isAutoFetching) + return; - Dispatcher.UIThread.Invoke(() => IsAutoFetching = true); - foreach (var remote in remotes) - new Commands.Fetch(_fullpath, remote, false, false, null) { RaiseError = false }.Exec(); - _lastFetchTime = DateTime.Now; - Dispatcher.UIThread.Invoke(() => IsAutoFetching = false); + var lockFile = Path.Combine(_gitDir, "index.lock"); + if (File.Exists(lockFile)) + return; + + var now = DateTime.Now; + var desire = _lastFetchTime.AddMinutes(_settings.AutoFetchInterval); + if (desire > now) + return; + + var remotes = new List(); + lock (_lockRemotes) + { + foreach (var remote in _remotes) + remotes.Add(remote.Name); + } + + Dispatcher.UIThread.Invoke(() => IsAutoFetching = true); + foreach (var remote in remotes) + new Commands.Fetch(_fullpath, remote, false, false, null) { RaiseError = false }.Exec(); + _lastFetchTime = DateTime.Now; + Dispatcher.UIThread.Invoke(() => IsAutoFetching = false); + } + catch + { + // DO nothing, but prevent `System.AggregateException` + } } private string _fullpath = string.Empty; diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 40b4c50c..a0933ea3 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -99,17 +99,18 @@ namespace SourceGit.ViewModels } } - public string UnstagedFilter + public string Filter { - get => _unstagedFilter; + get => _filter; set { - if (SetProperty(ref _unstagedFilter, value)) + if (SetProperty(ref _filter, value)) { if (_isLoadingData) return; - VisibleUnstaged = GetVisibleUnstagedChanges(_unstaged); + VisibleUnstaged = GetVisibleChanges(_unstaged); + VisibleStaged = GetVisibleChanges(_staged); SelectedUnstaged = []; } } @@ -133,6 +134,12 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _staged, value); } + public List VisibleStaged + { + get => _visibleStaged; + private set => SetProperty(ref _visibleStaged, value); + } + public List SelectedUnstaged { get => _selectedUnstaged; @@ -216,6 +223,9 @@ namespace SourceGit.ViewModels _visibleUnstaged.Clear(); OnPropertyChanged(nameof(VisibleUnstaged)); + _visibleStaged.Clear(); + OnPropertyChanged(nameof(VisibleStaged)); + _unstaged.Clear(); OnPropertyChanged(nameof(Unstaged)); @@ -269,7 +279,7 @@ namespace SourceGit.ViewModels } } - var visibleUnstaged = GetVisibleUnstagedChanges(unstaged); + var visibleUnstaged = GetVisibleChanges(unstaged); var selectedUnstaged = new List(); foreach (var c in visibleUnstaged) { @@ -278,8 +288,10 @@ namespace SourceGit.ViewModels } var staged = GetStagedChanges(); + + var visibleStaged = GetVisibleChanges(staged); var selectedStaged = new List(); - foreach (var c in staged) + foreach (var c in visibleStaged) { if (lastSelectedStaged.Contains(c.Path)) selectedStaged.Add(c); @@ -290,6 +302,7 @@ namespace SourceGit.ViewModels _isLoadingData = true; HasUnsolvedConflicts = hasConflict; VisibleUnstaged = visibleUnstaged; + VisibleStaged = visibleStaged; Unstaged = unstaged; Staged = staged; SelectedUnstaged = selectedUnstaged; @@ -337,7 +350,7 @@ namespace SourceGit.ViewModels public void UnstageAll() { - UnstageChanges(_staged, null); + UnstageChanges(_visibleStaged, null); } public void Discard(List changes) @@ -346,9 +359,9 @@ namespace SourceGit.ViewModels _repo.ShowPopup(new Discard(_repo, changes)); } - public void ClearUnstagedFilter() + public void ClearFilter() { - UnstagedFilter = string.Empty; + Filter = string.Empty; } public async void UseTheirs(List changes) @@ -538,11 +551,6 @@ namespace SourceGit.ViewModels DoCommit(false, true, false); } - public void CommitWithoutFiles(bool autoPush) - { - DoCommit(false, autoPush, true); - } - public ContextMenu CreateContextMenuForUnstagedChanges() { if (_selectedUnstaged == null || _selectedUnstaged.Count == 0) @@ -1472,16 +1480,16 @@ namespace SourceGit.ViewModels return menu; } - private List GetVisibleUnstagedChanges(List unstaged) + private List GetVisibleChanges(List changes) { - if (string.IsNullOrEmpty(_unstagedFilter)) - return unstaged; + if (string.IsNullOrEmpty(_filter)) + return changes; var visible = new List(); - foreach (var c in unstaged) + foreach (var c in changes) { - if (c.Path.Contains(_unstagedFilter, StringComparison.OrdinalIgnoreCase)) + if (c.Path.Contains(_filter, StringComparison.OrdinalIgnoreCase)) visible.Add(c); } @@ -1599,7 +1607,8 @@ namespace SourceGit.ViewModels private async void UnstageChanges(List changes, Models.Change next) { - if (changes.Count == 0) + var count = changes.Count; + if (count == 0) return; // Use `_selectedStaged` instead of `SelectedStaged` to avoid UI refresh. @@ -1611,16 +1620,15 @@ namespace SourceGit.ViewModels { await Task.Run(() => new Commands.UnstageChangesForAmend(_repo.FullPath, changes).Exec()); } - else if (changes.Count == _staged.Count) + else if (count == _staged.Count) { await Task.Run(() => new Commands.Reset(_repo.FullPath).Exec()); } else { - for (int i = 0; i < changes.Count; i += 10) + for (int i = 0; i < count; i += 10) { - var count = Math.Min(10, changes.Count - i); - var step = changes.GetRange(i, count); + var step = changes.GetRange(i, Math.Min(10, count - i)); await Task.Run(() => new Commands.Reset(_repo.FullPath, step).Exec()); } } @@ -1642,7 +1650,7 @@ namespace SourceGit.ViewModels DetailContext = new DiffContext(_repo.FullPath, new Models.DiffOption(change, isUnstaged), _detailContext as DiffContext); } - private void DoCommit(bool autoStage, bool autoPush, bool allowEmpty) + private void DoCommit(bool autoStage, bool autoPush, bool allowEmpty = false, bool confirmWithFilter = false) { if (!_repo.CanCreatePopup()) { @@ -1650,6 +1658,20 @@ namespace SourceGit.ViewModels return; } + if (!string.IsNullOrEmpty(_filter) && _staged.Count > _visibleStaged.Count && !confirmWithFilter) + { + var confirmMessage = App.Text("WorkingCopy.ConfirmCommitWithFilter", _staged.Count, _visibleStaged.Count, _staged.Count - _visibleStaged.Count); + App.OpenDialog(new Views.ConfirmCommit() + { + DataContext = new ConfirmCommit(confirmMessage, () => + { + DoCommit(autoStage, autoPush, allowEmpty, true); + }) + }); + + return; + } + if (string.IsNullOrWhiteSpace(_commitMessage)) { App.RaiseException(_repo.FullPath, "Commit without message is NOT allowed!"); @@ -1660,9 +1682,13 @@ namespace SourceGit.ViewModels { if ((autoStage && _count == 0) || (!autoStage && _staged.Count == 0)) { - App.OpenDialog(new Views.ConfirmCommitWithoutFiles() + var confirmMessage = App.Text("WorkingCopy.ConfirmCommitWithoutFiles"); + App.OpenDialog(new Views.ConfirmCommit() { - DataContext = new ConfirmCommitWithoutFiles(this, autoPush) + DataContext = new ConfirmCommit(confirmMessage, () => + { + DoCommit(autoStage, autoPush, true, confirmWithFilter); + }) }); return; @@ -1729,11 +1755,12 @@ namespace SourceGit.ViewModels private List _unstaged = []; private List _visibleUnstaged = []; private List _staged = []; + private List _visibleStaged = []; private List _selectedUnstaged = []; private List _selectedStaged = []; private int _count = 0; private object _detailContext = null; - private string _unstagedFilter = string.Empty; + private string _filter = string.Empty; private string _commitMessage = string.Empty; private bool _hasUnsolvedConflicts = false; diff --git a/src/Views/ConfirmCommitWithoutFiles.axaml b/src/Views/ConfirmCommit.axaml similarity index 92% rename from src/Views/ConfirmCommitWithoutFiles.axaml rename to src/Views/ConfirmCommit.axaml index 4c9fd1c8..77bbdb30 100644 --- a/src/Views/ConfirmCommitWithoutFiles.axaml +++ b/src/Views/ConfirmCommit.axaml @@ -5,8 +5,8 @@ xmlns:v="using:SourceGit.Views" xmlns:vm="using:SourceGit.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" - x:Class="SourceGit.Views.ConfirmCommitWithoutFiles" - x:DataType="vm:ConfirmCommitWithoutFiles" + x:Class="SourceGit.Views.ConfirmCommit" + x:DataType="vm:ConfirmCommit" x:Name="ThisControl" Icon="/App.ico" Title="{DynamicResource Text.Warn}" @@ -38,7 +38,7 @@ - + diff --git a/src/Views/ConfirmCommitWithoutFiles.axaml.cs b/src/Views/ConfirmCommit.axaml.cs similarity index 57% rename from src/Views/ConfirmCommitWithoutFiles.axaml.cs rename to src/Views/ConfirmCommit.axaml.cs index 342600fc..1cf770cb 100644 --- a/src/Views/ConfirmCommitWithoutFiles.axaml.cs +++ b/src/Views/ConfirmCommit.axaml.cs @@ -2,20 +2,16 @@ using Avalonia.Interactivity; namespace SourceGit.Views { - public partial class ConfirmCommitWithoutFiles : ChromelessWindow + public partial class ConfirmCommit : ChromelessWindow { - public ConfirmCommitWithoutFiles() + public ConfirmCommit() { InitializeComponent(); } private void Sure(object _1, RoutedEventArgs _2) { - if (DataContext is ViewModels.ConfirmCommitWithoutFiles vm) - { - vm.Continue(); - } - + (DataContext as ViewModels.ConfirmCommit)?.Continue(); Close(); } diff --git a/src/Views/Histories.axaml b/src/Views/Histories.axaml index 4fd8909d..96340d1e 100644 --- a/src/Views/Histories.axaml +++ b/src/Views/Histories.axaml @@ -195,7 +195,7 @@ - + + + + + + + + + + + + + + + - + @@ -75,40 +108,8 @@ - - - - - - - - - - - - - - - - + @@ -155,15 +156,16 @@ ViewMode="{Binding Source={x:Static vm:Preferences.Instance}, Path=StagedChangeViewMode, Mode=TwoWay}"/> - +