Compare commits

..

1352 commits

Author SHA1 Message Date
leo
74d77ab704
Merge branch 'release/v2025.22' 2025-06-16 09:18:41 +08:00
leo
b617181fc5
version: Release 2025.22
Signed-off-by: leo <longshuang@msn.cn>
2025-06-16 09:18:31 +08:00
github-actions[bot]
9dedcacb2f doc: Update translation status and sort locale files 2025-06-16 01:15:05 +00:00
Javier J. Martínez M.
b22733b565
localization: update spanish translations (#1422)
add missing translations
2025-06-16 09:14:52 +08:00
Göran W
28844c59cf
perf: optimize the WorkingCopy.IsChanged() method (#1418)
Some checks failed
Continuous Integration / Build (push) Has been cancelled
Continuous Integration / Prepare version string (push) Has been cancelled
Continuous Integration / Package (push) Has been cancelled
* There's no need to populate a Dictionary just to diff the the "old" and "cur" Lists of Changes.
* If the two lists are of equal length and no change has occurred, we can assume that they are also reported in equal sort-order (by git-status).
* Thus, we only need to compare the two items at each successive index.
2025-06-13 19:23:20 +08:00
leo
f88652ffdd
code_review: PR #1417
Remove unnecessary namespace using

Signed-off-by: leo <longshuang@msn.cn>
2025-06-13 17:12:14 +08:00
Göran W
8dffdef48d
refactor: reduce redundant code in NumericSort (#1417)
* Refactor the 2 do-loops into simpler while-loops and replace the use of "tmp1/2" char-arrays with calls to String.Substring().
* Rename the "loc1/2" variables to "subLen1/2", for clarity, since they represent the lengths of the two extracted Substrings.

These changes make the logic more compact and easier to follow.
2025-06-13 17:06:35 +08:00
leo
158d926189
ux: new style for submodule diff
Signed-off-by: leo <longshuang@msn.cn>
2025-06-13 16:19:04 +08:00
leo
99b7208a54
enhance: prevent to start bisect if it is already running
Signed-off-by: leo <longshuang@msn.cn>
2025-06-13 15:32:31 +08:00
leo
05757ebf40
feature: supports to view .tiff images
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-12 18:15:25 +08:00
leo
cb6d6a233f
feature: show change tooltip in INFORMATION page
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-12 11:42:58 +08:00
leo
79650d1851
feature: supports to view .gif file as static image (not animated)
Signed-off-by: leo <longshuang@msn.cn>
2025-06-12 11:32:24 +08:00
leo
7e2f3bec8c
enhance: clear commit message before merging/cherry-picking/rebasing/reverting to allow SourceGit read it from git (#1414)
Signed-off-by: leo <longshuang@msn.cn>
2025-06-12 10:39:52 +08:00
leo
7de5991ecb
code_review: PR #1415
- Column for hotkey in `Reset` popup should use `Auto` for width
- Add `SelectionBoxItemTemplate` for current selected mode in `Reset` popup

Signed-off-by: leo <longshuang@msn.cn>
2025-06-12 09:54:53 +08:00
Nathan Baulch
ffac71b15f
code_style: general cleanup (#1415)
* code_style:  general cleanup

* code_style: whitespace cleanup
2025-06-12 09:35:37 +08:00
leo
35eda489be
feature: show local branch's track status in CheckoutAndFastForward popup
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-11 21:14:06 +08:00
leo
f59851f454
refactor: case-insensitive sorting
- `ToUpper` is not necessary to compare digit char with non-digit char
- use numeric sorting for commit decorators with same type

Signed-off-by: leo <longshuang@msn.cn>
2025-06-11 20:25:41 +08:00
leo
a128b67bd4
code_review: PR #1412
- Use `ViewModels.StashesPage.SelectedStash` instead of `sender is not ListBox { SelectedValue: Models.Stash stash }`
- In tags view, `SelectedItem` can be `Models.Tag` or `ViewModels.TagTreeNode`
- In logs window, `vm.SelectedLog` may be null

Signed-off-by: leo <longshuang@msn.cn>
2025-06-11 16:13:47 +08:00
Nathan Baulch
196b454ae8
feature: support delete key everywhere (#1412) 2025-06-11 15:35:43 +08:00
leo
5494093261
refactor: now all filesystem related trees/lists are sorted in case-insensitive mode
Signed-off-by: leo <longshuang@msn.cn>
2025-06-11 15:20:50 +08:00
leo
c3c7d32167
refactor: do not change original image aspect ratio and do not up-scale image in BLEND image-diff mode
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-11 10:25:24 +08:00
leo
7c1a894525
refactor: do not change original image aspect ratio and do not upscale image in SWIPE mode
Signed-off-by: leo <longshuang@msn.cn>
2025-06-11 10:12:03 +08:00
leo
bcefb773c1
code_style: remove comment
Some checks failed
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Has been cancelled
Signed-off-by: leo <longshuang@msn.cn>
2025-06-10 17:19:37 +08:00
leo
aa1c8b1cc1
code_style: use combined expr
Signed-off-by: leo <longshuang@msn.cn>
2025-06-10 17:09:57 +08:00
github-actions[bot]
5e303d43d4 doc: Update translation status and sort locale files 2025-06-10 09:04:35 +00:00
leo
7d0536d94b
feature: when trying to checkout a local branch from its tracking upstream and it is behind the upstream, show Checkout & Fast-Forward popup
Signed-off-by: leo <longshuang@msn.cn>
2025-06-10 17:04:06 +08:00
Nathan Baulch
6c04f5390a
feature: double tap commit with tracked remote branch checks out local tracking branch (#1409) 2025-06-10 15:58:57 +08:00
leo
ee4d8a6a0e
code_review: PR #1408
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-10 11:18:20 +08:00
johanw1232
0ea4021a64
feature: update blame data when clicking/navigating commits (#1408)
* initial work on allowing navigation by clicking on commits in the blame window
* cleanup
2025-06-10 09:30:12 +08:00
leo
11a46dbc93
update: built-in github and unreal icons
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-09 17:35:20 +08:00
leo
69792b3262
refactor: do not upscale images
Signed-off-by: leo <longshuang@msn.cn>
2025-06-09 17:22:31 +08:00
leo
1b1dc2f666
code_style: remove unnecessary code
Signed-off-by: leo <longshuang@msn.cn>
2025-06-09 15:42:02 +08:00
leo
4302d7adb5
Merge branch 'master' into develop
Some checks failed
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Has been cancelled
2025-06-09 09:31:46 +08:00
leo
932baeec53
Merge branch 'release/v2025.21' 2025-06-09 09:30:45 +08:00
leo
637e133f47
version: Release 2025.21
Signed-off-by: leo <longshuang@msn.cn>
2025-06-09 09:30:36 +08:00
github-actions[bot]
a1e76e9bea doc: Update translation status and sort locale files 2025-06-09 01:27:28 +00:00
AquariusStar
a8541a780e
localization: update translate Russian (#1404) 2025-06-09 09:27:10 +08:00
Sina Hinderks
d55f19586f
fix: issue tracker rule over keyword in subject (#1403)
Some teams use issue tracker numbers in front of the commit message
subject, followed by a colon.  It was not possible to use an issue
tracker rule in such cases, since the issue tracker number would be
interpreted as a keyword due to the colon and therefore displayed in
bold face instead of as a link into the issue tracker.
2025-06-09 09:26:27 +08:00
leo
a22c39519f
code_style: remove unnecessary code
Some checks failed
Continuous Integration / Build (push) Has been cancelled
Continuous Integration / Prepare version string (push) Has been cancelled
Continuous Integration / Package (push) Has been cancelled
Signed-off-by: leo <longshuang@msn.cn>
2025-06-08 11:54:54 +08:00
leo
84fb39f97a
code_review: PR #1402
- it's unnecessary to implement `IEnumerable` interface
- we should check `IsIntersecting` before creating `InlineElement` to avoid unnecessary works suck as running `git cat-file -t <hash>`
- sort whold list after all elements have been added to avoid unnecessary memmove in `Insert`

Signed-off-by: leo <longshuang@msn.cn>
2025-06-08 11:09:20 +08:00
Sina Hinderks
fe54d30b70
refactor: collecting inlines for subjects (#1402)
Instead of checking intersections of inline elements yourself before adding an inline element, the new class `InlineElementCollector` prevents intersections internally.

Additionally the inline elements are sorted by the new class, so it's no longer necessary to do this after adding the inline elements.
2025-06-08 08:47:03 +08:00
leo
ba4c0f0cd2
enhance: scroll to home when active revision file changed
Some checks are pending
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Continuous Integration / Build (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-06-07 20:53:34 +08:00
leo
2478d2953b
code_style: remove unnecessary code in DiffContext
Signed-off-by: leo <longshuang@msn.cn>
2025-06-07 20:42:45 +08:00
leo
74f52fb266
enhance: only show syntax-highlighting toggle if current revision content is a text file
Signed-off-by: leo <longshuang@msn.cn>
2025-06-07 20:27:52 +08:00
leo
f830b68f6a
ux: change foreground for some labels
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-07 12:20:09 +08:00
leo
d323a2064e
feature: supports RGBA16 pixel format
Signed-off-by: leo <longshuang@msn.cn>
2025-06-07 12:00:16 +08:00
leo
203c50350e
fix: wrong pfim image format
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-06 20:50:37 +08:00
leo
47012e29dc
fix: file extensions are case-insensitive
Some checks failed
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Has been cancelled
Signed-off-by: leo <longshuang@msn.cn>
2025-06-06 18:47:36 +08:00
leo
8db033be99
code_review: PR #1392
- fix the issue that not all channel takes 8 bits
- if `PixelFormatTranscoder.Transcode` supports the same pixel formats, let it converts pixels automatically

Signed-off-by: leo <longshuang@msn.cn>
2025-06-06 18:23:10 +08:00
Henrik Andersson
a2ca071f08
feature: .dds image support (#1392)
* Added Pfim as 3rdparty lib

* Added support for parsing showing dds and tga images using Pfim

---------

Co-authored-by: Snimax <snimax@live.se>
2025-06-06 16:44:40 +08:00
Nathan Baulch
7bba40d03f
typos: (#1397) 2025-06-06 12:10:55 +08:00
leo
0c22409b7b
ux: new sort by time icon (#1393)
Signed-off-by: leo <longshuang@msn.cn>
2025-06-06 11:37:56 +08:00
leo
f63fe8637b
feature: use different icon for sort mode (#1393)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-06-06 11:22:30 +08:00
github-actions[bot]
08665e45c1 doc: Update translation status and sort locale files 2025-06-06 02:45:35 +00:00
leo
3bb20868fc
refactor: remove unnecessary sort by name (descending) for tags (#1393)
Signed-off-by: leo <longshuang@msn.cn>
2025-06-06 10:45:18 +08:00
leo
ac55bed812
enhance: revision file viewer
- show current file path
- add a toggle button to use global syntax highlighting setting (sometimes TextMateSharp will crash this app)

Signed-off-by: leo <longshuang@msn.cn>
2025-06-06 10:07:58 +08:00
leo
f003f67129
fix: should use file.SHA instead of _commit.SHA to query submodule's commit
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-05 21:54:09 +08:00
Göran W
f04b0c5d97
fix: prevent exception on repo with no commits/branches
Signed-off-by: leo <longshuang@msn.cn>
2025-06-05 21:28:32 +08:00
Göran W
406ace9e79
enhance: activate TabsDropdownItem on Tapped instead of DoubleTapped
Signed-off-by: leo <longshuang@msn.cn>
2025-06-05 21:28:10 +08:00
leo
464fe74580
code_review: commit b969ac161a
- The return code of `AutoRemoveInvalidNode`  is never used
- It's not necessary to sort all nodes after re-scan default clone dir. Because `FindOrAddNodeByRepositoryPath` makes sure added node is ordered
- Add a new parameter `save` to `FindOrAddNodeByRepositoryPath` method, and disable it while scanning. Instead, we will save it after scan finished.

Signed-off-by: leo <longshuang@msn.cn>
2025-06-05 21:27:19 +08:00
Göran W
b969ac161a
enhance: unify sorting of RepositoryNode tree, unconditional sort & save after rescan 2025-06-05 21:19:25 +08:00
Göran W
88c38b4139
enhance: unified all file-path normalization - use char-replace, trim trailing slash 2025-06-05 21:17:18 +08:00
Göran W
54c05ac35a
fix: remove trailing slash in paths, to avoid failing comparisons.
This is needed since DirectoryInfo.Fullname (and .FullPath) will not "normalize" trailing slashes, so direct equality tests are error-prone.
This fixes a bug in ScanRepositories.GetUnmanagedRepositories(), where not all Git repo folders were added.
(Also, corrected a variable name from 'founded' to 'found'.)
2025-06-05 21:15:28 +08:00
Göran W
75c32c1a01
typo: corrected spelling error in App.GetLauncher() method 2025-06-05 21:15:28 +08:00
leo
a023a9259b
refactor: rewrite lfs pointer detection and image loading
Signed-off-by: leo <longshuang@msn.cn>
2025-06-05 21:06:31 +08:00
leo
eebadd67a1
feature: remember the last active tab index in lfs-image diff view
Some checks are pending
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Continuous Integration / Build (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-06-05 09:18:19 +08:00
leo
f716c5ee1e
refactor: use existing QueryFileContent command
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-04 21:30:08 +08:00
leo
ed496a41fb
feature: supports to view image diff when lfs object points to a image
Signed-off-by: leo <longshuang@msn.cn>
2025-06-04 20:53:42 +08:00
leo
06a77502bc
fix: crash when clicking Previous Difference without visual lines (#1385)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Always scroll to top when the state of `Show All Lines` changed

Signed-off-by: leo <longshuang@msn.cn>
2025-06-04 13:13:28 +08:00
leo
c2187edbe9
fix: running git command in UIThread via context menu entry blocks whole app (#1384)
Some checks failed
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Has been cancelled
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 23:36:15 +08:00
github-actions[bot]
d85f82e171 doc: Update translation status and sort locale files 2025-06-03 13:38:04 +00:00
leo
f7c10d0b33
feature: supports to load avatar from local image and save it to disk
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 21:37:47 +08:00
leo
25e272fa55
ux: layout of filter mode toggle buttons
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 20:28:44 +08:00
leo
98041c803e
feature: supports re-order custom actions (#1346)
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 20:24:30 +08:00
leo
ee2e7d0127
enhance: ignores $ char when measuring contents in NamedHighlightedTextBlock
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 14:12:23 +08:00
leo
6517e78ab6
enhance: enable StaysOpenOnClick for filter mode in graph context menu item
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 14:06:53 +08:00
leo
bf43dd828a
ux: new style for ref's Visibility in Graph context menu item
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 12:34:49 +08:00
leo
cd009bda6b
ux: enable Use monospace font only in text editor by default
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 10:15:58 +08:00
leo
cd8ff2e9bf
Merge branch 'master' into develop
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
2025-06-03 09:27:51 +08:00
leo
0594196dee
Merge branch 'release/v2025.20' 2025-06-03 09:27:03 +08:00
leo
425395da29
version: Release 2025.20
Signed-off-by: leo <longshuang@msn.cn>
2025-06-03 09:26:57 +08:00
leo
6e501b1ee4
feature!: now SourceGit requires git >= 2.25.1
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-06-02 22:38:00 +08:00
leo
7b05b011aa
fix: USE THEIRS for AU conflict and USE MINE for UA conflict
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-02 13:03:38 +08:00
leo
f1052c3efc
refactor: use git reset --hard HEAD to discard all changes and use git restore --staged to unstage changes in text diff view
Signed-off-by: leo <longshuang@msn.cn>
2025-06-02 12:50:58 +08:00
leo
78f9ae2fa9
refactor: rewrite git restore integration
Signed-off-by: leo <longshuang@msn.cn>
2025-06-02 12:14:22 +08:00
leo
80df53cf04
ux: move hunk-based operation button away from scrollbar (#1382)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-01 20:04:15 +08:00
leo
57004c4baf
code_style: run dotnet format
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-06-01 11:23:04 +08:00
leo
fa004ce31b
enhance: unstaged renamed file should use git restore --staged <path> <org_path> instead of git restore --staged <path>
Signed-off-by: leo <longshuang@msn.cn>
2025-06-01 11:19:41 +08:00
leo
6620bd193e
ux: remove tooltip for USE THEIRS and USE MINE button
Signed-off-by: leo <longshuang@msn.cn>
2025-06-01 11:09:31 +08:00
leo
26307e2343
refactor: new tooltip for change
Signed-off-by: leo <longshuang@msn.cn>
2025-06-01 10:34:24 +08:00
leo
db5bb0aec9
fix: must convert the relative path to absolute before send it to first instance (#1376)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-31 21:26:01 +08:00
leo
dd432c63e8
enhance: when counting commits in Statistics, if the authors have the same e-mail address, the commits are considered to be from the same person (#1380)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-31 18:52:15 +08:00
github-actions[bot]
b94f26a937 doc: Update translation status and sort locale files
Some checks failed
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Has been cancelled
2025-05-31 04:15:23 +00:00
Javier J. Martínez M.
8e5d5b946e
localization: update spanish translations (#1379)
add missing translations
2025-05-31 12:15:06 +08:00
leo
a9734ea8e9
code_style: remove unused code
Signed-off-by: leo <longshuang@msn.cn>
2025-05-31 11:33:22 +08:00
github-actions[bot]
e22f0f8513 doc: Update translation status and sort locale files
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
2025-05-30 10:20:10 +00:00
leo
8b17f3b1f4
localization: change Compare with HEAD to Compare with <current_branch_name>
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 18:19:46 +08:00
leo
7934496cff
feature: reset non-active branch to selected commit should not depends on upstream
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 17:56:06 +08:00
leo
188408fdfc
project: remove duplicated attributes in csproj
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 17:21:49 +08:00
leo
bc5deac9fe
fix: OpenFolderPickerAsync raise exception when selected a drive root such as E:\
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 17:12:56 +08:00
leo
1bd2044589
ux: show conflict description in change status icon
Some checks are pending
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Continuous Integration / Build (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 11:20:43 +08:00
leo
f0c77ffeb8
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 11:16:07 +08:00
leo
60cd210b80
fix: using theirs or mine does not work if it is deleted by ours or theirs
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 11:13:29 +08:00
leo
75015d550c
ux: show conflict short format in changes view
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 10:42:02 +08:00
leo
e40ca4bbe0
refactor: use git restore instead of git reset to unstage local changes (#1373)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-30 09:43:45 +08:00
leo
46231a759c
code_style: run dotnet format
Some checks failed
Continuous Integration / Build (push) Has been cancelled
Continuous Integration / Prepare version string (push) Has been cancelled
Localization Check / localization-check (push) Has been cancelled
Continuous Integration / Package (push) Has been cancelled
Signed-off-by: leo <longshuang@msn.cn>
2025-05-28 15:17:05 +08:00
leo
fbc8edcc13
feature: show conflict reason
Signed-off-by: leo <longshuang@msn.cn>
2025-05-28 14:20:56 +08:00
github-actions[bot]
3437f5f4a9 doc: Update translation status and sort locale files 2025-05-28 02:19:23 +00:00
leo
40bf69bff3
ux: move some buttons to page switcher (#1370)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-28 10:18:34 +08:00
leo
2aac6779a5
fix: squash should not change the original author
Signed-off-by: leo <longshuang@msn.cn>
2025-05-28 09:50:14 +08:00
cdammanintopix
9affca1fb2
fix: arguments order for checkout command (#1368)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
2025-05-27 17:43:33 +08:00
Gadfly
729e06d5c0
fix: SaveAsPatch for untracked changes in stash (#1366)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
2025-05-26 22:50:29 +08:00
leo
826619e7c9
fix: new added file in stash changes may not come from untracked file but from staged files (#1358)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-26 22:13:10 +08:00
github-actions[bot]
056b90a5ae doc: Update translation status and sort locale files
Some checks failed
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Continuous Integration / Build (push) Waiting to run
Localization Check / localization-check (push) Has been cancelled
2025-05-26 04:28:23 +00:00
leo
0641a22230
feature: allow to reset author when --amend is enabled for committing 2025-05-26 12:28:00 +08:00
leo
d3bc85418e
Merge branch 'master' into develop 2025-05-26 09:56:00 +08:00
leo
4887252870
Merge branch 'release/v2025.19' 2025-05-26 09:45:48 +08:00
leo
860f6f2369
version: Release 2025.19
Signed-off-by: leo <longshuang@msn.cn>
2025-05-26 09:45:43 +08:00
leo
cfc80d41a1
fix: sometimes track status is not correct because the local branch name is ambiguous to git
Signed-off-by: leo <longshuang@msn.cn>
2025-05-26 09:42:46 +08:00
leo
ac26d5bb06
fix: can not squash and fixup until first picked/edit/reword commit in interactive rebase exists list (#1362)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-05-25 13:46:27 +08:00
github-actions[bot]
d7c3bb7150 doc: Update translation status and sort locale files 2025-05-25 05:05:31 +00:00
AquariusStar
39d955b033
localization: update russian translate (#1363) 2025-05-25 13:05:14 +08:00
leo
0e35c56529
enhance: disable squash and fixup for the first commit in interactive rebase list (#1362)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-25 13:03:36 +08:00
leo
22339ab619
enhance: allow to use arrow keys to select changes up/down after stage/unstage previous selected changes by hotkey (#1361)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-24 21:29:48 +08:00
leo
ef53dd0025
refactor: use a new Models.ChangeState.Conflicted to represent all the unmerged file state (#1359)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-24 20:25:05 +08:00
Göran W
30d4c1008a
enhance: don't show unmerged files in STAGED area (#1359)
Unmerged files (i.e unresolved conflicts) should only appear in the Unstaged area, and not "duplicated" in the Staged area.

Motivation:
* The user-friendly git-status command does not show these as "Changes to be committed".
* If they appear in the Staged area, they are quite redundant since the Diff view will just show "No changes or only EOL changes".
* Some other Git UIs (like Fork) don't show these as Staged items either.

NOTE: According to docs for the git-status "Short Format" (and --porcelain=v1), the XY fields for Unmerged paths do NOT actually represent the Index & Working-tree states, instead they represent the states introduced by each HEAD in the merge (i.e Ours & Theirs, relative to Base).
2025-05-24 19:42:10 +08:00
leo
ca33107a45
code_review: PR #1360
Signed-off-by: leo <longshuang@msn.cn>
2025-05-24 19:26:17 +08:00
Göran W
4363b8b6aa
refactor: add new constant Models.Commit.EmptyTreeSHA1 (#1360) 2025-05-24 19:23:28 +08:00
Göran W
f3fe90b2e1
fix: IsConflictResolved check should not be done for submodules (#1356)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
A submodule conflict is not resolved until it's Staged.
2025-05-24 09:40:17 +08:00
leo
e28b75b860
enhance: include stdout in error popup when git process (in Exec mode, we do not need to parse its output) exit with non-zero code
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 16:12:40 +08:00
leo
3377886bab
enhance: filter hint: blocks
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 14:13:48 +08:00
leo
4807cd5eb2
fix: if font family name contains '#', make sure we have that built-in font
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 13:32:02 +08:00
github-actions[bot]
d21b790784 doc: Update translation status and sort locale files
Some checks failed
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Has been cancelled
2025-05-23 04:25:41 +00:00
Javier J. Martínez M.
764ae31239
localization: update spanish translations (#1355)
* localization: update spanish translations

add missing translations

* Update es_ES.axaml

Quickfix for `Text.DeinitSubmodule.Force` translation
2025-05-23 12:25:29 +08:00
github-actions[bot]
38d67d7f17 doc: Update translation status and sort locale files 2025-05-23 03:28:10 +00:00
leo
76a197aae7
feature: supports to overwrite existing branch while creating new branch (#1349)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 11:27:45 +08:00
leo
594ffc0d1a
localization: fix typo in en_US for Text.DeinitSubmodule.Force
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 10:38:44 +08:00
leo
fb1f5638ce
code_style: simpfy context menu creation for blame editor
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 10:31:11 +08:00
leo
492da8dd57
fix: blame highlight background did not update when using scrollbar (#1354)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 10:27:48 +08:00
leo
0ae39faad1
enhance: do not show hint: messages in error popup, but leave it in git command logs (#1348)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 10:05:09 +08:00
leo
c112549b69
refactor: query branch head after operation finished to avoid branch head mismatch
Signed-off-by: leo <longshuang@msn.cn>
2025-05-23 09:40:15 +08:00
Göran W
9fb8af51ff
code_style: move hardcoded brush/strings (for outlier Conflict-icon) into named constants (#1350)
This makes code more consistent and gives better overview of all the icons.
(Potentially, this special/outlier icon could be moved into the existing arrays as an extra ChangeState enum-value.)
2025-05-23 09:18:05 +08:00
leo
1ee7d1184e
enhance: only refresh submodules when it is needed (#1344)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-22 11:02:54 +08:00
Göran W
44c83ef342
enhance: added more FileSystemWatcher patterns, to improve handling (#1345)
Skip files frequently updated by Git fsmonitor--daemon and Visual Studio, to ease debugging and for early exit.
Check for HEAD and ORIG_HEAD under .git/modules/<submodule>/, to improve handling of submodules.
Check for MERGE_HEAD and AUTO_MERGE under .git/, to improve handling of submodules.
2025-05-22 09:11:28 +08:00
leo
c3ac59ee1a
enhance: refresh submodules after .gitmodules file changed
Some checks failed
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Has been cancelled
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 20:51:29 +08:00
leo
c73f775aa5
enhance: mark submodule having local changes even if there are only untracked files (#1344)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 20:47:10 +08:00
M-L-Ml
afbd0d7135
fix: typo in name SetupExternalTools (#1343) 2025-05-21 20:35:22 +08:00
github-actions[bot]
bf39673b21 doc: Update translation status and sort locale files 2025-05-21 12:34:51 +00:00
leo
b0c0c46441
feature: supports to de-initialize a submodule (#1272)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 20:34:33 +08:00
leo
1fef7a7baa
perf: only update uninited or outdated submodules
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 17:51:00 +08:00
github-actions[bot]
1872740265 doc: Update translation status and sort locale files 2025-05-21 09:18:49 +00:00
leo
09d0122e26
refactor: rewrite git pull command
If we do not provide pulling remote branch, it will auto fetch all branches first.

Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 17:18:25 +08:00
github-actions[bot]
7728f4ffbf doc: Update translation status and sort locale files 2025-05-21 08:54:46 +00:00
leo
936160ea5c
feature: supports --recurse-submodules on pull (#1342)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 16:54:23 +08:00
leo
d73ae83b01
feature: supports to use relative path in remote URL (#1339)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 16:29:33 +08:00
leo
5e05c008fc
refactor: simplfy the regex to check remote's URL with HTTP/HTTPS/GIT protocol
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 15:09:36 +08:00
leo
598ba6d9f6
refactor: rewrite Remote.IsValidURL (#1339)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 14:48:21 +08:00
leo
3232e6f313
fix: on Windows, the correct file protocol url format is file:///<driver>:/path/to/file_or_dir (#1339)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 14:18:06 +08:00
leo
0a6b1faa65
feature: support git:// protocol (#1339)
Some checks are pending
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Continuous Integration / Build (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 09:36:41 +08:00
leo
71b90a82b6
refactor: remove validation for relative path while adding submodule (#1339)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 09:27:02 +08:00
leo
d304c50e7f
enhance: show custom action output in popup
Some checks are pending
Localization Check / localization-check (push) Waiting to run
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 00:16:19 +08:00
leo
438aa76695
feature: support to use relative path as submodule's url when adding new submodule (#1339)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-21 00:10:10 +08:00
leo
ece51fbd32
fix: remove binding error in debug mode (#1338)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 23:02:45 +08:00
leo
224f7a949a
fix: since can not been used in HotKey property and ⌘+⌥+D has been used to show Dock, change the hotkey to open external merge tool to Ctrl+Shift+D/⌘+⇧+D
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 23:01:21 +08:00
leo
e6fdc778b7
fix: remove binding error in debug mode (#1338)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 21:48:58 +08:00
leo
53c6fc8999
fix: remove binding error in debug mode (#1338)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 21:44:28 +08:00
leo
f0d1d460a9
fix: remove binding error in debug mode (#1338)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 21:35:14 +08:00
leo
3386cb177b
refactor: rewrite git flow init
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 21:26:41 +08:00
leo
4d5be9f280
refactor: rewrite git-flow integration
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 21:08:00 +08:00
leo
6fa454ace8
fix!: same hotkey for opening external diff tool and discard block (#1337)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 17:32:06 +08:00
leo
75b7724d44
refactor: implement IDisposable instead of calling custom Cleanup
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 17:24:00 +08:00
leo
550493b572
enhance: prevent requesting worktree files more than once time
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 16:49:00 +08:00
leo
eb183589f5
enhance: prevent requesting revision files more than once time
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 16:32:57 +08:00
github-actions[bot]
d56c6a5030 doc: Update translation status and sort locale files 2025-05-20 04:24:40 +00:00
leo
f9b6116a76
feature: supports reset branch to selected commit without checkout (#1247) (#1318)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 12:24:07 +08:00
Gadfly
12d2b7721c
fix: Trim and normalize commit message history line endings (#1335)
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
2025-05-20 10:56:02 +08:00
leo
119b0fe95c
feature: log output of custom action if Wait for action exit enabled (#1334)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-20 09:17:00 +08:00
github-actions[bot]
1dfb629cef doc: Update translation status and sort locale files
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
2025-05-19 04:22:07 +00:00
leo
0e2bb1b276
feature: show commit changes count (#1306)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-19 12:21:50 +08:00
leo
57ee1f7dbd
fix: wrong hotkey tip for open Preferences window
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-19 10:55:25 +08:00
leo
aaf53ac694
enhance: try to cancel switcher first then other popup
Signed-off-by: leo <longshuang@msn.cn>
2025-05-19 10:08:37 +08:00
leo
736991198f
Merge branch 'master' into develop 2025-05-19 09:45:11 +08:00
leo
7dd1389c25
Merge branch 'release/v2025.18' 2025-05-19 09:43:59 +08:00
leo
341ac26576
version: Release 2025.18
Signed-off-by: leo <longshuang@msn.cn>
2025-05-19 09:43:48 +08:00
leo
aff003fd6d
enhance: cleanup unused resources
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
Signed-off-by: leo <longshuang@msn.cn>
2025-05-18 22:00:35 +08:00
qiufengshe
b78f6b0ea8
perf: minimize temporary strings for better performance (#1332) 2025-05-18 20:52:05 +08:00
leo
5e85f6fefe
enhance: auto-select the first page by default
Signed-off-by: leo <longshuang@msn.cn>
2025-05-18 20:47:38 +08:00
github-actions[bot]
52991351af doc: Update translation status and sort locale files 2025-05-18 12:34:17 +00:00
leo
4b849d9d5c
ux: update workspace/page switcher popup layout
Signed-off-by: leo <longshuang@msn.cn>
2025-05-18 20:33:55 +08:00
github-actions[bot]
6b083dcd3e doc: Update translation status and sort locale files 2025-05-18 11:36:39 +00:00
leo
9614b995d8
refactor: workspace/page switcher (#1330)
- add `Switch Tab` popup
- change hotkey to open `Preferences` to `Ctrl+,/⌘+,`
- change hotkey to open `Switch Workspace` to `Ctrl+Shift+P/⌘+⇧+P`
- change hotkey to open `Switch Tab` to `Ctrl+P/⌘+P`

Signed-off-by: leo <longshuang@msn.cn>
2025-05-18 19:36:17 +08:00
github-actions[bot]
36c2e083cc doc: Update translation status and sort locale files
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
2025-05-18 07:02:46 +00:00
AquariusStar
fd35e0817d
localization: update russian translate (#1331) 2025-05-18 15:02:30 +08:00
github-actions[bot]
d429a6426a doc: Update translation status and sort locale files
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
2025-05-17 12:14:32 +00:00
leo
4c1ba717a7
refactor: rewrite workspace switcher (#1267)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-17 20:14:09 +08:00
github-actions[bot]
bd553405c2 doc: Update translation status and sort locale files 2025-05-17 10:37:25 +00:00
leo
f121975a28
code_review: PR #1328
* remove hotkey to open workspace dropdown menu
* call orignal `ViewModels.Launcher.SwitchWorkspace` directly in view
* add missing translation for Chinese

Signed-off-by: leo <longshuang@msn.cn>
2025-05-17 18:37:02 +08:00
github-actions[bot]
ea320d2cdf doc: Update translation status and sort locale files
Some checks are pending
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Localization Check / localization-check (push) Waiting to run
2025-05-17 05:17:22 +00:00
popara
01945f231e
Added workspaces shortcuts (#1328)
- added Alt+Space for opening Workspaces context menu (which can then be navigated normally with arrows)
- added Alt+1 through Alt+9 for switching to corresponding workspace
2025-05-17 13:17:10 +08:00
github-actions[bot]
506dbc218c doc: Update translation status and sort locale files 2025-05-17 05:12:20 +00:00
Javier J. Martínez M.
d3a740fb95
localization: update spanish translations (#1329)
add missing translations
2025-05-17 13:12:01 +08:00
leo
d3d0e7b15c
ux: thinner border for default avatar
Some checks are pending
Continuous Integration / Prepare version string (push) Waiting to run
Continuous Integration / Build (push) Waiting to run
Continuous Integration / Package (push) Blocked by required conditions
Signed-off-by: leo <longshuang@msn.cn>
2025-05-17 08:13:19 +08:00
Gadfly
879b84ac20
enhance: Show the stderr content from QueryLocalChanges (#1327) 2025-05-17 07:58:47 +08:00
github-actions[bot]
7f86ad9f22 doc: Update translation status and sort locale files 2025-05-16 12:08:16 +00:00
Leonardo
0c9cb41e68
localization: new keys translated to italian (#1323) 2025-05-16 20:08:04 +08:00
leo
86f27c5e58
refactor: generate hash based default avatar instead of simple label (#1322)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-16 17:55:02 +08:00
leo
1f0ab2bfec
refactor: simpfy SourceGit.Views.BranchTreeNodeIcon
Signed-off-by: leo <longshuang@msn.cn>
2025-05-16 13:43:41 +08:00
leo
fd935259aa
refactor: build tags view data in viewmodels instead of views
Signed-off-by: leo <longshuang@msn.cn>
2025-05-16 12:22:52 +08:00
github-actions[bot]
f46bbd01cd doc: Update translation status and sort locale files 2025-05-16 03:32:09 +00:00
leo
ed1351b1f7
feature: supports to show submodules as tree or list (#1307)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-16 11:31:53 +08:00
leo
d299469613
ux: show tooltip at right of hovered item in repository's left side bar (#1317)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-16 10:47:38 +08:00
leo
e4490d87dc
code_review: PR #1314
Signed-off-by: leo <longshuang@msn.cn>
2025-05-16 09:45:26 +08:00
Martin Smith
85b223a3d0
Task/UI usability tweaks (#1314)
* Allow About to center in parent
* About closes on Escape
* ConfirmEmptyCommit dialog closes on Escape
* Ignore Dev file
* Missed condition

---------

Co-authored-by: Martin Smith <martin.smith@purplebricks.com>
2025-05-16 09:27:42 +08:00
github-actions[bot]
6c62789c4c doc: Update translation status and sort locale files 2025-05-16 01:20:43 +00:00
AquariusStar
85e08f5eea
localization: update russian localization (#1319) 2025-05-16 09:20:31 +08:00
leo
463d161ac7
refactor: show submodule as tree instead of list (#1307) 2025-05-14 17:55:28 +08:00
github-actions[bot]
5ec51eefb9 doc: Update translation status and sort locale files 2025-05-14 08:02:08 +00:00
leo
bc5c4670de
feature: supports to use Ctrl+D/⌘+D to open in external diff/merge tool (#1312) 2025-05-14 16:01:47 +08:00
leo
d3363429df
ux: new style for submodule tooltip (#1307) 2025-05-14 15:49:42 +08:00
github-actions[bot]
f83b6c24ae doc: Update translation status and sort locale files 2025-05-14 06:27:00 +00:00
leo
61bb0f7dc7
feature: show submodule's URL in tooltip (#1307) 2025-05-14 14:26:33 +08:00
leo
20a239621b
fix: can not open submodule that has not been initialized 2025-05-14 11:48:44 +08:00
github-actions[bot]
9e91494a20 doc: Update translation status and sort locale files 2025-05-14 03:36:15 +00:00
leo
d71189c705
feature: tooltip for submodule list item (#1307) 2025-05-14 11:35:34 +08:00
leo
55232aeddd
project: ignore custom script files
Signed-off-by: leo <longshuang@msn.cn>
2025-05-13 22:55:24 +08:00
leo
6bf930a9e0
feature: show tags count in tags tree (#1306)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-13 22:50:10 +08:00
Göran W
5b72b15cf2
feature: show remote's URL in tooltip for relevant BranchTreeNodes (#1310) 2025-05-13 22:36:10 +08:00
leo
0e61a0196b
fix: right caption buttons should not visible on macOS (#1311)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-13 22:34:53 +08:00
leo
7bb4e355bd
feature: show branches count in branch tree (#1306) 2025-05-13 19:28:52 +08:00
leo
57d15dc6d3
fix: git submodule status may return lines that start as U character (#1307) 2025-05-13 18:11:51 +08:00
leo
65808e5f58
fix: filter with local branch should not include invalid upstream (gone) (#1308) 2025-05-13 17:59:51 +08:00
leo
cf7b61dd71
refactor: new way to display item count 2025-05-13 17:50:47 +08:00
leo
ac1bd7ca85
ux: hide tag message if it's the same with its name (#1305) 2025-05-13 14:22:41 +08:00
leo
142ee5a327
ux: use localized text instead of hard-coded string annotated (#1305) 2025-05-13 13:01:15 +08:00
leo
afc8a772dd
ux: new style for tag's tooltip (#1305) 2025-05-13 12:26:33 +08:00
leo
8a45e25106
refactor: rewrite custom WM_NCHITTEST implementation on Windows 2025-05-13 10:19:51 +08:00
leo
4e41a6207a
enhance: display tag's name instead of nothing while showing tooltip of tag without message 2025-05-13 10:01:41 +08:00
Göran W
a5c25cf9fe
enhance: add border around tag name, makes tooltip work as for branches
(cherry picked from commit 6a5e6d12d70f52e5777cc4edc4022fed870151d4)
2025-05-13 09:38:09 +08:00
leo
11a9d7fdd8
enhance: force using --no-sign to ignore tag.gpgsign configuration while creating lightweight tag
Signed-off-by: leo <longshuang@msn.cn>
2025-05-13 09:24:00 +08:00
leo
ef4b639f8e
code_style: move platform dependent code to initialize window to namespace SourceGit.Native
Signed-off-by: leo <longshuang@msn.cn>
2025-05-12 21:52:50 +08:00
leo
c62b4a031f
perf: return HTCLIENT directly when window is fullscreen or maximized
Signed-off-by: leo <longshuang@msn.cn>
2025-05-12 18:09:25 +08:00
leo
af9cf6ba6a
ux: force using 4 * RenderScaling as resize border size on Windows
Signed-off-by: leo <longshuang@msn.cn>
2025-05-12 17:57:49 +08:00
leo
641098ffb2
ux: better content padding for maximized window on Windows
Signed-off-by: leo <longshuang@msn.cn>
2025-05-12 16:27:54 +08:00
leo
fcad8eeadc
Merge branch 'master' into develop 2025-05-12 09:24:48 +08:00
leo
01625ada1a
Merge branch 'release/v2025.17' 2025-05-12 09:23:46 +08:00
leo
88dc12275a
version: Release 2025.17
Signed-off-by: leo <longshuang@msn.cn>
2025-05-12 09:22:28 +08:00
Bailey Allen
bac21c5714
enhance: added support for kitty terminal on macOS and Linux. (#1300) 2025-05-12 09:17:20 +08:00
github-actions[bot]
19a51f227b doc: Update translation status and sort locale files 2025-05-12 01:13:27 +00:00
Javier J. Martínez M.
b6d618a6d7
localization: update spanish translations (#1302)
* localization: update spanish translations

add missing translations

* localization: update spanish translations

add missing translations
2025-05-12 09:13:13 +08:00
github-actions[bot]
2573553e01 doc: Update translation status and sort locale files 2025-05-12 01:12:59 +00:00
AquariusStar
9dd0beb61f
localization: update russian translate (#1301) 2025-05-12 09:12:49 +08:00
leo
029fd6933f
refactor: new way to discard selected or all local changes
This modification aims to solve the problem that the deleted submodule cannot be discarded.

Signed-off-by: leo <longshuang@msn.cn>
2025-05-09 22:57:46 +08:00
leo
0f6c8976af
refactor: rewrite checkout/create branch with submodules
Signed-off-by: leo <longshuang@msn.cn>
2025-05-09 18:12:30 +08:00
leo
e446e97f28
fix: remove testing code for git checkout command
Signed-off-by: leo <longshuang@msn.cn>
2025-05-09 17:22:17 +08:00
leo
3e530de9cc
enhance: update submodules individually (#1272)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-09 17:12:12 +08:00
leo
6cf1b20ea6
refactor: context menu for commit change and revision file
Signed-off-by: leo <longshuang@msn.cn>
2025-05-09 14:11:15 +08:00
github-actions[bot]
321ccf9622 doc: Update translation status and sort locale files 2025-05-09 02:47:52 +00:00
leo
ebe0e61367
feature: support to enable --squash and --push option while finishing git-flow branches (#1290)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-09 10:47:36 +08:00
leo
e8bf58f6c3
code_review: PR #1292
Use syntax `String.AsSpan(int start, int len)` instead of `String.AsSpan().Slice(int start, int len)`

Signed-off-by: leo <longshuang@msn.cn>
2025-05-09 09:30:00 +08:00
qiufengshe
15ee2dac91
perf: minimize temporary strings for better performance (#1292) 2025-05-09 09:19:33 +08:00
github-actions[bot]
5d1601086f doc: Update translation status and sort locale files 2025-05-09 01:16:10 +00:00
AquariusStar
3eaa24a993
localization: update and fix translation russian (#1291) 2025-05-09 09:15:59 +08:00
leo
6986e1ac24
code_style: calculate bounds only when it is needed
Signed-off-by: leo <longshuang@msn.cn>
2025-05-08 13:42:21 +08:00
leo
2c8370fa92
refactor: get graph clip width from grid column definition directly
Signed-off-by: leo <longshuang@msn.cn>
2025-05-08 13:39:27 +08:00
leo
008708f07c
ux: use larger font size for commit ref label
Signed-off-by: leo <longshuang@msn.cn>
2025-05-08 13:13:22 +08:00
leo
832fcd7487
fix: offset of commit graph does not look quite right (#1287)
This is because that when using `VirtualizingStackPanel`, the `Bounds.Height` of `ListBoxItem` may not be the same with its `Height` setted in axaml.

Signed-off-by: leo <longshuang@msn.cn>
2025-05-08 12:22:23 +08:00
leo
6df38ad970
ux: new style for inline code in commit subject
Signed-off-by: leo <longshuang@msn.cn>
2025-05-07 20:23:06 +08:00
github-actions[bot]
0a7b973388 doc: Update translation status and sort locale files 2025-05-07 11:08:51 +00:00
Christopher Göttfert
6b050fa557
localization: updated german translations (#1284) 2025-05-07 19:08:39 +08:00
leo
417ab3ecc2
ux: layout for revision compare targets
Signed-off-by: leo <longshuang@msn.cn>
2025-05-07 09:52:26 +08:00
leo
a413df6f89
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 20:56:45 +08:00
leo
ddf643c081
ux: new style for revision/branch compare targets
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 20:52:43 +08:00
leo
bbc840a5cb
perf: set/update TimeToSort while creating branch nodes
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 19:26:06 +08:00
github-actions[bot]
c8e21673e4 doc: Update translation status and sort locale files 2025-05-06 10:24:59 +00:00
leo
e45e37d305
feature: supports sort branches by committer date (#1192)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 18:24:34 +08:00
github-actions[bot]
b7fa04d141 doc: Update translation status and sort locale files 2025-05-06 07:52:23 +00:00
leo
93a5d7baea
feature: supports to visit remote repository in web browser (#1265)
- combine `Open in File Manager`, `Open in Terminal` and `Open with external editor` into one dropdown menu
- add `Visit $REMOTE in Browser`

Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 15:51:57 +08:00
leo
e4e2f7b3a7
ux: use smaller font size for inline code in commit subject
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 14:49:54 +08:00
leo
eae6d10784
enhance: only log exception in popup task (#1281)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 12:17:48 +08:00
github-actions[bot]
4bc5b90e6b
doc: Update translation status and sort locale files
(cherry picked from commit 15445d02379020144239886bc87380ae38c2018a)
2025-05-06 12:02:19 +08:00
leo
df29edd8f0
feature: make --recurse-submdoules an option while trying to checkout branch with submodules (#1272)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 12:01:58 +08:00
leo
054bbf7e0c
enhance: do not override core.autocrlf configure while reading file diff (#1278)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 09:39:03 +08:00
leo
ce00fa6c88
Merge branch 'master' into develop 2025-05-06 09:23:20 +08:00
leo
a960e14368
Merge branch 'release/v2025.16' 2025-05-06 09:22:58 +08:00
leo
867edd9453
version: Release 2025.16
Signed-off-by: leo <longshuang@msn.cn>
2025-05-06 09:22:49 +08:00
github-actions[bot]
aee4ce6387 doc: Update translation status and sort locale files 2025-05-06 01:17:55 +00:00
Javier J. Martínez M.
d92d279fbe
localization: update spanish translations (#1279)
add missing translations
2025-05-06 09:17:45 +08:00
github-actions[bot]
5e080279ce doc: Update translation status and sort locale files 2025-05-04 09:36:42 +00:00
AquariusStar
704c6f589d
localization: update and fix translation russian (#1276) 2025-05-04 17:36:30 +08:00
broknecho
666275c747
feature: add Meld as an option for external merge tool on Windows (#1275) 2025-05-04 11:24:11 +08:00
leo
c0c52695a3
code_style: remove unused code
Signed-off-by: leo <longshuang@msn.cn>
2025-05-03 21:31:10 +08:00
Alen Šiljak
c529fab869
feature: close repository configuration dialog when user pressed Esc (#1269) 2025-05-03 21:18:24 +08:00
leo
4b2983b330
fix: commit detail panel is overlapping history when resizing (#1273)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-03 21:09:43 +08:00
leo
8c1d397480
fix: inline blocks is not sorted in order (#1274)
Signed-off-by: leo <longshuang@msn.cn>
2025-05-03 20:52:40 +08:00
leo
007acb3fa6
project: remove unused scripts
Signed-off-by: leo <longshuang@msn.cn>
2025-04-30 21:40:01 +08:00
leo
3b0c57be84
feature: supports to re-order workspaces (#1261)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-30 21:39:03 +08:00
github-actions[bot]
61bc42612e doc: Update translation status and sort locale files 2025-04-30 13:06:53 +00:00
leo
fe677d40c1
feature: supports search commits by change content (#1263)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-30 21:05:53 +08:00
leo
9bde797b24
fix: make sure the new pattern is appended as a new line (#1264)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-30 20:41:00 +08:00
leo
7501588c95
enhance: quit application after main window has been closed
Signed-off-by: leo <longshuang@msn.cn>
2025-04-30 15:03:14 +08:00
leo
80aead3a17
feature: add dirty state indicator icon to repository tab (#1227)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-30 11:01:39 +08:00
leo
847a1e727b
refactor: enable --ignore-cr-at-eol in diff by default
Signed-off-by: leo <longshuang@msn.cn>
2025-04-30 09:26:34 +08:00
leo
98dd37a9bc
localization: update tranlation for Text.Diff.IgnoreWhitespace
This is because that in `git diff` command the `--ignore-all-space` option will also ignore line-ending changes (`--ignore-cr-at-eol`)

Signed-off-by: leo <longshuang@msn.cn>
2025-04-29 22:49:20 +08:00
leo
95ea0a6ba6
ux: Ignore Whitespace and EOL Changes should always be visible (#1260)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-29 22:21:38 +08:00
leo
b9dc5a8164
feature: parse url in commit message (#1133)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-29 18:08:35 +08:00
leo
63803c9b88
feature: show command running time in logs window (#1253)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-29 16:36:05 +08:00
leo
825b74c2a3
refactor: use String.AsSpan(int, int) instead of String.AsSpan().Slice(int, int)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-29 09:44:06 +08:00
qiufengshe
48bb8e91de
perf: minimize temporary strings for better performance (#1255) 2025-04-29 09:33:14 +08:00
leo
53a55467f1
enhance: ignore submodule changes when deal with local changes before pull/checkout/create branch (#1256)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-29 09:27:09 +08:00
leo
5681bf489d
fix: empty dialog when generating commit message with AI (#1257)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-29 09:14:24 +08:00
leo
226bc434f5
ux: make log window resizable (#1253)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-28 16:53:51 +08:00
leo
30d42b11e2
enhance: wait a while after branch changed (#1254)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-28 16:19:40 +08:00
leo
2698427cd0
fix: popup running animation did not update after switch back from another page
Signed-off-by: leo <longshuang@msn.cn>
2025-04-28 11:57:36 +08:00
leo
b4f1f35e67
Merge branch 'master' into develop 2025-04-28 09:17:40 +08:00
leo
92f215d039
Merge branch 'release/v2025.15' 2025-04-28 09:16:44 +08:00
leo
2e1cf76c82
version: Release 2025.15
Signed-off-by: leo <longshuang@msn.cn>
2025-04-28 09:16:37 +08:00
leo
951ea8f088
fix: use subject as context menu item header to fix vertical alignment (#1251)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-27 11:20:44 +08:00
Chiahong
21cb87cec5
localization: update zh_TW.axaml (#1249) 2025-04-27 09:38:28 +08:00
github-actions[bot]
f39048df77 doc: Update translation status and sort locale files 2025-04-27 01:38:20 +00:00
AquariusStar
bbdeecdcc6
locallization: update russian translate (#1248) 2025-04-27 09:38:09 +08:00
leo
d2e688908c
ux: use different inline code background for different themes
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 21:26:21 +08:00
leo
91acf0a32a
enhance: fore invalidate measure after data context of BisectStateIndicator changed
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 20:55:11 +08:00
leo
d44d2b9770
ux: use a outer border to hold tooltip of commit message in FileHistories view (#1232)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 18:50:56 +08:00
cdammanintopix
f09367a614
fix: Append UserName to the SourceGitIPCChannel NamedPipeServerStream to allow multiple users usage on the same server (#1244) (#1246) 2025-04-25 16:56:28 +08:00
leo
00e56ce9d1
fix: System.NullReferenceException raised after popup stop (success or not) running
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 15:56:37 +08:00
leo
22d4f26bc3
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 14:31:14 +08:00
leo
a94c7f55ce
ux: remove tips in commit list
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 13:37:11 +08:00
leo
1d16925e74
enhance: stop render next inline elements when it is out of bounds
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 13:30:00 +08:00
leo
8c4362a98d
feature: subject presenter supports inline codeblock
Signed-off-by: leo <longshuang@msn.cn>
2025-04-25 13:24:13 +08:00
leo
9efbc7dd7a
localization: update translations for Chinese
Signed-off-by: leo <longshuang@msn.cn>
2025-04-24 10:04:57 +08:00
github-actions[bot]
c519381645 doc: Update translation status and sort locale files 2025-04-24 02:00:26 +00:00
leo
6590812634
localization: update translations for Chinese
Signed-off-by: leo <longshuang@msn.cn>
2025-04-24 10:00:07 +08:00
github-actions[bot]
ad6ed1512b doc: Update translation status and sort locale files 2025-04-24 01:22:43 +00:00
Javier J. Martínez M.
f73e0687a1
localization: update spanish translations (#1241)
add missing translations. `Bisect`/`Bisecting` stays the same because they reference command names.
2025-04-24 09:22:32 +08:00
qiufengshe
ea680782fe
perf: minimize temporary strings for better performance (#1240)
(cherry picked from commit f4dad2bf551ead5640a500297a4a6f408aef1350)
2025-04-23 21:15:58 +08:00
leo
7e282b13fa
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-04-23 20:59:39 +08:00
leo
1386ca30e3
fix: typo in conventional commit type (#1239)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-23 20:52:41 +08:00
github-actions[bot]
2107676058 doc: Update translation status and sort locale files 2025-04-23 07:34:37 +00:00
leo
f72f1894c3
feature: supports to enable --ignore-cr-at-eol in diff by default
Signed-off-by: leo <longshuang@msn.cn>
2025-04-23 15:34:21 +08:00
github-actions[bot]
586ff39da1 doc: Update translation status and sort locale files 2025-04-23 02:39:41 +00:00
AquariusStar
9bdbf47522
localization: update russian localization (#1233) 2025-04-23 10:39:30 +08:00
leo
17c08d42a0
enhance: ignore all sub-directories those names start with '.' (#1234)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-23 10:38:01 +08:00
leo
fafa2a53ae
enhance: show commit full message tooltip when hover commit subject in FileHistories view (#1232)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-23 10:33:49 +08:00
leo
7890f7abbf
refactor: use PointerPressed event instead of ListBox.SelectionChanged event to navigate to commit (#1230)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-23 10:17:14 +08:00
leo
345ad06aba
refactor: diff for staged file with --amend enabled (#1231)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 19:20:27 +08:00
leo
78f4809875
fix: no changes were displayed when try to amend a commit without parent (branch first commit) (#1231)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 19:04:40 +08:00
leo
87ebe3741d
fix: for init-commit, app will crash with COMMIT & PUSH due to local branch has not been updated (#1229)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 18:45:14 +08:00
leo
f2000b4a84
enhance: show git log without command itself for git bisect
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 17:51:55 +08:00
leo
9a6c671a96
refactor: --ignore-cr-at-eol is not necessary when --ignore-all-space is enabled
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 16:50:46 +08:00
leo
34e0ea3bcb
enhance: raise bisect error manually
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 16:07:23 +08:00
leo
7be37424e1
fix: modal dialog did not take focus after show (#1225)
Co-authored-by: Gadfly <gadfly@gadfly.vip>
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 16:02:27 +08:00
github-actions[bot]
a42df87b9c doc: Update translation status and sort locale files 2025-04-22 07:45:38 +00:00
leo
df5294bcb7
feature: git bisect support
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 15:45:15 +08:00
leo
9eae1eeb81
ux: add InputGesture for hotkeys dialog
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 11:05:39 +08:00
leo
4c3698b171
feature: use F1 to quick open the Keyboard Shortcuts Reference dialog (#1225)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 10:30:19 +08:00
qiufengshe
9f18cbca5b
minimize temporary strings for better performance (#1224)
* minimize temporary strings for better performance

* minimize temporary strings for better performance

(cherry picked from commit c9e6a8d4c2d7b5fe03ee13af0a79c5334c23b1c0)
2025-04-22 10:23:20 +08:00
leo
6882ae069f
enhance: do not show tooltip if the ower window is deactived (#1218)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-22 10:22:02 +08:00
leo
9c53894cb4
ux: add an empty icon if there are no git command logs available
Signed-off-by: leo <longshuang@msn.cn>
2025-04-21 18:48:01 +08:00
leo
06d033464d
code_style: move commit link parser to Models.CommitLink.Get
Signed-off-by: leo <longshuang@msn.cn>
2025-04-21 17:27:07 +08:00
leo
750ca8ec61
refactor: use custom view locator to create new window/dialog (#1216)
Signed-off-by: leo <longshuang@msn.cn>
(cherry picked from commit 3e6f2b25f15b263e2b84922abc5cf6d621d62a83)
2025-04-21 15:32:21 +08:00
leo
86113701f3
Merge branch 'master' into develop 2025-04-21 09:49:51 +08:00
leo
387b68cdfe
Merge branch 'release/v2025.14' 2025-04-21 09:49:02 +08:00
leo
550c108f84
version: Release 2025.14
Signed-off-by: leo <longshuang@msn.cn>
2025-04-21 09:48:52 +08:00
qiufengshe
232482ca92
minimize temporary strings for better performance (#1215)
(cherry picked from commit b4fa80c0939ca198bff8e858a4dc241efd31d558)
2025-04-21 09:44:26 +08:00
heartacker
b4db88a663
chore: update Avalonia package references to version 11.2.8 (#1220) 2025-04-21 09:43:44 +08:00
leo
41416a6bed
refactor: use DataTemplates instead of create NamedHighlightedTextBlock manually for menu item (#1216)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-20 11:05:24 +08:00
leo
5fd074a9b6
refactor: use view locator instead of creating views manually in viewmodels (#1213)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-19 11:14:19 +08:00
leo
413669741d
enhance: ensure sourcegit_rebase_jobs.json only being used when orig-head and onto are both matched
Signed-off-by: leo <longshuang@msn.cn>
2025-04-18 12:49:19 +08:00
leo
75b4a4b294
enhance: record more git command logs
Signed-off-by: leo <longshuang@msn.cn>
2025-04-18 11:29:59 +08:00
leo
d254b557a9
docs: update README.md
Signed-off-by: leo <longshuang@msn.cn>
2025-04-18 10:25:53 +08:00
leo
892f3b8032
code_style: move SourceGit.CommandExtensions to SourceGit.ViewModels.CommandExtensions
Signed-off-by: leo <longshuang@msn.cn>
2025-04-18 10:24:20 +08:00
leo
afe5d4b969
ux: show an icon to draw user's attention to LOCAL CHANGES when there is an in-progress operation (#1210)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-18 09:59:34 +08:00
lwray-renesas
4d31392085
Fixed tooltip
Tooltip for chosing mine was wrong.
Was --theirs when should be --ours.

(cherry picked from commit 26a471933c)
2025-04-18 09:47:31 +08:00
leo
de31d4bad4
ux: layout of git command log item
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 21:17:54 +08:00
github-actions[bot]
5bd7dd428d doc: Update translation status and sort locale files 2025-04-17 12:04:02 +00:00
leo
4c1a04477e
refactor: enhanced copy commit information context menu (#1209)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 20:03:46 +08:00
leo
090b64d68d
refactor: notification popup uses the same text presenter with git command log viewer (#1149)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 18:21:55 +08:00
leo
231010abc6
ux: custom style for command line in git command log
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 17:45:49 +08:00
leo
3358ff9aee
enhance: disable hyper link and email link in git command logs
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 17:24:56 +08:00
leo
104a3f0bbf
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 16:35:18 +08:00
github-actions[bot]
a06d1183d7 doc: Update translation status and sort locale files 2025-04-17 08:32:08 +00:00
leo
9f493abd1a
enhance: add context menu for selected log
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 16:31:30 +08:00
github-actions[bot]
349844cf2a doc: Update translation status and sort locale files 2025-04-17 08:07:57 +00:00
leo
021aab8408
enhance: add a button to clear all git command logs
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 16:07:40 +08:00
leo
c1e31ac4e3
ci: try to remove zlib1g-dev:arm64
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 15:48:02 +08:00
github-actions[bot]
2a43efde07 doc: Update translation status and sort locale files 2025-04-17 05:34:40 +00:00
Javier J. Martínez M.
33ae6a9989
localization: update spanish translations (#1206)
add missing translations
modify instances of `stagear` with `hacer stage`
2025-04-17 13:34:27 +08:00
leo
0e967ffc8e
fix: pressing Alt+Enter to commit and push in a repository that has no remotes will crash (#1205)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 13:30:41 +08:00
github-actions[bot]
c231772298 doc: Update translation status and sort locale files 2025-04-17 05:24:26 +00:00
leo
8b39df32cc
feature: git command logs
Signed-off-by: leo <longshuang@msn.cn>
2025-04-17 13:23:56 +08:00
leo
928a0ad3c5
feature: add wip (work in progress) type (#1200)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-16 19:39:24 +08:00
leo
9606f128e4
enhance: remember commit message when exiting (#1166)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-16 16:36:23 +08:00
leo
67255a5529
ux: reduce combobox item height
Signed-off-by: leo <longshuang@msn.cn>
2025-04-16 15:42:44 +08:00
leo
cac4b7edf6
enhance: conventional commit message helper (#1200)
- add `build`, `ci`, `pref`
- re-design helper dialog

Signed-off-by: leo <longshuang@msn.cn>
2025-04-16 15:40:26 +08:00
leo
fa44fa773c
ux: re-design welcome (repositories manager) page (#1202)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-16 11:54:50 +08:00
leo
db46de0261
enhance: append character U+26D4 to line when \ No newline at end of file is found in git diff output (#1197)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-16 11:41:40 +08:00
leo
e9036b5fb9
ux: re-design commit message input box
Signed-off-by: leo <longshuang@msn.cn>
2025-04-16 10:22:54 +08:00
leo
9ba0b595d9
enhance: remember the last state of Ignore Whitespace Change and EOF in text diff view (#1198)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 17:58:26 +08:00
github-actions[bot]
cf763b47c6 doc: Update translation status and sort locale files 2025-04-15 09:47:30 +00:00
leo
539d3f6eca
ux: re-design commit message input box (#1169)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 17:47:12 +08:00
leo
03216fc31e
code_style: run dotnet format and re-order codes
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 16:30:50 +08:00
leo
3cc463d24b
enhance: use Environment.Exit(0) instead of IClassicDesktopStyleApplicationLifetime.Shutdown to stop for non-first instance of SourceGit
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 16:24:48 +08:00
leo
33a463ce59
feature: allow to view contribution chart based on selected author (#1196)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 16:08:38 +08:00
leo
90b37663ed
refactor: use lock file instead of named mutex since the second one may not work on other platforms
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 14:36:12 +08:00
leo
9ebde1943e
project: downgrade AvaloniaUI to 11.2.6 to fix duplicated characters when input to textbox (#1195)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 11:15:13 +08:00
leo
be3f418680
fix: no diff content shows with new files (#1193)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 11:03:34 +08:00
leo
a97f163860
readme: update translation tips
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 10:53:53 +08:00
github-actions[bot]
c1839199ee doc: Update translation status and sort locale files 2025-04-15 02:42:33 +00:00
leo
7d5ffaf867
code_style: keep all translations ordered by key
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 10:42:16 +08:00
github-actions[bot]
f0d4cfc9f9 doc: Update translation status and sort locale files 2025-04-15 02:30:43 +00:00
Oleksii Borovyk
70494485ab
Added ukrainian translation (#1191)
(cherry picked from commit b40bfeb98f35da080a1b3935e801e422858faf14)
2025-04-15 10:30:24 +08:00
leo
c4c04b8b01
enhance: bring window into view after receive IPC message
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 10:19:57 +08:00
leo
e2da44c8fd
enhance: use Mutex to force running SourceGit in singleton mode
Signed-off-by: leo <longshuang@msn.cn>
2025-04-15 09:35:16 +08:00
leo
0acbe3e487
enhance: use PipeOptions.FirstPipeInstance to create NamedPipeServerStream
Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 23:55:42 +08:00
leo
05982e6dc0
style: re-design style for disabled primary button
Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 23:23:40 +08:00
leo
e5dc211c35
refactor: simpfy IPC code
Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 23:17:04 +08:00
Gadfly
1e0fd63543
localization: add translation sorting and formatting (#1186)
* doc: Update translation status and missing keys

* localization: add translation sorting and formatting

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-14 22:07:24 +08:00
Gadfly
3b1018e0e2
fix: update visible staged changes retrieval in WorkingCopy (#1187)
* doc: Update translation status and missing keys

* fix: update visible staged changes retrieval in WorkingCopy

* fix: prevent unintended amend behavior when changing current branch

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-14 22:05:05 +08:00
leo
7d20f97f4e
code_review: PR #1185
- make `SourceGit` running in singleton mode
- `TrySendArgsToExistingInstance` should not be called before `BuildAvaloniaApp().StartWithClassicDesktopLifetime(args)` since we may want to launch `SourceGit` as a core editor.
- avoid `preference.json` to be saved by multiple instances.
- move IPC code to models.

Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 22:03:51 +08:00
Massimo
09c0edef8e
feat: implement IPC for opening repositories in new tabs (#1185)
* refactor: improve diff handling for EOL changes and enhance text diff display

- Updated `Diff.cs` to streamline whitespace handling in diff arguments.
- Enhanced `DiffContext.cs` to check for EOL changes when old and new hashes differ, creating a text diff if necessary.
- Added support for showing end-of-line symbols in `TextDiffView.axaml.cs` options.

* localization: update translations to include EOF handling in ignore whitespace messages

- Modified the ignore whitespace text in multiple language files to specify that EOF changes are also ignored.
- Ensured consistency across all localization files for the patch application feature.

* revert: Typo in DiffResult comment

* revert: update diff arguments to ignore CR at EOL in whitespace handling (like before changes)

* revert: update translations to remove EOF references in Text.Apply.IgnoreWS and fixed typo in Text.Diff.IgnoreWhitespace (EOF => EOL)

* feat: add workspace-specific default clone directory functionality

- Implemented logic in Clone.cs to set ParentFolder based on the active workspace's DefaultCloneDir if available, falling back to the global GitDefaultCloneDir.
- Added DefaultCloneDir property to Workspace.cs to store the default clone directory for each workspace.
- Updated ConfigureWorkspace.axaml to include a TextBox and Button for setting the DefaultCloneDir in the UI.
- Implemented folder selection functionality in ConfigureWorkspace.axaml.cs to allow users to choose a directory for cloning.
- This closes issue #1145

* feat: implement IPC for opening repositories in new tabs

- Added functionality to send repository paths to an existing instance of the application using named pipes.
- Introduced a new preference option to open repositories in a new tab instead of a new window.
- Updated UI to include a checkbox for the new preference.
- Enhanced the handling of IPC server lifecycle based on the new preference setting.
- This closes issue #1184

---------

Co-authored-by: mpagani <massimo.pagani@unitec-group.com>
2025-04-14 19:16:15 +08:00
github-actions[bot]
558eb7c9ac doc: Update translation status and missing keys 2025-04-14 09:03:23 +00:00
leo
b7aa49403b
code_review: PR #1183
- code style in `Clone` constructor
- re-design workspace configuration dialog

Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 17:03:08 +08:00
Massimo
f14a666091
feat: add workspace-specific default clone directory functionality (#1183)
* refactor: improve diff handling for EOL changes and enhance text diff display

- Updated `Diff.cs` to streamline whitespace handling in diff arguments.
- Enhanced `DiffContext.cs` to check for EOL changes when old and new hashes differ, creating a text diff if necessary.
- Added support for showing end-of-line symbols in `TextDiffView.axaml.cs` options.

* localization: update translations to include EOF handling in ignore whitespace messages

- Modified the ignore whitespace text in multiple language files to specify that EOF changes are also ignored.
- Ensured consistency across all localization files for the patch application feature.

* revert: Typo in DiffResult comment

* revert: update diff arguments to ignore CR at EOL in whitespace handling (like before changes)

* revert: update translations to remove EOF references in Text.Apply.IgnoreWS and fixed typo in Text.Diff.IgnoreWhitespace (EOF => EOL)

* feat: add workspace-specific default clone directory functionality

- Implemented logic in Clone.cs to set ParentFolder based on the active workspace's DefaultCloneDir if available, falling back to the global GitDefaultCloneDir.
- Added DefaultCloneDir property to Workspace.cs to store the default clone directory for each workspace.
- Updated ConfigureWorkspace.axaml to include a TextBox and Button for setting the DefaultCloneDir in the UI.
- Implemented folder selection functionality in ConfigureWorkspace.axaml.cs to allow users to choose a directory for cloning.
- This closes issue #1145

---------

Co-authored-by: mpagani <massimo.pagani@unitec-group.com>
2025-04-14 16:41:34 +08:00
leo
e89dbd8f43
code_review: PR #1177
- use `Command.ReadToEnd` instead of `Command.Exec` to avoid git trims line endings.
- use `StringBuilder.Append('\n')` instead of `StringBuilder.AppendLine()` to restore original line endings (we split the original diff output by `\n` not `\r')
- there's no need to show file content (the `StreamReader.ReadLine()` will trim line endings)

Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 16:06:52 +08:00
Massimo
81820e7034
refactor: improve diff handling for EOL changes and enhance text diff… (#1177)
* refactor: improve diff handling for EOL changes and enhance text diff display

- Updated `Diff.cs` to streamline whitespace handling in diff arguments.
- Enhanced `DiffContext.cs` to check for EOL changes when old and new hashes differ, creating a text diff if necessary.
- Added support for showing end-of-line symbols in `TextDiffView.axaml.cs` options.

* localization: update translations to include EOF handling in ignore whitespace messages

- Modified the ignore whitespace text in multiple language files to specify that EOF changes are also ignored.
- Ensured consistency across all localization files for the patch application feature.

* revert: Typo in DiffResult comment

* revert: update diff arguments to ignore CR at EOL in whitespace handling (like before changes)

* revert: update translations to remove EOF references in Text.Apply.IgnoreWS and fixed typo in Text.Diff.IgnoreWhitespace (EOF => EOL)

---------

Co-authored-by: mpagani <massimo.pagani@unitec-group.com>
2025-04-14 15:18:45 +08:00
leo
e7f0217a7b
refactor: move binding for ToolTip.IsOpen from code to axaml
Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 11:51:40 +08:00
leo
0cb2ca78fe
code_review: PR #1180
- replace `SetNeedNavigateToUpstreamHead` with `NavigateToBranchDelayed`
- navigate to current HEAD instead of original source HEAD after merge

Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 11:35:50 +08:00
Gadfly
17cf402c78
enhance: navigate to upstream head after fetch, pull, and merge (#1180) 2025-04-14 10:42:34 +08:00
leo
245de9b458
fix: tooltip did not hide after pointer move out (#1178)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 10:40:24 +08:00
leo
e76328ff38
Merge branch 'master' into develop 2025-04-14 09:56:48 +08:00
leo
61a1b130f2
Merge branch 'release/v2025.13' 2025-04-14 09:55:55 +08:00
leo
69d8d963ea
version: Release 2025.13
Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 09:55:49 +08:00
leo
48835ca043
project: upgrade AvaloniaUI to 11.2.7
Signed-off-by: leo <longshuang@msn.cn>
2025-04-14 09:53:59 +08:00
github-actions[bot]
241f92a290 doc: Update translation status and missing keys 2025-04-14 01:47:39 +00:00
AquariusStar
12b1204809
update russian localization (#1181) 2025-04-14 09:47:23 +08:00
leo
cd5a682194
refactor: directly use --exclude=HEAD instead of --exclude=HEA[D]
Signed-off-by: leo <longshuang@msn.cn>
2025-04-11 15:44:02 +08:00
leo
18888de081
refactor: rewrite histories filter to support ref name that contains non-ascii characters (#1175)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-11 15:39:51 +08:00
github-actions[bot]
13af0a43ed doc: Update translation status and missing keys 2025-04-11 04:31:25 +00:00
leo
af350c2fcd
code_review: PR #1174
- keeps all keys in locale files in order
- add தமிழ் (Tamil)

Signed-off-by: leo <longshuang@msn.cn>
2025-04-11 12:31:09 +08:00
தமிழ் நேரம்
accccb5ea3
தமிழ் (Tamil) translation file added (#1174)
* Tamil file added

220

* 0

* Tamil file added

220

0

(cherry picked from commit 355db34db382d17e0b8f0bb6f05b8e2e2f2963d9)
2025-04-11 12:22:48 +08:00
github-actions[bot]
cfabfb7368 doc: Update translation status and missing keys 2025-04-11 02:02:56 +00:00
leo
1799de4907
code_review: PR #1173
- rename c-style `file_arg` to `fileArg`
- add missing translations for zh_CN and zh_TW
- re-design conflict view and add tooltip for `USE THEIRS` and `USE MINE`
- re-order unstaged toolbar buttons

Signed-off-by: leo <longshuang@msn.cn>
2025-04-11 10:02:33 +08:00
github-actions[bot]
a99ab37797 doc: Update translation status and missing keys 2025-04-11 01:33:18 +00:00
Göran W
47824dc27a
Add button for running external mergetool on ALL conflicts (#1173)
* Make a few non-translated strings localizable (in Conflict view)

* Add button and wiring to run mergetool on all conflicts

* Corrected spelling and wording in related code and exception msg
2025-04-11 09:33:07 +08:00
leo
3b18ee0b37
code_style: remove unused code
Signed-off-by: leo <longshuang@msn.cn>
2025-04-08 20:20:20 +08:00
github-actions[bot]
5d90c2ed60 doc: Update translation status and missing keys 2025-04-08 12:06:21 +00:00
leo
768b324356
ux: if there are no local changes, show different confirm message (#1143)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-08 20:06:00 +08:00
github-actions[bot]
8b5f491e34 doc: Update translation status and missing keys 2025-04-08 12:01:06 +00:00
leo
506af95963
enhance: new confirm empty commit dialog (#1143)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-08 20:00:42 +08:00
leo
898a8bc69a
ux: resize confirm commit dialog
Signed-off-by: leo <longshuang@msn.cn>
2025-04-08 18:05:53 +08:00
leo
da38b72ee5
ux: disable commit button when commit message is empty
Signed-off-by: leo <longshuang@msn.cn>
2025-04-08 18:03:40 +08:00
leo
7cda7211f1
refactor: statistics dialog
- use `%aN+%aE` instead of `%aN` to get commit author
- show user avatar in statistics dialog

Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 21:20:59 +08:00
Göran W
1555abd027
Added new ExternalMerger - Plastic SCM (#1162)
Motivation:
https://m-pixel.com/how-to-use-plastic-scms-merge-tool-with-p4v/
2025-04-07 20:22:53 +08:00
github-actions[bot]
7fedef396f doc: Update translation status and missing keys 2025-04-07 12:19:19 +00:00
leo
2c5ee4fa99
localization: add keys deleted by sorter tools back
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 20:19:00 +08:00
github-actions[bot]
f29402ceec doc: Update translation status and missing keys 2025-04-07 12:05:43 +00:00
leo
f5c213060e
localization: keep all keys in order and remove duplicated keys in fr_FR (#1161)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 20:05:24 +08:00
leo
3275dd07d2
enhance: auto stash and re-apply local changes before squashing (#1141)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 16:04:10 +08:00
github-actions[bot]
67fb0b300f doc: Update translation status and missing keys 2025-04-07 06:43:08 +00:00
leo
3049730dd5
feature: add Preferred Merge Mode in repository configure (#1156)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 14:42:46 +08:00
leo
ad9021e892
enhance: allow using + character in branch name (#1152)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 14:07:58 +08:00
leo
39f7f119dd
doc: always show current translation status in develop branch
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 12:06:06 +08:00
leo
3431ed4bab
Merge branch 'master' into develop 2025-04-07 12:02:24 +08:00
leo
f3d99d64bf
Merge branch 'release/v2025.12' 2025-04-07 12:00:59 +08:00
leo
b65c697e5b
version: Release 2025.12
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 12:00:45 +08:00
github-actions[bot]
48f8b6116a doc: Update translation status and missing keys 2025-04-07 03:48:59 +00:00
leo
fa02c65da5
code_review: PR #1153
- use a single filter for both unstage and staged files
- show confirm dialog if staged files are displayed partially

Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 11:48:38 +08:00
Göran W
a37c6b29ec
In Local Changes, added filter-box in Staged area, to match Unstaged area (#1153)
Also added minimal handling (RaiseException) if trying to commit with active filter (might commit more changes than visible, so disallow).
Minor unification in unstageChanges() to make it more similar to StageChanges().
2025-04-07 10:37:58 +08:00
leo
ac7b02590b
enhance: add comma between date and time (#1150)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 10:23:37 +08:00
leo
8c9cf05c1d
fix: renamed files are missing in commit changes and stash changes (#1151)
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 10:14:02 +08:00
leo
c615d04038
doc: update README.md for Japanese support
Signed-off-by: leo <longshuang@msn.cn>
2025-04-07 09:54:48 +08:00
github-actions[bot]
17d285d9bf doc: Update translation status and missing keys 2025-04-07 01:53:35 +00:00
Sousi Omine
ef106e6909
Add Japanese localization (#1157)
* Initial Japanese translation

Only a small part was translated

* Unspecified words will be in English

When new words are added, they will be displayed in English even if Japanese support is delayed.

* Expanded translation scope

* Expanded translation scope

* Proceed with translation with a focus on overall settings

* Re-translated the outdated settings screen

* Add items that only exist in the latest en_US and remove items that do not exist in en_US

* A lot of translation work done

* A lot more translation work has been done

* ja_JP.axaml has been translated into Japanese

* Fixed three incomplete parts of the Japanese translation
2025-04-07 09:53:20 +08:00
github-actions[bot]
cbc7079e59 doc: Update translation status and missing keys 2025-04-07 01:45:21 +00:00
UchiTesting
904432a8f1
style(locale): Add a few translations to the French locale (#1158) 2025-04-07 09:45:02 +08:00
github-actions[bot]
7ef4cca1f5 doc: Update translation status and missing keys 2025-04-02 09:20:43 +00:00
Javier J. Martínez M.
2deb79f8ce
localization: update spanish translations (#1142)
add literal translation for 'CopyFullPath' string
2025-04-02 17:20:33 +08:00
leo
8e55ba1b47
enhance: avoid unhandled exceptions in timer
Signed-off-by: leo <longshuang@msn.cn>
2025-03-31 19:06:10 +08:00
leo
55be1ad1ca
Merge branch 'master' into develop 2025-03-31 09:30:56 +08:00
leo
1138ba304d
Merge branch 'release/2025.11' 2025-03-31 09:30:18 +08:00
leo
ae5fa6a793
version: Release 2025.11
Signed-off-by: leo <longshuang@msn.cn>
2025-03-31 09:29:56 +08:00
leo
0045e06d78
project: upgrade AvaloniaUI to 11.2.6
Signed-off-by: leo <longshuang@msn.cn>
2025-03-31 09:29:07 +08:00
qiufengshe
07d99f5fd2
enhance: get email hash code opimization (#1137)
(cherry picked from commit 839b92a284d6b103894f6a8a39e5ce1f99bb12fa)
2025-03-31 09:22:57 +08:00
github-actions[bot]
9ee3a00fba doc: Update translation status and missing keys 2025-03-31 01:21:15 +00:00
AquariusStar
1482a005bb
localization: update and fix translation russian (#1136) 2025-03-31 09:20:54 +08:00
github-actions[bot]
ce7196490a doc: Update translation status and missing keys 2025-03-28 10:02:16 +00:00
leo
276d000bcf
refactor: change Copy File Name to Copy Full Path for selected file or change (#1132)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-28 18:01:53 +08:00
github-actions[bot]
b26c8a64ad doc: Update translation status and missing keys 2025-03-28 04:20:55 +00:00
leo
56ebc182f2
enhance: try to reinstate not onl the working tree's change, but also the index's ones (#1135)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-28 12:20:36 +08:00
Gadfly
1575ae977e
fix: improve font family name handling by collapsing multiple spaces (#1131) 2025-03-27 20:22:46 +08:00
Gadfly
4153eec1a8
chore: Update DEB package configuration with installed size (#1130) 2025-03-26 12:15:15 +08:00
github-actions[bot]
fc37677546 doc: Update translation status and missing keys 2025-03-26 01:30:58 +00:00
leo
4fb853d1fd
localization: add translation Text.Configure.IssueTracker.AddSampleAzure for Chinese (#1128)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-26 09:30:41 +08:00
github-actions[bot]
dccf53e518 doc: Update translation status and missing keys 2025-03-26 01:27:21 +00:00
Iacopo Sbalchiero
ca0fb7ae10
Adding template for Azure DevOps workitems (#1128)
* feat: add Azure DevOps issue tracker integration

* localization: add Azure DevOps sample rule to issue tracker in multiple languages
2025-03-26 09:27:10 +08:00
leo
f37ac904b9
enhance: do not create crash log for unobserved task exceptions (#1121)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-25 10:33:39 +08:00
github-actions[bot]
467089aec5 doc: Update translation status and missing keys 2025-03-25 01:51:33 +00:00
Javier J. Martínez M.
380e6713b5
localization: update spanish translations (#1124) 2025-03-25 09:51:22 +08:00
leo
fc85dd3269
enhance: improve Repository.Open() performance (#1121)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-24 19:37:39 +08:00
leo
0a877c6730
project: upgrade OpenAI and Azure.AI.OpenAI to 2.2.0-beta.4
Signed-off-by: leo <longshuang@msn.cn>
2025-03-24 10:03:27 +08:00
leo
166c925eee
Merge branch 'master' into develop 2025-03-24 09:45:30 +08:00
leo
7581d761cc
Merge branch 'release/v2025.10' 2025-03-24 09:44:50 +08:00
leo
88bb603dc9
version: Release 2025.10
Signed-off-by: leo <longshuang@msn.cn>
2025-03-24 09:44:41 +08:00
leo
d335cac167
enhance: only raise BlockNavigationChangedEvent when UseBlockNavigation enabled
Signed-off-by: leo <longshuang@msn.cn>
2025-03-21 18:00:46 +08:00
leo
9590f96a44
enhance: clear highlight chunk while scrolling out of TextArea.TextView
Signed-off-by: leo <longshuang@msn.cn>
2025-03-21 17:46:11 +08:00
leo
03f49ccff0
refactor: text diff view block navigation
Signed-off-by: leo <longshuang@msn.cn>
2025-03-21 17:35:59 +08:00
leo
39f4cd1732
ci: move all translation status to TRANSLATION.md and do not modify README.md while checking localization
Signed-off-by: leo <longshuang@msn.cn>
2025-03-21 10:54:47 +08:00
leo
cdc0fbb753
doc: update README.md
Signed-off-by: leo <longshuang@msn.cn>
2025-03-21 10:23:52 +08:00
leo
8c1e1a3e6a
fix: text diff view scrolling issue introduced by AvaloniaEdit 11.2.0 (commit 7caa03a09b)
- `SyncScrollOffset` does not update in `side-by-side` mode while scrolling
- Highlighted chunk is not cleared when scroll by drag scrollbar

Signed-off-by: leo <longshuang@msn.cn>
2025-03-21 10:09:43 +08:00
github-actions[bot]
56253e95c3 doc: Update translation status and missing keys 2025-03-21 01:31:07 +00:00
Ilian Delagrange
5467703a6e
localization: add missing french translations (#1113)
Co-authored-by: Ilian Delagrange <ilian@MacBook-Air-de-Ilian.local>
2025-03-21 09:30:57 +08:00
leo
7cd5814410
enhance: better regex for output of Commands.CompareRevisions
Signed-off-by: leo <longshuang@msn.cn>
2025-03-20 21:18:51 +08:00
leo
38d87fa1a1
feature: use git stash show -u --name-status <stash_name> command to query changes in selected stash if git >= 2.32.0
Signed-off-by: leo <longshuang@msn.cn>
2025-03-20 21:12:08 +08:00
leo
65dbfd336d
refactor: it's not necessary to store untracked file list for selected stash
Signed-off-by: leo <longshuang@msn.cn>
2025-03-20 20:53:30 +08:00
leo
891e1b2ec8
ux: show name of stash instead of SHA which is useless to user
Signed-off-by: leo <longshuang@msn.cn>
2025-03-20 19:56:06 +08:00
github-actions[bot]
c349ac10f3 doc: Update translation status and missing keys 2025-03-20 03:11:14 +00:00
leo
145273b4a7
refactor: move Show tags in commit graph to Preferences (#1109)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-20 11:10:48 +08:00
leo
a5bdcab341
code_style: move dynamic context menu creation to view models
Signed-off-by: leo <longshuang@msn.cn>
2025-03-20 09:38:02 +08:00
github-actions[bot]
673b335a2a doc: Update translation status and missing keys 2025-03-20 01:14:21 +00:00
AquariusStar
f7197e08eb
localization: update russian localization (#1111) 2025-03-20 09:14:07 +08:00
github-actions[bot]
f02a7b9858 doc: Update translation status and missing keys 2025-03-18 13:40:50 +00:00
leo
2512d3be7a
feature: allow to hide tags in graph (#1109)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-18 21:40:31 +08:00
leo
ae1e46b586
fix: layout horizontal not working since 2025.9 after switching away from history screen (#1108)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-18 19:47:54 +08:00
leo
822452a20c
enhance: show inner exception message if possible when check update failed
Signed-off-by: leo <longshuang@msn.cn>
2025-03-18 15:55:32 +08:00
leo
760e44877b
fix: wrong split char
Signed-off-by: leo <longshuang@msn.cn>
2025-03-18 12:15:00 +08:00
leo
695db2a319
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 20:57:18 +08:00
leo
8d47bd5cd9
refactor: use --format=<format> instead of --pretty=format:<format>
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 20:46:01 +08:00
leo
808302ce84
code_review: PR #1106
- Use new syntex `[...]` instead of `new char[] {...}` to create char arrays
- Use `string.ReplaceLineEndings('\n').Split('\n')` instead of `string.Split(['\n', '\r'], StringSplitOptions.RemoveEmptyEntries)` because that the `Signer` part may be missing

Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 20:35:31 +08:00
Gadfly
b930066b5a
fix: improve line splitting to handle both LF and CRLF line endings (#1106) 2025-03-17 19:59:28 +08:00
leo
a0cddaea80
feature: support --ff-only option for git merge command
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 19:53:47 +08:00
github-actions[bot]
2b95ea2ab1 doc: Update translation status and missing keys 2025-03-17 09:15:30 +00:00
Leonardo
c9fe373dda
add missing key and fix untranslated one (#1104) 2025-03-17 17:15:17 +08:00
leo
398b14695c
enhance: the git dir of worktree's owner repository may not named .git
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 17:10:59 +08:00
github-actions[bot]
5845ef3eb6 doc: Update translation status and missing keys 2025-03-17 09:06:42 +00:00
leo
3e8bba0d0b
ux: re-design About page
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 17:06:26 +08:00
leo
7031693489
refactor: pass dirs to watcher directly
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 16:30:16 +08:00
leo
b4ab4afd3a
code_review: PR #1103
Since we only use `$GIT_COMMON_DIR` in filesystem watcher, it is unnecessary to store this value in `Repository`, and we can query the `$GIT_COMMON_DIR` only when it looks like a worktree

Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 16:19:59 +08:00
Gadfly
cea8a90680
refactor: use $GIT_COMMON_DIR instead of cut $GIT_DIR/worktrees (#1103) 2025-03-17 15:56:13 +08:00
github-actions[bot]
265aaa1d67 doc: Update translation status and missing keys 2025-03-17 07:30:48 +00:00
leo
cdd1926e2f
refactor: rewrite git apply implementation
- Do not translate commandline options for `git`
- Re-design combox layout for `git apply` popup

Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 15:30:32 +08:00
leo
ddfc868df3
ux: re-design merge option style
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 15:08:49 +08:00
leo
10fd0f9d15
doc: fix typo
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 12:02:32 +08:00
leo
99a45335fe
doc: group third-party components by types
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 12:01:29 +08:00
leo
8f8385072c
doc: add third-party components
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 11:56:38 +08:00
Gadfly
a480ba0139
docs: Add third-party components and licenses section
(cherry picked from commit 95c697248755f7b6de4d2d0bfdaa9de1e572c9f6)
2025-03-17 11:47:51 +08:00
Gadfly
4b41029768
fix: use better JSP grammar file and add licensing information (#1102) 2025-03-17 11:31:50 +08:00
leo
6273c01d71
fix: git rev-list raises errors after selected commit in Histories page (#1101)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 10:55:54 +08:00
Gadfly
450dadf76c
feat: Add JSP grammar support and improve TextMateHelper file type handling (#1100)
- Extend grammar support by allowing multiple file extensions per grammar and adding JSP file type handling.
- Add a new JSON grammar file for JavaServer Pages (JSP) syntax highlighting.
2025-03-17 10:12:44 +08:00
leo
7caa03a09b
project: upgrade AvaloniaEdit to 11.2.0
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 09:57:52 +08:00
leo
d9cf849b9f
Merge branch 'master' into develop 2025-03-17 09:38:30 +08:00
leo
6fd6bbb6b5
Merge branch 'release/v2025.09' 2025-03-17 09:37:49 +08:00
leo
34f8618989
version: Release 2025.09
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 09:37:40 +08:00
leo
84979b20b3
ux: force using VertialAlignment="Center" for sign info of commit (#1098)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-17 09:32:31 +08:00
Gadfly
66517fd4bf
enhance: add tooltips to various UI elements for better accessibility (#1097)
* enhance: add tooltips to various UI elements for better accessibility

* refactor: simplify user string conversion
2025-03-16 11:23:42 +08:00
github-actions[bot]
a46e52582f doc: Update translation status and missing keys 2025-03-14 08:57:15 +00:00
Asurada
db504241ea
feat: add translation for "1 hour ago" in multiple languages (#1096) 2025-03-14 16:57:03 +08:00
leo
c3e1fb93b6
refactor: fix maxOS PATH env
Signed-off-by: leo <longshuang@msn.cn>
2025-03-14 10:54:09 +08:00
leo
c8bee2f6ba
code_review: PR #1093
Merge deleting branch and tag on remote into `SourceGit.Commands.Push(repo, remote, refname, isDelete)`

Signed-off-by: leo <longshuang@msn.cn>
2025-03-14 09:36:34 +08:00
Michael Pakhantsov
9645b65db6
Explicitly provided fully qualified reference for the git branch, becase can be exists a tag and a branch with identical names (#1093)
Fix push command for branch deletion

Updated the `push` command to use `--delete refs/heads/{name}` instead of `--delete {name}` for clearer branch reference when deleting a remote branch.

Co-authored-by: Michael Pakhantsov <michae.pakhantsov@gmail.com>
2025-03-14 09:26:59 +08:00
leo
67f4330dd4
code_style: arrange methods in App.axaml.cs
Signed-off-by: leo <longshuang@msn.cn>
2025-03-13 15:23:43 +08:00
leo
9560496c7b
code_review: PR #1092
- Remove `SourceGit.ViewModels.Preference.FixFontFamilyName` (it is not necessary any more)
- Use `string.Join` instead of `StringBuilder` to make the logic more clear

Signed-off-by: leo <longshuang@msn.cn>
2025-03-13 15:17:20 +08:00
Gadfly
b9b684a83d
fix: improve font string processing in SetFonts method (#1092) 2025-03-13 15:05:30 +08:00
github-actions[bot]
519bdf1ddc doc: Update translation status and missing keys 2025-03-13 02:22:09 +00:00
leo
0e261cffd2
refactor: rewrite the way to deal with uncommitted local changes when checkout/pull/create branch (#1085)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-13 10:21:54 +08:00
leo
e430e847ff
enhance: auto convert spaces with dashes while renaming a branch (#1088)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-13 09:50:42 +08:00
Gadfly
7331167be2
fix: schedule DWM frame extension to next render frame on Windows 10 (#1087)
The DwmExtendFrameIntoClientArea call needs to be posted to the next render frame to ensure the window handle is fully initialized and avoid potential race conditions.
2025-03-13 09:38:08 +08:00
Morgan Courbet
f07832c385
docs: fix typo in README.md
(cherry picked from commit 59fd2aaab1)
2025-03-13 09:24:43 +08:00
leo
e4f5c34e0c
code_style: remove whitespaces
Signed-off-by: leo <longshuang@msn.cn>
2025-03-12 17:58:57 +08:00
leo
eaa322dfab
enhance: re-design commit search result display (#1083)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-12 17:57:31 +08:00
leo
77d8afe056
refactor: reduce the times to call RefreshLayout
Signed-off-by: leo <longshuang@msn.cn>
2025-03-12 15:10:43 +08:00
leo
0476a825ef
code_style: move some code from Histories.axaml to separate files
Signed-off-by: leo <longshuang@msn.cn>
2025-03-12 14:58:59 +08:00
leo
bb2284c4c9
refactor: re-write commit searching (part 3)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-12 11:53:24 +08:00
leo
ee7ccc0391
refactor: re-write commit searching (part 2)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-12 11:05:19 +08:00
leo
231f3bf668
enhance: use --ancestry-path=<commit_oid> to reduce unnecessary outpus while querying children commits
Signed-off-by: leo <longshuang@msn.cn>
2025-03-12 10:11:00 +08:00
leo
f5d6e1264d
refactor: use List<T> instead of AvaloniaList<T> since it is not used for bindings
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 23:01:34 +08:00
leo
64a41dce39
refactor: rewrite searching commit by file path
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 20:55:39 +08:00
leo
fa4d9d24e9
enhance: hide suggestion popups when window is deactived (#963)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 20:22:32 +08:00
leo
91c5c96afc
fix: accessing dummy in multi-threads throws exception
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 20:05:34 +08:00
leo
2fc03025ee
fix: file suggestion popup did not show while searching commit by file path
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 19:52:50 +08:00
leo
471452646b
refactor: use System.Threading.CancellationToken instead of SourceGit.Commands.Command.CancelToken to cancel fetching information of selected commit
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 16:53:51 +08:00
leo
f23e3478e6
fix: do not save preference in design mode
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 11:41:37 +08:00
leo
54d49a9eda
fix: app crashes when close a repository on read-only drive (#1080)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 09:36:13 +08:00
leo
5f2bd8ad94
ux: layout for Preferences window
Signed-off-by: leo <longshuang@msn.cn>
2025-03-11 09:27:32 +08:00
leo
f54c8877d7
Merge pull request #1079 from AquariusStar/develop_translation_russian
update russian localization
2025-03-11 09:21:20 +08:00
Михаил Усоцкий
f496d15f70 update russian localization 2025-03-10 20:15:29 +03:00
leo
cf8cff6b64
code_style: add ViewModels.Repository.GetCustomAction(scope)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 21:30:04 +08:00
leo
5c279b4b56
feature: add global configuration for custom action (#1077)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 21:19:38 +08:00
leo
0f9087fac6
code_review: PR #1078
- Remove `ForceEnglishLocale` because we want all `git` outputs in English
- Remove locale settings for `ExecuteCustomAction`

Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 20:08:42 +08:00
Gadfly
860f52153b
fix: Force English locale in branch query command. (#1078) 2025-03-10 20:05:37 +08:00
leo
b4fbc2372b
enhance: show commit info tip when hover SHA in conflict view
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 20:02:09 +08:00
leo
2b2f070c4a
enhance: use --no-optional-locks parameter for git status command
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 18:29:11 +08:00
leo
e65cb50495
fix: use \ as path delim on Windows when executing custom actions (#1077)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 17:48:02 +08:00
Gadfly
cdae9168ed
ci(windows): maintain SourceGit folder structure (#1076) 2025-03-10 15:44:39 +08:00
leo
2e51e8939b
Merge branch 'master' into develop 2025-03-10 12:34:34 +08:00
leo
e3cc987682
Merge branch 'develop' 2025-03-10 12:33:20 +08:00
Gadfly
c1c0e7b2a0
enhance: Save Preferences after switched Workspace and closed Preferences (#1073) 2025-03-10 12:04:19 +08:00
leo
df6cbcaa28
fix: app crashed after enable Show children in the commit details (#1072)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 11:33:38 +08:00
leo
855466686d
ux: show conflict sources when it comes from a stash or patch (#1067)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 10:22:49 +08:00
leo
bfc3f37e47
Merge branch 'master' into develop 2025-03-10 09:37:40 +08:00
leo
18d3b9560b
Merge branch 'release/v2025.08' 2025-03-10 09:36:44 +08:00
leo
82fdd2e9d4
version: Release 2025.08
Signed-off-by: leo <longshuang@msn.cn>
2025-03-10 09:36:36 +08:00
Gadfly
6ba26770c4
ci: enhance Linux and Windows package workflow (#1071)
* ci: fix Linux packaging workflow with specific Ubuntu 20.04 image

* ci: use Compress-Archive in Windows try to prevent Defender false positives
2025-03-10 09:28:13 +08:00
github-actions[bot]
978801c9ff doc: Update translation status and missing keys 2025-03-10 01:27:39 +00:00
AquariusStar
2fb1d7e14a
update and fix translation russian (#1070) 2025-03-10 09:27:25 +08:00
Gustav Andersson
89f655c84d
fix: Show detached HEAD (#1060) 2025-03-07 16:16:15 +08:00
leo
0860245674
code_style: simple window do not using DataContext
Signed-off-by: leo <longshuang@msn.cn>
2025-03-07 15:44:50 +08:00
leo
43fed8e04d
refactor: re-write About window
Signed-off-by: leo <longshuang@msn.cn>
2025-03-07 15:15:47 +08:00
leo
83f23583be
enhance: supports to navigate to target commit while resolving conflicts
Signed-off-by: leo <longshuang@msn.cn>
2025-03-07 12:22:47 +08:00
leo
ca6d41ee60
enhance: try to get stopped at revision info from .git/rebase-merge/head
Signed-off-by: leo <longshuang@msn.cn>
2025-03-07 11:39:15 +08:00
github-actions[bot]
773e27fda7 doc: Update translation status and missing keys 2025-03-07 01:32:14 +00:00
Javier J. Martínez M.
14877d4d63
localization: update spanish translations (#1061)
add missing spanish translations
update previous references of `patch` as `parche`
2025-03-07 09:32:05 +08:00
leo
92fa25ae8d
ux: disable scrollbar in NumericUpDown control (#1023)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-06 15:14:05 +08:00
leo
aa0d4b4296
ux: adjust column width of commit hash and time after font size changed (#994)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-06 11:50:22 +08:00
leo
78c0d8d334
fix: both --tags and --no-tags are used in git pull command
Signed-off-by: leo <longshuang@msn.cn>
2025-03-06 10:37:50 +08:00
leo
81bbe11345
code_style: rename some variables in ParseLinksInMessage
Signed-off-by: leo <longshuang@msn.cn>
2025-03-05 17:06:45 +08:00
Gadfly
991ebe4082
ci: set ubuntu:20.04 (#1056) 2025-03-05 09:55:55 +08:00
leo
fb8d4a2542
code_review: PR #1055
- since the author and time are already shown in the blame view, use the full message as tooltip is better.
- cache the commit message in `ViewModels.Blame` since the `Tooltip` of control may change.
- querying commit message synchronously (it's very fast) to avoid similar issues in commit details panel.

Signed-off-by: leo <longshuang@msn.cn>
2025-03-05 09:54:23 +08:00
GadflyFang
269903503f
feat: Add commit Tooltip in Blame (#1055)
Fixes #993
2025-03-05 09:36:32 +08:00
leo
5e898a809e
enhance: check commit hash after intersect testing
Signed-off-by: leo <longshuang@msn.cn>
2025-03-05 09:30:55 +08:00
GadflyFang
71d0b69eee
fix: prevent kill apt process by accident (#1054) 2025-03-04 19:51:36 +08:00
leo
792e61b24f
ux: re-design the layout for Interactive Rebase window that tries to fix issue #1037
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 18:23:13 +08:00
leo
e884f27f67
code_style: re-order CommitDetail properties
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 18:02:29 +08:00
leo
e28f8611ef
ux: re-design the layout for Interactive Rebase window that tries to fix issue #1037
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 17:39:21 +08:00
github-actions[bot]
5af856b9da doc: Update translation status and missing keys 2025-03-04 09:26:48 +00:00
leo
2137ad9ec9
enhance: allow to configure editor tab width in preferences window (#1048)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 17:26:27 +08:00
leo
11af5d9b29
code_style: use ?: operator instead of if ... else statement
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 16:42:32 +08:00
GadflyFang
68e96f428e
fix: validate result not update #1052 (#1053) 2025-03-04 16:34:51 +08:00
GadflyFang
25e6e261a6
refactor: Improve key modifier checks and AltGr detection (#1051) 2025-03-04 16:33:43 +08:00
leo
96538b9a62
fix: there's an extra line-ending while copy multiple lines from text diff view (#1049)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 16:26:14 +08:00
leo
b75676a7f8
refactor: commit message
- move issue tracker and commit hash links parsing to view models
- parsing links async
- make sure matched hash is a valid commit oid
- disable `CHILDREN` row in submodule info panel

Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 16:04:19 +08:00
leo
5301a368e0
ux: re-design the layout for Interactive Rebase window that tries to fix issue #1037
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 09:46:02 +08:00
leo
d4bcc60113
enhance: disable CONTINUE button while it is running (#1046)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-04 09:29:07 +08:00
leo
35ee4a47db
fix: the last selected line is missing while trying to copy multiple lines in text diff view (#1044)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-03 15:39:59 +08:00
leo
598bba5210
code_review: PR #1043
`FileModeChange` should not be changed out of UIThread

Signed-off-by: leo <longshuang@msn.cn>
2025-03-03 14:25:49 +08:00
GadflyFang
72c7f24e2f
fix: set FileModeChange after RefreshAll (#1043) 2025-03-03 14:17:03 +08:00
GadflyFang
9dffd55c2b
build: Add pre-install and pre-removal scripts for DEBIAN package (#1041)
kill sourcegit before install
2025-03-03 10:39:57 +08:00
GadflyFang
7f8372f6b5
enhance: Handle file mode changes for new/deleted file (#1040) 2025-03-03 10:38:58 +08:00
leo
4c63c4c90d
Merge branch 'master' into develop 2025-03-03 09:28:02 +08:00
leo
4418214d38
Merge branch 'release/v2025.07' 2025-03-03 09:27:04 +08:00
leo
8c48b9623e
version: Release 2025.07
Signed-off-by: leo <longshuang@msn.cn>
2025-03-03 09:26:49 +08:00
leo
25fa223c6b
enhance: better regex for remote URL (#1039)
Signed-off-by: leo <longshuang@msn.cn>
2025-03-02 10:39:04 +08:00
heartacker
8423f53ace
chore: 升级Avalonia和CommunityToolkit.Mvvm包 (#1038)
- Upgrade Avalonia packages to version 11.2.5 and CommunityToolkit.Mvvm to version 8.4.0.
2025-03-01 19:20:37 +08:00
leo
8dd0274bdd
enhance: only write MERGE_MSG when commit message is not null
Signed-off-by: leo <longshuang@msn.cn>
2025-03-01 09:21:52 +08:00
leo
5199fb2b74
enhance: do NOT remember the last selected handling method of uncommitted local changes (#977)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-28 22:14:21 +08:00
leo
c90b7afac1
feature: makes the base on branch name selectable (#1036)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-28 19:18:10 +08:00
leo
88c7d5bbc9
fix: app crashes when Return key is pressed while current action is already running (#1035)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-28 19:15:02 +08:00
leo
9cf1cba9b7
feature: apply commit message while continue merge/revert (#1027)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-28 19:08:27 +08:00
leo
639bff9ad8
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-02-28 17:27:17 +08:00
leo
3e70ff94b0
fix: should not use ... to get revision range for rebasing (#1033)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-28 17:06:07 +08:00
Andre Greeff
f930967698
feat: remove IsMerged check from "Interactive Rebase" context menu conditional (#1033) 2025-02-28 17:05:49 +08:00
github-actions[bot]
109eee5668 doc: Update translation status and missing keys 2025-02-27 13:14:38 +00:00
GadflyFang
57cb9d0909
fix: Dynamic load copyright (#1030) 2025-02-27 21:14:24 +08:00
github-actions[bot]
caca1dcaaf doc: Update translation status and missing keys 2025-02-27 13:12:27 +00:00
Leonardo
337ee1a55d
localization: update italian translation (#1029) 2025-02-27 21:12:14 +08:00
leo
fc3043b93c
fix: double-clicking button trigger binded command twice (#1032)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-27 21:10:41 +08:00
leo
61d7f36be4
enhance: reset diff view context for empty commit
Signed-off-by: leo <longshuang@msn.cn>
2025-02-27 10:59:00 +08:00
leo
bdf439a742
enhance: do not show error message if it is empty
Signed-off-by: leo <longshuang@msn.cn>
2025-02-26 16:33:11 +08:00
leo
7bfb95f7ce
fix: ptyxis does not start with given working directory (#1005)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-26 16:07:18 +08:00
github-actions[bot]
c849c13fcb doc: Update translation status and missing keys 2025-02-26 07:45:04 +00:00
Javier J. Martínez M.
8f7db4e874
localization: add missing spanish translations (#1024)
* localization: add missing spanish translations

* localization: add missing spanish translations
2025-02-26 15:44:51 +08:00
leo
a7e254cac6
fix: multiple bindings for IsVisible property of Button
Signed-off-by: leo <longshuang@msn.cn>
2025-02-26 09:50:54 +08:00
leo
79306ad73b
fix: ptyxis does not start with given working directory (#1005)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-25 19:50:09 +08:00
leo
a0786bf9cc
fix: pulling with empty repository (no local branch) crashes this app (#1020)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-25 14:37:03 +08:00
leo
4d740f4731
feature: auto-select the first change when selected stash changed (#1019)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-25 11:09:12 +08:00
leo
c6747f72f9
feature: auto-select first change in commit details panel and revision/branch compare panel (#1019)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-25 10:53:42 +08:00
github-actions[bot]
1f35e83799 doc: Update translation status and missing keys 2025-02-24 13:25:13 +00:00
leo
1d037c7c57
feature: add context menu Save As Patch... for selected stash (#1018)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-24 21:24:53 +08:00
leo
4868ea1a0b
Merge branch 'master' into develop 2025-02-24 09:50:24 +08:00
leo
fb6b57bdf5
Merge branch 'release/v2025.06' 2025-02-24 09:49:41 +08:00
leo
0b7805b2ee
version: Release 2025.06
Signed-off-by: leo <longshuang@msn.cn>
2025-02-24 09:49:30 +08:00
github-actions[bot]
89e09d842d doc: Update translation status and missing keys 2025-02-24 01:45:49 +00:00
Javier J. Martínez M.
d4341c1195
localization: add missing spanish translations (#1017) 2025-02-24 09:45:39 +08:00
github-actions[bot]
74e5bcb704 doc: Update translation status and missing keys 2025-02-24 01:37:52 +00:00
leo
124bdc97f9
localization: add missing keys for zh_CN and zh_TW
Signed-off-by: leo <longshuang@msn.cn>
2025-02-24 09:37:34 +08:00
github-actions[bot]
52a53cc697 doc: Update translation status and missing keys 2025-02-24 01:32:32 +00:00
Göran W
fa4caa2186
enhance: add first/last buttons for block-nav, no wrapping (#1015) (#1016)
Added 2 new buttons (only visible in block-nav mode), with new icons and new (en_US) strings (First/Last Difference).
Implemented these new buttons, and disabled the automatic wrap-around for the prev/next buttons in block-nav mode.
2025-02-24 09:32:19 +08:00
Ikko Eltociear Ashimine
9ab602788a
docs: update README.md (#1014)
comaptible -> compatible
2025-02-24 09:28:00 +08:00
github-actions[bot]
b2ab62825e doc: Update translation status and missing keys 2025-02-21 02:48:21 +00:00
saxc
841276852a
localization: add german translations (#1011)
(cherry picked from commit fcc720480c85fe01120e555c22b6aec286ee717b)
2025-02-21 10:47:48 +08:00
leo
2b4fc64c73
fix: resolve conflict with deleted files does not work (#1009)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-21 10:26:14 +08:00
leo
9da2c787db
enhance: supports to configure fetch.prune for selected repository (#995)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-21 09:44:51 +08:00
leo
b5feabfd37
enhance: auto-set commit message while rebasing is inprogress (#1003)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-20 15:42:11 +08:00
leo
08da3ac5d8
enhance: prefer to use Default Remote in repository settings while fetching remote changes (#1008)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-20 11:12:29 +08:00
leo
731f1055bc
feat!: add ptyxis support (#1005)
BREAKING CHANGE: Index of `Custom` shell/terminal

Signed-off-by: leo <longshuang@msn.cn>
2025-02-20 11:04:57 +08:00
leo
507e502874
fix: Custom Action height is not large enough to display all contents (#1004)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-20 10:19:00 +08:00
github-actions[bot]
b57c0158c1 doc: Update translation status and missing keys 2025-02-20 02:14:51 +00:00
leo
53f591bdad
ux: add a warning icon when the tracking upstream of a local branch is gone (#1006)
Co-authored-by: Davide Tentori <dtentori@softeam.it>
2025-02-20 10:14:25 +08:00
leo
0e1dfba7ef
code_review: PR #1007
Signed-off-by: leo <longshuang@msn.cn>
2025-02-20 09:34:03 +08:00
Oleg Kosmakov
cbc2e46beb
fix: Update unstaged filed counter when unstaged files change (#1007)
* Add missing OnPropertyChanged in Cleanup

* Force unstaged count to refresh
2025-02-20 09:31:07 +08:00
leo
ce16ac63eb
enhance: submodule bookmark inherts from parent repo (#1001)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-19 19:22:36 +08:00
github-actions[bot]
68946d2140 doc: Update translation status and missing keys 2025-02-19 10:01:37 +00:00
leo
c3eca0d7fd
refactor: OpenAI integration (#996)
- Add `OpenAIResponse` to trim the `<think>...</think>` block
- Add an `Enable Streaming` option to fix the issue that some services do not support streaming output

Signed-off-by: leo <longshuang@msn.cn>
2025-02-19 18:01:16 +08:00
leo
69d107430a
project: upgrade OpenAI and Azure.AI.OpenAI to 2.2.0-beta.2
Signed-off-by: leo <longshuang@msn.cn>
2025-02-19 10:44:51 +08:00
leo
59638eb731
enhance: tag push behavior while creating and deleting (#999)
- Remember the state of `Push to all remotes after created` checkbox while creating tag
- Remember the state of `Delete from remote repositories` checkbox while deleting tag
- Change default state of `Delete from remote repositories` to `false`

Signed-off-by: leo <longshuang@msn.cn>
2025-02-19 10:35:34 +08:00
leo
5d2cd8b2fa
ux: new style for current branch (#998)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-18 18:19:19 +08:00
leo
3d4a9b86b4
ux: use bold font weight for current branch name (#997)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-18 16:54:00 +08:00
leo
af4645a4ad
project: upgrade LiveChartsCore.SkiaSharpView.Avalonia to 2.0.0-rc5.4
Signed-off-by: leo <longshuang@msn.cn>
2025-02-18 16:27:19 +08:00
leo
cf42381802
Merge branch 'master' into develop 2025-02-18 11:00:25 +08:00
leo
ed37b42a4a
Merge branch 'release/v2025.05' 2025-02-18 10:58:58 +08:00
leo
d401e898a2
version: Release 2025.05
Signed-off-by: leo <longshuang@msn.cn>
2025-02-18 10:58:30 +08:00
leo
e28abf8119
enhance: supports remove single histories filter (#987)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-18 10:04:56 +08:00
leo
14f47a9007
ux: style for current branch in branch tree (#991)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-18 09:50:01 +08:00
Arun
7ae5100fcf
chore: Convey the usage of monospace font only in text editor (#990)
Signed-off-by: Arun <visionofarun@gmail.com>
(cherry picked from commit 7ec7de7b4a933a599cfffc79382a6edd13582c85)
2025-02-18 09:32:15 +08:00
Chiahong
36178d5ecf
localization: update zh_TW.axaml (#989) 2025-02-18 09:26:44 +08:00
leo
bc66e24407
project: upgrade AvaloniaUI to 11.2.4
Signed-off-by: leo <longshuang@msn.cn>
2025-02-15 17:43:47 +08:00
github-actions[bot]
e39351b4a7 doc: Update translation status and missing keys 2025-02-14 02:43:26 +00:00
leo
9104060d79
feature: support add custom actions for selected branch (#980)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-14 10:43:08 +08:00
leo
9b07034846
code_review: PR #978
* Remove unnecessary parentheses since the name of relative path uses secondary foreground color already

Signed-off-by: leo <longshuang@msn.cn>
2025-02-13 10:46:28 +08:00
Dmitrij D. Czarkoff
588879eb7f
feat: change worktree presentation (#978)
Present the worktree name first, then relative path to the main repo.

This is more aligned with Git's own UI,  and works better with UI size constrains.
2025-02-13 10:41:08 +08:00
leo
c6aedf1193
ux: right margin of main tab bar on macOS
Signed-off-by: leo <longshuang@msn.cn>
2025-02-12 21:29:17 +08:00
leo
3302bdeb26
localization: remove duplicated keys in de_DE
Signed-off-by: leo <longshuang@msn.cn>
2025-02-12 21:25:57 +08:00
github-actions[bot]
21e4dcffd0 doc: Update translation status and missing keys 2025-02-12 02:59:19 +00:00
Christopher Göttfert
9757678dcf
localization: added missing german translations (#973)
Co-authored-by: Christopher Göttfert <Christopher.Goettfert@.uni-wuerzburg.de>
2025-02-12 10:59:00 +08:00
github-actions[bot]
19e72f8650 doc: Update translation status and missing keys 2025-02-12 02:51:20 +00:00
AquariusStar
eea55ec56f
localization: update russian localization (#971) 2025-02-12 10:51:06 +08:00
leo
21cfd17cdb
fix: do NOT quit when try to input @ via Alt Gr+Q with German ISO keyboard layout (#970)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-11 18:57:54 +08:00
leo
e9d16a5102
project: upgrade TextMateSharp to 1.0.66 (#969)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-11 16:58:32 +08:00
github-actions[bot]
1bfe1a2755 doc: Update translation status and missing keys 2025-02-11 07:15:47 +00:00
leo
011a415949
enhance: add a button to clear all notifications (#950)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-11 15:15:27 +08:00
leo
37e5926388
code_style: keep translation ordered
Signed-off-by: leo <longshuang@msn.cn>
2025-02-11 14:41:56 +08:00
leo
06df27780f
localization: update Text.Configure.CustomAction.WaitForExit for en_US
Signed-off-by: leo <longshuang@msn.cn>
2025-02-11 14:36:46 +08:00
github-actions[bot]
37fed93589 doc: Update translation status and missing keys 2025-02-11 06:34:33 +00:00
leo
af20ab2448
feature: add Wait for action done option to control whether or not to wait for the custom action execution to complete (#951)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-11 14:34:14 +08:00
leo
10fba08e43
code_review: PR #949
Signed-off-by: leo <longshuang@msn.cn>
2025-02-11 11:07:33 +08:00
Doodeletion
821063e3ec
Swap selection start and end index if selection is created from bottom to top (#967) 2025-02-11 10:57:20 +08:00
leo
aebfffee00
fix: GUI stops refreshing after manually refresh while merge tool is open (#949)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-10 20:51:36 +08:00
leo
0c8179b934
enhance: add a opened tabs selector popup (#958)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-10 20:06:44 +08:00
leo
e757e63bf7
refactor: launcher tab bar scroller visibility
Signed-off-by: leo <longshuang@msn.cn>
2025-02-10 16:42:42 +08:00
leo
59e4f0d388
refactor: update submodules when branch status changed
Signed-off-by: leo <longshuang@msn.cn>
2025-02-10 14:28:20 +08:00
GadflyFang
bead749c57
enhance: async refresh operations in Watcher (#961) 2025-02-10 14:05:27 +08:00
leo
c61ecb0bb0
Merge branch 'master' into develop 2025-02-10 10:05:55 +08:00
leo
7fc7c8fdb6
Merge branch 'release/v2025.04' 2025-02-10 10:05:23 +08:00
leo
3b76a30948
version: Release 2025.04
Signed-off-by: leo <longshuang@msn.cn>
2025-02-10 10:05:10 +08:00
GadflyFang
ef2e0a8a56
fix: Ignore the Chain-of-Thought in AI response (#952)
- Improve chat response processing to handle thinking patterns using regular expressions.
- Migrate server value by removing trailing '/chat/completions' path.
2025-02-08 17:30:27 +08:00
leo
8cc056d2af
enhance: supports searching/filtering unstaged changes (#960)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-08 17:16:56 +08:00
leo
35abeae758
project: upgrade Azure.AI.OpenAI to 2.2.0-beta.1
Signed-off-by: leo <longshuang@msn.cn>
2025-02-08 16:20:45 +08:00
leo
aa0d066944
enhance: move Create New Page button out of tab list if scroll arrow is visible (#958)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-08 14:55:55 +08:00
leo
2495911bd8
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-02-08 12:08:06 +08:00
leo
1f0dd15192
fix: only o1-mini does not supports system prompt
Signed-off-by: leo <longshuang@msn.cn>
2025-02-08 11:57:10 +08:00
github-actions[bot]
6a80e54b47 doc: Update translation status and missing keys 2025-02-08 02:17:16 +00:00
leo
a915708db3
refactor: rewrite OpenAI integration
- use `OpenAI` and `Azure.AI.OpenAI`
- use `developer` role instead of `system` for OpenAI's `o1` series models
- use streaming response
- re-design `AIAssistant`

Signed-off-by: leo <longshuang@msn.cn>
2025-02-08 10:03:11 +08:00
github-actions[bot]
cf90e51887 doc: Update translation status and missing keys 2025-02-07 10:08:27 +00:00
leo
f8bc022813
ux: clarify Delete operation for tree node in welcome page (#957)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-07 18:08:07 +08:00
leo
12597fd3e3
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2025-02-07 12:06:29 +08:00
leo
9a36e652e6
fix: add a new interface CanStartDirectly and move this check to StartPopup (#956)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-07 11:56:30 +08:00
leo
8ed7a99923
fix: COMMIT & PUSH should hide when there's no remotes available (#956)
Signed-off-by: leo <longshuang@msn.cn>
2025-02-07 11:45:18 +08:00
leo
8edd955370
code_review: PR #956
* Just use `Check` instead of a new one `AutoCheck`

Signed-off-by: leo <longshuang@msn.cn>
2025-02-07 11:36:30 +08:00
GadflyFang
2105fd450d
fix: when upstream is null show CommitAndPush and stop auto push (#955) (#956) 2025-02-07 11:30:14 +08:00
github-actions[bot]
d1f3469250 doc: Update translation status and missing keys 2025-02-06 08:34:27 +00:00
leo
7089f29b85
refactor: re-implement git stash apply
* supports `--index` option
* add an option to drop selected stash after applying
* remove `Pop` context menu for stash

Signed-off-by: leo <longshuang@msn.cn>
2025-02-06 16:33:55 +08:00
leo
dbb1df5f8b
fix: single _ will be traited as a space by image shields
Signed-off-by: leo <longshuang@msn.cn>
2025-02-06 15:34:12 +08:00
leo
e9297096df
enhance: remember last view mode in file histories view
Signed-off-by: leo <longshuang@msn.cn>
2025-02-06 13:30:56 +08:00
leo
dacbd2a791
enhance: auto-select the first revision in file histories view
Signed-off-by: leo <longshuang@msn.cn>
2025-02-06 13:13:45 +08:00
leo
38a8490d16
code_review: PR #946
Signed-off-by: leo <longshuang@msn.cn>
2025-02-06 13:07:58 +08:00
GadflyFang
9aba737d9e
feat: support compare both revision in FileHistories (#786) (#946) 2025-02-06 11:33:55 +08:00
GadflyFang
65a9406c9a
fix: adjust SHA regex pattern to min 6 chars (#944)
- Adjust the SHA regex pattern to match commit hashes with a minimum length of 6 characters instead of 10.
2025-02-06 10:55:07 +08:00
github-actions[bot]
2ee5b4707a doc: Update translation status and missing keys 2025-02-06 02:32:00 +00:00
GadflyFang
3ca4dc488c
feat: Add stash auto-restore functionality (#947) (#948) 2025-02-06 10:31:46 +08:00
GadflyFang
942f349275
enhance: enhance crash logging with detailed system info (#943)
- Enhance crash logging by adding detailed system and process information, including thread name, user, app start time, exception time, and memory usage.
2025-02-06 10:22:34 +08:00
GadflyFang
84533599f1
fix: support encoded url in remote (#938) 2025-02-06 10:22:01 +08:00
github-actions[bot]
018a32b95b doc: Update translation status and missing keys 2025-02-06 02:20:06 +00:00
leo
e784696058
enhance: add a checkbox to toggle Initialize & update submodules after clone
Signed-off-by: leo <longshuang@msn.cn>
2025-02-06 10:19:43 +08:00
GadflyFang
3af6012561
refactor: Update submodules individually to avoid failures (#925) (#936)
* refactor: Update submodules individually to avoid failures (#925)

- Remove `--recurse-submodules` flag from the clone command to simplify the cloning process.
- Refactor submodule update logic to handle updating all submodules in a loop and improve progress description handling.

* fix: Parse submodule list even if submodule status fails (#935)
2025-02-06 10:08:12 +08:00
GadflyFang
a4157e11e6
fix: Improve in-progress rebase handling (#933)
* fix: Improve in-progress rebase handling

* fix: Close merge popup even if there are conflicts (#941)
2025-02-06 10:00:35 +08:00
github-actions[bot]
c2950ad209 doc: Update translation status and missing keys 2025-02-06 02:00:25 +00:00
Leonardo
9a9f63a787
Add missing keys and general reviewing of the Italian translation (#932)
* update italian translation

* ordered italian translation and removed from md file

* revert edits in translations.md
2025-02-06 10:00:12 +08:00
GadflyFang
4f41f44a9f
fix: add --include-untracked to stash push for specific changes (#931) 2025-02-06 09:51:03 +08:00
GadflyFang
92065dee12
fix: Ensure each ImageView instance calculates its own aspect ratio (#929)
* fix: Ensure each ImageView instance calculates its own aspect ratio

- Modified ArrangeOverride methods in ImageView class to independently calculate and apply the aspect ratio based on the instance's image.

Signed-off-by: Gadfly <gadfly@gadfly.vip>

* fix: Make IgnoredWhitespace toggle button visible based on IsTextDiff

---------

Signed-off-by: Gadfly <gadfly@gadfly.vip>
2025-02-06 09:49:45 +08:00
leo
dd254ebf4f
ux: new attached property MenuItemExtension.Command for MenuItem
Signed-off-by: leo <longshuang@msn.cn>
2025-01-26 14:55:44 +08:00
Erica Buckmann
6a1026c992
feature: Add Ghostty to macOS terminals. (#928) 2025-01-26 10:42:13 +08:00
leo
fa07bb5b5a
refactor: move per-repository config Enable --prune on fetch to global git config fetch.prune (#908)
Signed-off-by: leo <longshuang@msn.cn>
2025-01-25 12:06:48 +08:00
leo
aad42a8297
feature: select the cursor line by triple-click (#927)
Signed-off-by: leo <longshuang@msn.cn>
2025-01-25 11:14:15 +08:00
leo
733ffe1af2
localization: update Text.WorkingCopy.Amend since we already add --amend as tooltip
Signed-off-by: leo <longshuang@msn.cn>
2025-01-24 17:15:05 +08:00
github-actions[bot]
4f6a878177 doc: Update translation status and missing keys 2025-01-24 06:46:07 +00:00
leo
49ee9c8e33
ux: move --signoff toggle from repository configuration window to commit options bar
Signed-off-by: leo <longshuang@msn.cn>
2025-01-24 14:45:49 +08:00
github-actions[bot]
0192e941f0 doc: Update translation status and missing keys 2025-01-24 04:11:14 +00:00
leo
37c4545875
feature: branch name allows spaces and auto replace spaces with dashes (#917) 2025-01-24 12:10:56 +08:00
leo
ab080b53b1
enhance: exclude indicators or empty blocks in diff text view while copying text (#924) 2025-01-24 11:41:11 +08:00
github-actions[bot]
cc111baf01 doc: Update translation status and missing keys 2025-01-23 08:11:28 +00:00
leo
e242119a03
fix: searching by Author & Committer does not work when the committer is different with author 2025-01-23 16:11:07 +08:00
leo
620f411e99
code_style: move RevisionTextFileView 2025-01-22 11:42:14 +08:00
leo
e033a93dd8
localization: update Text.Fetch.Force 2025-01-22 11:36:53 +08:00
github-actions[bot]
cce08fb086 doc: Update translation status and missing keys 2025-01-22 03:23:54 +00:00
leo
cd0b2326f5
localization: update en_US 2025-01-22 11:23:38 +08:00
leo
75288e7a31
ci: replacing 100% and 100.00% with for translation progress in README.md 2025-01-22 11:21:24 +08:00
leo
6ae66095c2
project: upgrade LiveChartsCore.SkiaSharpView.Avalonia to 2.0.0-rc5.1 2025-01-22 10:55:38 +08:00
leo
cb4ad63ba3
fix: discarding changes with selected changes should never be traited as Discard all changes (#904) 2025-01-22 10:52:01 +08:00
aikawayataro
90c04f1db2
fix: _ is not parsed in template variable name (#920) 2025-01-21 20:01:09 +08:00
GadflyFang
6482ef227a
fix: prevent target branch HEAD from being changed when adding worktree (#919)
* fix: prevent target branch HEAD from being changed when adding worktree

Signed-off-by: Gadfly <gadfly@gadfly.vip>

* fix: worktree path validator trigger error

Signed-off-by: Gadfly <gadfly@gadfly.vip>

---------

Signed-off-by: Gadfly <gadfly@gadfly.vip>
2025-01-21 13:58:07 +08:00
leo
38e7b69450
Merge branch 'master' into develop 2025-01-20 10:06:59 +08:00
leo
0f13c002f5
Merge branch 'release/v2025.03' 2025-01-20 10:06:00 +08:00
leo
b00c81c996
version: Release 2025.03 2025-01-20 10:05:43 +08:00
leo
8a472cb472
fix: sometimes tags did not update after deleting selected tag (#908) 2025-01-15 10:42:35 +08:00
leo
53ec53a6ee
project: upgrade LiveChartsCore.SkiaSharpView.Avalonia to 2.0.0-rc5 2025-01-14 21:26:31 +08:00
leo
1c8d4d312a
fix: SelectableTextBlock does not re-draw after Text property changed (#906) 2025-01-14 21:02:32 +08:00
leo
c8aecc00cc
ux: use Grid instead of DockPanel 2025-01-14 20:39:56 +08:00
github-actions[bot]
5b425c4ed0 doc: Update translation status and missing keys 2025-01-14 10:11:25 +00:00
Nils van Rijsinge
765286ec0b
localization: add missing de_DE keys (#905)
Configure.IssueTracker Gittee 22ba8b3acf
General.DateFormat c058b4744b
Git.SSLVerify 1596ca71a5
Repository.HistoriesLayout 26ebd5ae7e 6b5e8c588d
OnlyHighlightCurrentBranchInHistories, UseRelativeTimeInHistories 26ebd5ae7e
Tags.Order..., Tags.Sort 08a128cd87
SetUpstream 6fe4d8162b
2025-01-14 18:11:11 +08:00
leo
8ea17e57da
Merge branch 'feat-bare-repository' into develop 2025-01-14 18:08:46 +08:00
leo
6f407fb086
enhance: enable --index option in git stash pop command by default (#903) 2025-01-14 18:07:55 +08:00
leo
f2b1c06bb8
enhance: disable checkout branch via double-clicking branch tree node (#899) 2025-01-14 17:57:31 +08:00
leo
766b60d05e
enhance: disable unused context menus for bare repository (#899) 2025-01-14 17:53:26 +08:00
leo
a9327274c6
enhance: disable LOCAL CHANGES and STASHES for bare repository (#899) 2025-01-14 17:26:01 +08:00
leo
5acc6e6928
enhance: double-click commit in histories of a bare repository 2025-01-14 17:26:01 +08:00
leo
a112d212dc
enhance: disable pull/stash/apply/git-flow/git-lfs buttons in bare repository 2025-01-14 17:26:01 +08:00
leo
b9b5220590
feature: bare repository support 2025-01-14 17:26:01 +08:00
leo
cc5f3ebfa5
refactor: do not run git add for untracked file while stashing local changes (#903) 2025-01-14 17:10:06 +08:00
leo
d8168c3ba6
ux: submodule alignment 2025-01-14 16:14:19 +08:00
Vixb
99b7086cd0
doc: update default path for windows (#901)
(cherry picked from commit 4456366ea63b277665d7250709928deb1e563675)
2025-01-14 10:20:51 +08:00
Mat
011f5258ad
fix: LFS locks do not show if user name contains . character (#902) 2025-01-14 10:18:56 +08:00
leo
5f4c1bb984
enhance: do not show Initialize Repository popup for bare repositories (#891) 2025-01-13 17:42:41 +08:00
leo
632222a776
ux: add icon for quit menu item 2025-01-13 15:37:55 +08:00
wl2776
458a1ea83c
feature: Exit on Ctrl+Q (#898) 2025-01-13 15:33:13 +08:00
leo
b10e084c54
ux: context menu separator 2025-01-13 14:47:32 +08:00
github-actions[bot]
88e64a4f31 doc: Update translation status and missing keys 2025-01-13 06:42:23 +00:00
leo
10d8d3b2ef
refactor: branch compare 2025-01-13 14:42:07 +08:00
GadflyFang
59e3e4c635
docs: Update README.md with APT source config changes (#897)
- Update APT source configuration to include architecture-specific settings.

Signed-off-by: Gadfly <gadfly@gadfly.vip>
2025-01-13 12:07:24 +08:00
leo
f87bf8b4c6
Merge branch 'master' into develop 2025-01-13 10:30:08 +08:00
leo
4f3e6398b0
Merge branch 'release/v2025.02' 2025-01-13 10:29:01 +08:00
leo
001e813b7e
version: Release 2025.02 2025-01-13 10:28:31 +08:00
leo
6e6cd7a7f3
enhance: do not show Initialize Repository popup for bare repositories (#891) 2025-01-13 10:25:58 +08:00
github-actions[bot]
a205e17bf2 doc: Update translation status and missing keys 2025-01-13 02:11:41 +00:00
wl2776
6e5626f267
fix: several typos in source code (#895) 2025-01-13 10:11:28 +08:00
github-actions[bot]
91883c9f11 doc: Update translation status and missing keys 2025-01-13 02:07:46 +00:00
UchiTesting
f8e7976ec2
style(locale): Translate French locale further (#896)
- Picked a few of the 1st lines from TRANSLATION.md
- Updated a few others. Prune to Elaguer for instance.
2025-01-13 10:07:32 +08:00
leo
b26838ff68
refactor: git version related commands
* use `--pathspec-from-file=<FILE>` in `git add` command if git >= 2.25.0
* use `--pathspec-from-file=<FILE>` in `git stash push` command if git >= 2.26.0
* use `--staged` in `git stash push` command only if git >= 2.35.0
2025-01-11 17:29:38 +08:00
aikawayataro
c939308e4c
readme: add package repository instructions (#893) 2025-01-11 15:06:42 +08:00
leo
275a52eb5c
refactor: add repository 2025-01-11 11:28:37 +08:00
leo
52fba29613
readme: add doc for Linux RPM/DEB packages 2025-01-10 14:32:01 +08:00
GadflyFang
d7ba310a24
build: Update package dependencies to include broader range of ICU libraries (#890)
Signed-off-by: Gadfly <gadfly@gadfly.vip>
(cherry picked from commit d340584249b771f497f818f45a3bc542bc473cc5)
2025-01-10 12:24:37 +08:00
aikawayataro
f1acc96a72
ci: remove Buildkite, add missing dependencies, README edits (#885)
* build: add libicu dependency for deb package

* ci: remove obsolete Buildkite publish workflow

* build: add xdg-utils dependency

* readme: update Linux notes

Remove Buildkite repo instructions and fix some typos.
2025-01-10 09:29:19 +08:00
github-actions[bot]
7361b3d403 doc: Update translation status and missing keys 2025-01-10 01:25:28 +00:00
Bernat Borràs Civil
eca5639e31
localization: add missing translations for Spanish (#886) 2025-01-10 09:25:16 +08:00
github-actions[bot]
dd15f3aa45 doc: Update translation status and missing keys 2025-01-10 01:24:30 +00:00
AquariusStar
afe55a5ff5
localization: update russian localization (#887) 2025-01-10 09:24:18 +08:00
leo
810568e179
fix: typo 2025-01-09 18:14:11 +08:00
leo
b06d14fec7
refactor: SourceGit.App 2025-01-09 18:12:11 +08:00
leo
495b3a9296
refactor: issue tracker configuration (#884) 2025-01-09 12:28:07 +08:00
github-actions[bot]
f74dbdf8ed doc: Update translation status and missing keys 2025-01-09 04:04:52 +00:00
leo
22ba8b3acf
feature: add issue/pr tracker for Gitee.com (#884) 2025-01-09 12:04:36 +08:00
leo
9baa2c9fad
refactor: get owner page of repsitory dynamically 2025-01-09 09:21:58 +08:00
leo
f07e838e6f
code_style: remove used code 2025-01-08 21:46:35 +08:00
leo
a3d744f426
code_style: run dotnet format 2025-01-08 21:44:35 +08:00
leo
f06b1d5d51
refactor: merge ViewModels.PopupHost into ViewModels.LauncherPage 2025-01-08 21:36:49 +08:00
leo
0e34a77add
enhance: threadsafe way to accessing _remotes (#882) 2025-01-08 19:20:27 +08:00
leo
94c532889b
fix: auto fetch does not work if use ssh (#882) 2025-01-08 19:09:52 +08:00
leo
8018abe0a2
code_style: remove unused namespace using 2025-01-08 16:10:16 +08:00
leo
5d791b63bf
fix: crach while submodule changed (#881) 2025-01-08 12:42:30 +08:00
leo
eea3d5db6c
ux: right margin of filter toggle button (#875) 2025-01-08 11:14:17 +08:00
leo
df422b2219
fix: missing popup window shadows on Windows 10 (#879) 2025-01-08 09:40:23 +08:00
github-actions[bot]
5f7b6c3c66 doc: Update translation status and missing keys 2025-01-07 11:51:52 +00:00
leo
1596ca71a5
feature: add checkbox to enable/disable global http.sslVerify configuration (#877) 2025-01-07 19:51:27 +08:00
leo
7a217336dc
enhance: graph color allocation 2025-01-07 15:24:11 +08:00
github-actions[bot]
0391ec99b4 doc: Update translation status and missing keys 2025-01-07 04:06:26 +00:00
leo
6fe4d8162b
refactor: use popup to change tracking branch 2025-01-07 12:05:52 +08:00
leo
25a2bf603f
ux: conventional commit message builder layout 2025-01-07 10:40:35 +08:00
leo
903a3b9660
feature: add Ctrl+Enter/⌘+Enter hotkey to submit conventional commit (#874) 2025-01-07 10:36:07 +08:00
leo
85504b1487
enhance: enable text search for branch ComboBox (#784) 2025-01-07 10:29:55 +08:00
leo
8b04ab52d6
fix: Height can not be negative (#869) 2025-01-07 09:48:44 +08:00
AquariusStar
7f9be03e5c
localization: update translation russian (#872)
fix
2025-01-06 20:18:31 +08:00
github-actions[bot]
999c19052c doc: Update translation status and missing keys 2025-01-06 12:17:41 +00:00
leo
6b5e8c588d
ux: add a group header for advanced histories options 2025-01-06 20:17:20 +08:00
leo
a00e62233f
ux: reduce width of buttons in Histories toolbar 2025-01-06 17:58:43 +08:00
leo
68cfb092fc
ux: use a transparent brush for non relatives paths (#848) 2025-01-06 17:52:59 +08:00
github-actions[bot]
fffa4f9bea doc: Update translation status and missing keys 2025-01-06 09:24:41 +00:00
AquariusStar
108a212108
localization: update russian translate (#870) 2025-01-06 17:24:27 +08:00
github-actions[bot]
03b06de907 doc: Update translation status and missing keys 2025-01-06 08:16:48 +00:00
leo
08a128cd87
feature: add a button to switch tag sort method (creatordate/name asc/name des) (#865) 2025-01-06 16:16:27 +08:00
leo
84721a7258
update: icon for --reflog 2025-01-06 15:21:15 +08:00
github-actions[bot]
702e8ec34f doc: Update translation status and missing keys 2025-01-06 06:59:46 +00:00
leo
26ebd5ae7e
feature: add option to only highlight current branch in commit graph (#848)
- add a toggle button to only highlight current branch in commit graph
- re-order buttons in histories toolbar
- remove unused icons and styles
2025-01-06 14:59:27 +08:00
leo
65e820e4d5
fix: new created branch expanded state is not remembered 2025-01-06 10:41:41 +08:00
leo
68210d8a3e
ci: release title 2025-01-06 10:23:58 +08:00
leo
a5e1e5ebc8
Merge branch 'master' into develop 2025-01-06 09:55:38 +08:00
leo
0aa2aaaf9d
Merge branch 'release/v2025.01' 2025-01-06 09:54:31 +08:00
leo
1898385086
version: Release 2025.01 2025-01-06 09:54:18 +08:00
leo
0628e3d3f7
feature: clear commit message when toggle off Amend 2025-01-03 14:27:54 +08:00
leo
8ebf4d76d6
ux: use AvaloniaEdit.TextEditor to display release update detail info 2025-01-03 14:13:57 +08:00
leo
c6afc6a205
doc: add tips for translation 2025-01-03 09:31:04 +08:00
leo
4e06944c9f
fix: auto-filter does not work well (#855) 2025-01-02 20:05:04 +08:00
leo
127315528a
feature: auto-change filter branches after checkout (#855) 2025-01-02 14:19:10 +08:00
leo
2a55ba6d07
fix: Avalonia designer does not work (#858) 2025-01-02 11:19:52 +08:00
Juga Paazmaya
554ffc728d
Short list of commands needed when nothing has not yet been done (#859) 2025-01-02 09:14:19 +08:00
UchiTesting
1e75a518a6
style(locale): Translate French locale further (#857)
- "Checkout" translates to "Récupérer". Updating lines that match
- "Push" translates to "Pousser". Updating lines that match.
- Staged translates to "Présent dans l'index" but it is too long to I go simply for "Indexé".
- Translating a few extra lines
- Some of the terms mentioned above remain untranslated because it is not appropriate provided their respective context
2025-01-02 01:52:58 +08:00
github-actions[bot]
70fa80bab9 doc: Update translation status and missing keys 2025-01-01 17:52:14 +00:00
AquariusStar
4b02199c9b
update russian translate (#853)
fix and update
2025-01-02 01:52:01 +08:00
leo
4f350c84c3
ux: use Auto for commit time column 2024-12-31 14:44:19 +08:00
leo
7a02854e2d
fix: bad output file name while creating archive by tag 2024-12-31 11:19:05 +08:00
leo
87e7b792bb
refactor: date time format
- generate example dynamically
- update commit/author time in histories immediately after data time format changed
2024-12-31 10:43:00 +08:00
leo
a6420aff9b
fix: crash if the executable file can not be found 2024-12-31 09:38:46 +08:00
wl2776
addc756fbf
feature: support several more variants of git installation on MacOS (#852) 2024-12-31 09:28:00 +08:00
leo
ced1737bdc
fix: typo in DataTimeFormat 2024-12-30 20:29:50 +08:00
leo
82fc261743
feature: shows the git configured commit template in Template/Histories popup (#846) 2024-12-30 19:40:58 +08:00
leo
8d12227227
ux: show date time format string 2024-12-30 17:47:55 +08:00
leo
7d0fa3b86d
Revert "feature: ignore remote.{REMOTE}.mirror settings (#844)"
This reverts commit 093176d10b.
2024-12-30 17:34:58 +08:00
github-actions[bot]
418897c5de doc: Update translation status and missing keys 2024-12-30 09:20:17 +00:00
leo
c058b4744b
feature: allows to change DateTime format (#755) 2024-12-30 17:19:55 +08:00
leo
dc649e6142
refactor: rewrite the portable mode (#851) 2024-12-30 15:12:23 +08:00
leo
093176d10b
feature: ignore remote.{REMOTE}.mirror settings (#844)
(cherry picked from commit 9164f1b7340f68e00fea99bf9bac67734062f930)
2024-12-30 14:54:04 +08:00
leo
7f268a6557
Merge branch 'master' into develop 2024-12-30 09:22:26 +08:00
leo
2d500fc35a
Merge branch 'release/v8.45' 2024-12-30 09:21:39 +08:00
leo
bb8e66e479
version: Release 8.45 2024-12-30 09:21:25 +08:00
github-actions[bot]
cdda418c2d doc: Update translation status and missing keys 2024-12-30 01:19:01 +00:00
Bernat Borràs Civil
1f316708fd
Update spanish translation (#849)
* Add missing translations

* Add missing keys after merge

* Remove duplicated string

* Sort unsorted strings
2024-12-30 09:18:49 +08:00
AquariusStar
03d3cbe11e
update translation russian (#850)
fix
2024-12-30 09:18:12 +08:00
AquariusStar
fa46586417
localization: update (#845)
fix incorrected translated
2024-12-28 12:17:36 +08:00
Martin Garstenauer
12e8a212d4
fix: Enter key does not stage/unstage all selected items (#843) 2024-12-27 20:26:18 +08:00
leo
5081d2fba2
fix: error occurs while using WinMerge as external diff tool with Single instance mode enabled (#842) 2024-12-27 17:40:34 +08:00
wl2776
e407399d03
Fix some more messages in russian and english (#839) 2024-12-26 09:23:41 +08:00
wl2776
4254a22d79
Fix grammar in tip (#838) 2024-12-25 18:17:06 +08:00
leo
c9b00d7bfe
ci: do not use portable for windows actions 2024-12-24 14:48:04 +08:00
leo
f53b71bfe7
feature: add -p:EnablePortable=true option for dotnet publish command to store app data portable (#834) 2024-12-24 09:23:50 +08:00
leo
7028e08390
enhance: remove invalid expanded node records in repository's settings 2024-12-23 16:56:49 +08:00
leo
ec94c8c1b4
Merge branch 'master' into develop 2024-12-23 09:21:06 +08:00
leo
f3adb25c82
Merge branch 'release/v8.44' 2024-12-23 09:20:23 +08:00
leo
9603f2b5aa
version: Release 8.44 2024-12-23 09:20:00 +08:00
leo
ae2ffd5b40
fix: wrong text trimming position 2024-12-20 15:31:33 +08:00
leo
2e838840e0
localization: update Text.OpenAppDataDir 2024-12-20 14:57:33 +08:00
leo
dbf12ff88e
ux: layout of commit message template 2024-12-20 14:11:22 +08:00
leo
1862428a0f
feature: supports Warp terminal on macOS (#829)
Signed-off-by: leo <longshuang@msn.cn>
2024-12-20 10:44:06 +08:00
leo
50892f7401
ux: re-order context menu items for selected multiple branches 2024-12-20 10:00:10 +08:00
leo
fec13cdc87
ux: layout of INFORMATION page 2024-12-20 09:56:53 +08:00
leo
ed229166ee
enhance: allow wrap commit refs in INFORMATION page (#807) 2024-12-20 09:51:25 +08:00
leo
6c795e1238
project: upgrade TextMateSharp to 1.0.65 2024-12-19 19:30:17 +08:00
leo
7ee7964799
ux: use trimmed error message 2024-12-19 17:38:53 +08:00
leo
7acd6e42fe
project: upgrade Avalonia to 11.2.3 2024-12-19 17:09:20 +08:00
leo
9a6d6bb68a
ux: enable text wrap in notification panel 2024-12-19 10:01:36 +08:00
leo
37bf6dec5e
feature: remember --reflog, --first-parent, --topo-order and --date-order toggle states 2024-12-18 19:49:08 +08:00
leo
ed3e7cbfaf
ux: update unreal icon 2024-12-18 19:03:59 +08:00
github-actions[bot]
df6f2f3585 doc: Update translation status and missing keys 2024-12-18 10:54:50 +00:00
wl2776
b2ca6480b8
localization: Russian translation (#827)
add missing keys, based on TRANSLATION.md

reword some existing keys that seemed incorrect
2024-12-18 18:54:38 +08:00
leo
a899de2b98
enhance: ignore refs/*/HEAD when query refs those contains given commit 2024-12-18 17:50:19 +08:00
leo
31ad317a57
feature: remember the Include Untracked Files toggle state in local changes 2024-12-18 17:30:04 +08:00
leo
5ec8279d38
feature: remember the state of repository sidebar (#823) 2024-12-18 15:33:09 +08:00
leo
7526def448
project: rename dotnet publish option -p:SourceGitNoAot=true|false to -p:DisableAOT=true|false 2024-12-18 10:17:00 +08:00
leo
e4fb9eeb52
refactor: built-in default avatar 2024-12-18 10:00:25 +08:00
leo
cb3727b524
feature: remember --force check state in git fetch popup (#824) 2024-12-18 09:36:25 +08:00
Martin Garstenauer
39dff8a93f
ux: change text selection brush to improve readability (#825) 2024-12-18 09:25:56 +08:00
leo
23326d179a
refactor: commit hash detection in message 2024-12-17 14:39:18 +08:00
leo
6768a2c1fe
ux: new notification theme 2024-12-17 12:08:25 +08:00
leo
1c345df37d
ux: add some tooltips to checkboxes 2024-12-17 11:24:59 +08:00
leo
c768b1750e
feature: use -p:DisableUpdateDetection=true to disable built-in update detection feature (#819) 2024-12-17 10:26:35 +08:00
leo
707a227aca
ux: make Welcome page responsive (#821) 2024-12-17 09:36:06 +08:00
leo
f418b72c64
feature: use [$workspace] $repo_name ($repo_path) as main window's title (#818) 2024-12-16 15:47:33 +08:00
leo
5425fa64fe
refactor: use another way to open tooltip of SHA after getting commit info (#810) 2024-12-16 13:29:46 +08:00
github-actions[bot]
e4cfca0ffd doc: Update translation status and missing keys 2024-12-16 01:51:11 +00:00
Nils van Rijsinge
dd85760b7a
localization: add missing de_DE keys (#817)
* localization: add missing de_DE keys

BranchCM.MergeMultiBranches, CommitCM.MergeMultiple, MergeMultiple #793
CommitCM.Merge 2053ce033d
CommitDetail.Files.Search 894f3e9b03
Diff.UseBlockNavigation #703
FileCM.ResolveUsing 3b5d87391d
Hotkeys.Global.Clone bea2a39feb
InProgress.CherryPick.Head e1df5c52f1
InProgress.Merge.Operating ef40e4b738
InProgress.Rebase.StoppedAt, Repository.Skip #790
InProgress.Revert.Head 93d9a04460
Merge.Source 2504a52398
WorkingCopy.CommitToEdit c1368212df

* localization: consistently use clone with 'k'

for most other keys a more "germanized" version with a k is used rather than a c
2024-12-16 09:50:59 +08:00
leo
819602f77c
Merge branch 'master' into develop 2024-12-16 09:30:14 +08:00
leo
0e37e018ef
Merge branch 'release/v8.43' 2024-12-16 09:29:17 +08:00
leo
e1fb799fd4
version: Release 8.43 2024-12-16 09:29:06 +08:00
leo
f986e59a94
fix: tag filter hidden behind the scroll bar (#815)
Signed-off-by: leo <longshuang@msn.cn>
2024-12-14 20:25:25 +08:00
leo
0a0e2bc044
enhance: only create squash menu item if it is needed 2024-12-13 16:24:39 +08:00
leo
24b6153226
ux: context menu of selected commits
* update English translation
* re-order the menu items
2024-12-13 16:02:10 +08:00
leo
751991c816
refactor: rewrite the way reading full message of commit 2024-12-13 11:00:03 +08:00
leo
a99bd2e973
enhance: only dispatch error message if it contains valid data 2024-12-13 10:43:39 +08:00
Ezra
26923435e7
enhance: improve readability of default clone dir errors. (#813) 2024-12-13 10:08:47 +08:00
leo
02658839c2
enhance: notification popup 2024-12-13 10:08:26 +08:00
leo
6eb226eb44
fix: wrong whitespace at start of the last commit message while interactive rebasing (#790) 2024-12-12 20:01:10 +08:00
leo
59f11e9aca
fix: original FullMessage missing line-endings (#790) 2024-12-12 19:38:02 +08:00
leo
c4c7bef93c
ux: update Icons.Commit 2024-12-12 17:14:04 +08:00
leo
27afe1871f
fix: tooltip of commit sha did not close properly (#810) 2024-12-12 14:40:47 +08:00
github-actions[bot]
0ac1031c4c doc: Update translation status and missing keys 2024-12-12 02:03:49 +00:00
leo
2053ce033d
feature: supports merge selected commit to current branch (#800) 2024-12-12 10:03:34 +08:00
leo
e17b53da42
enhance: block-navigation in text diff view
* It is not necessary to re-calculate all the contents when `UseBlockNavigation` changed
* Redraw the text view after `block-navigation` has turned off
2024-12-12 09:44:55 +08:00
leo
9dd4166009
refactor: use MultiBinding instead of code to control visibility of Commit & Push button 2024-12-11 16:08:23 +08:00
leo
a10f9e0dd0
enhance: popup will be closed when cherry-pick or revert failed 2024-12-11 15:27:00 +08:00
leo
0dd6692cd8
enhance: supports --skip while reverting commits 2024-12-11 15:12:25 +08:00
leo
dcaeaef48a
refactor: re-design conflict panel 2024-12-11 11:33:20 +08:00
leo
36ecbcc4e0
enhance: supports self-host git server (#733) 2024-12-10 21:38:06 +08:00
leo
55ad194e0e
code_style: remove unused code 2024-12-10 21:09:26 +08:00
github-actions[bot]
9b88db290d doc: Update translation status and missing keys 2024-12-10 12:57:28 +00:00
leo
93d9a04460
enhance: show reverting commit in banner while reverting is in-progress 2024-12-10 20:57:10 +08:00
leo
2dd9cab695
enhance: try to use friendly name instead of commit hash 2024-12-10 20:23:46 +08:00
leo
3b5d87391d
ux: use Views.NameHighlightedTextBlock instead of plan text for FileCM.ResolveUsing 2024-12-10 16:56:05 +08:00
github-actions[bot]
767de75512 doc: Update translation status and missing keys 2024-12-10 08:44:55 +00:00
leo
feb7e96b2c
enhance: show friendly name instead of --theirs or --mine while resolving conflicts 2024-12-10 16:44:37 +08:00
leo
c8cdda3477
ux: color for in processing target 2024-12-10 16:17:12 +08:00
github-actions[bot]
3cecb3f888 doc: Update translation status and missing keys 2024-12-10 07:38:27 +00:00
leo
2504a52398
fix: wrong display when merge tag
* remove `Text.Merge.Source`  translations from `de_DE`/`es_ES`/`fr_FR`/`it_IT`/`pt_BR`/`ru_RU` because its content has been changed
2024-12-10 15:38:06 +08:00
github-actions[bot]
4dd3b7f412 doc: Update translation status and missing keys 2024-12-10 07:18:11 +00:00
leo
ef40e4b738
enhance: show source branch/tag/commit in banner while merging request in progress 2024-12-10 15:17:54 +08:00
leo
e1df5c52f1
localization: update Text.InProgress.CherryPick.Head 2024-12-10 14:13:44 +08:00
leo
33ef9a612d
fix: avoid crash if fontfamily contains consecutive whitespace (#799) 2024-12-10 12:06:36 +08:00
github-actions[bot]
0a486a90d9 doc: Update translation status and missing keys 2024-12-10 03:17:52 +00:00
leo
aee3abfffb
enhance: redesign in-progress banner (#790)
* show head for cherry-pick
* show stopped at for rebase
* supports `--skip` for cherry-pick and rebase
2024-12-10 11:17:30 +08:00
leo
1644b4c8ce
readme: remove unnecessary tips 2024-12-10 09:28:35 +08:00
Bernat Borràs Civil
967429cea6
doc: add repository instructions to readme (#797) 2024-12-10 09:27:26 +08:00
Данил Бизимов
33625b58da
readme: added appimagehub link (#798) 2024-12-10 09:26:15 +08:00
leo
64bedd2ae9
ux: layout for Views.MergeMultiple 2024-12-09 21:21:16 +08:00
github-actions[bot]
2b6210e61c doc: Update translation status and missing keys 2024-12-09 13:13:16 +00:00
leo
94daa46db9
code_review: PR #793
* do NOT modify the existing merge, and add a new constructor for `Commands.Merge` instead
* rewrite `ViewModels.MergeMultiple`
  - since `_histories.Commits.Find` may returns null, use `List<object>` instead of `List<Models.Commits>`
  - supports display merge target as both `Models.Commit` and `Models.Branch`
* rename translation key `Text.MergeMultiple.Commit` to `Text.MergeMultiple.Targets`, and add translations for zh_CN and zh_TW
* some UI/UX changes
2024-12-09 21:12:58 +08:00
github-actions[bot]
4eed9674b4 doc: Update translation status and missing keys 2024-12-09 13:04:39 +00:00
Dmitrij D. Czarkoff
dce33fdf60
feature: merge multiple heads (#793)
* feature: allow merging multiple heads
* feature: allow merging multiple branches from branch tree
2024-12-09 21:04:25 +08:00
github-actions[bot]
c9c7fb5d5b doc: Update translation status and missing keys 2024-12-09 08:44:36 +00:00
leo
ee3942fec6
code_review: PR #795
* update zh_CN and zh_TW translations
* simplify calling `Welcome.Clone`
2024-12-09 16:44:16 +08:00
github-actions[bot]
3990cc9452 doc: Update translation status and missing keys 2024-12-09 08:36:52 +00:00
Luigi Grilli
bea2a39feb
feature: added Ctrl+N/⌘+N shortcut (#795)
(cherry picked from commit 726cf0d376a9af9167145560977ec6e1bf748277)
2024-12-09 16:36:19 +08:00
leo
19307cebc0
ux: update icon for Block-Navigation 2024-12-09 16:11:20 +08:00
leo
a9011ddc2c
readme: update tooltips for Linux users 2024-12-09 10:24:59 +08:00
leo
9f5cbaba09
fix: publish-packages should depends on package and version 2024-12-09 09:56:07 +08:00
leo
a263002c83
Merge branch 'master' into develop 2024-12-09 09:36:03 +08:00
leo
4a3ef6267f
Merge branch 'release/v8.42' 2024-12-09 09:35:18 +08:00
leo
3196bd41a6
version: Release 8.42 2024-12-09 09:35:08 +08:00
github-actions[bot]
076ab95614 doc: Update translation status and missing keys 2024-12-09 01:31:58 +00:00
AquariusStar
33ff191212
localization: update (#794) 2024-12-09 09:31:45 +08:00
leo
962055dd2a
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2024-12-08 21:51:33 +08:00
leo
723263d099
fix: wrong binding modes
Signed-off-by: leo <longshuang@msn.cn>
2024-12-08 21:47:20 +08:00
github-actions[bot]
ea130967fb doc: Update translation status and missing keys 2024-12-08 13:02:51 +00:00
leo
15d3ad355d
code_review: PR #703
* change the name of this feature to `Enable Block-Navigation`
* change the icon of the toggle button used to enable this feature
* use a new class `BlockNavigation` to hold all the data about this feature
* create `BlockNavigation` data only when it is enabled

Signed-off-by: leo <longshuang@msn.cn>
2024-12-08 21:02:30 +08:00
github-actions[bot]
0c04cccd52 doc: Update translation status and missing keys 2024-12-08 09:50:45 +00:00
Göran W
655d71b0bc
Add navigation and highlighting of change-blocks in Text Diff (#616, #717) (#703)
* Corrected misspelled local variable nextHigh(t)light

* Implemented change-block navigation

* Modified behavior of the Prev/Next Change buttons in DiffView toolbar.
* Well-defined change-blocks are pre-calculated and can be navigated between.
* Current change-block is highlighted in the Diff panel(s).
* Prev/next at start/end of range (re-)scrolls to first/last change-block
(I.e when unset, or already at first/last change-block, or at the only one.)
* Current change-block is unset in RefreshContent().

* Added safeguards for edge cases

* Added indicator of current/total change-blocks in DiffView toolbar

* Added new Icon and String (en-US) for Highlighted Diff Navigation

* Added Preference and ToggleButton for diff navigation style
2024-12-08 17:50:33 +08:00
GadflyFang
c062f27081
fix: Dispose _autoFetchTimer before _setting set to null (#792)
Signed-off-by: Gadfly <gadfly@gadfly.vip>
2024-12-06 15:09:14 +08:00
Bernat Borràs Civil
c2252266ce
Update Spanish translation (#791)
* Update spanish translation

* doc: Update translation status and missing keys

* Add missing key

(cherry picked from commit 2bf0641323325bf97d1fac9ed225228e5015a3ba)

* doc: Update translation status and missing keys

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-12-06 09:13:45 +08:00
leo
e18d6d65e8
ux: style of MenuItem 2024-12-05 20:43:31 +08:00
leo
75e9f1e9a4
feature: show track status in Delete Multiple Branches panel (#785) 2024-12-04 19:14:48 +08:00
leo
1ddd348a40
feature: show tracking status in Delete Branch panel if possible (#785) 2024-12-04 18:04:57 +08:00
leo
d616d0897b
refactor: relative time display mode (#777) 2024-12-04 11:25:25 +08:00
stone-w4tch3r
43928936bc
Added repositories for deb/rpm packages on buildkite (#780)
* added and used new github action for publishing packages to packagecloud

* publish-packages.yml WIP

* publish-packages.yml now uses curl push

* fix naming from packagecloud to buildkite

* Add debug logs to publish-packages.yml

* fix package path

* change repo name to sourcegit

* fixed unused code

* added --fail to curl pushes

* Remove leftowers from release.yml
2024-12-04 09:57:30 +08:00
stone-w4tch3r
abacccab00
feat: Add libicu dependency to RPM spec file (#781)
(cherry picked from commit f312895ef8c77098612645a54420539fef70a849)
(cherry picked from commit 662149045f9b37e8b8842125c82d835625055150)
2024-12-04 09:48:30 +08:00
leo
ca29a232e4
enhance: call gc after viewing commit changed 2024-12-03 10:44:27 +08:00
leo
ea0bec16da
refactor: use control instead of DataContext to get input string 2024-12-03 09:35:32 +08:00
leo
0160600c75
revert: changes about SystemAccentColor (#776)
This reverts commit db8ee3410b.
2024-12-03 09:27:16 +08:00
leo
d1a1b4b2b9
enhance: do NOT show search suggestion if input string is empty (#775) 2024-12-02 21:51:05 +08:00
github-actions[bot]
a52977baf3 doc: Update translation status and missing keys 2024-12-02 13:44:50 +00:00
leo
894f3e9b03
feature: supports searching revision files (#775) 2024-12-02 21:44:15 +08:00
leo
536f225867
feature: allow using Amend while rebasing (#773) 2024-12-02 10:38:40 +08:00
leo
f9c55a94c9
Merge branch 'master' into develop 2024-12-02 09:34:19 +08:00
leo
790e1f6c4b
Merge branch 'release/v8.41' 2024-12-02 09:31:46 +08:00
leo
dc5cbd05ef
version: 8.41 2024-12-02 09:31:38 +08:00
github-actions[bot]
e5ba097141 doc: Update translation status and missing keys 2024-12-02 01:27:03 +00:00
AquariusStar
d4c5306333
localiztion: update (#772) 2024-12-02 09:26:49 +08:00
Alberto de la Cruz
22de6673bc
fix: onSHAPressed avoid right click nav (#770)
- When the right click button is pressed it should not navigate to the parent. Navigation actions only should execute with the left button.
2024-11-30 19:31:13 +08:00
github-actions[bot]
0b73f7b483 doc: Update translation status and missing keys 2024-11-30 11:25:39 +00:00
leo
c1368212df
feature: change the CONTINUE button to SplitButton to support editing/splitting original commit (#767)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-30 19:25:20 +08:00
github-actions[bot]
941ea4a695 doc: Update translation status and missing keys 2024-11-30 09:23:35 +00:00
Nils van Rijsinge
58d1122046
localization: add de_DE key for FilterCommits (#769)
8bd5bd864e
2024-11-30 17:23:23 +08:00
leo
6e69c0567a
refactor: do not use key to start fetch/pull/push/stash directly on macOS (#766)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-29 21:15:12 +08:00
leo
7d857a49f7
ux: add margins for ListItem in InteractiveRebase window (#764)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-29 21:03:11 +08:00
leo
938876e924
fix: wrong column indentation on right side of Interactive Rebase window, for wide commit messages (#764) 2024-11-29 19:12:27 +08:00
leo
e65ac18afc
fix: wrong column indentation on right side of Interactive Rebase window, for wide commit messages (#764) 2024-11-29 19:04:58 +08:00
leo
f028513d49
doc: update tips for manually build 2024-11-29 11:46:27 +08:00
leo
4cb9dbfd14
code_style: remove unused namespace using 2024-11-29 10:35:23 +08:00
leo
4aad6a7f86
fix: System.ArgumentException when hover the commit link multiple times before the first time tooltip shows (#765) 2024-11-29 10:26:36 +08:00
leo
db8ee3410b
refactor: users should change the SystemAccentColor from system-wide settings 2024-11-29 09:59:07 +08:00
leo
dfc03d7a8f
feature: allows to copy branch/tag name from the context menu of selected commit 2024-11-29 09:51:50 +08:00
leo
400aaacf18
fix: wrong column indentation on right side of Interactive Rebase window, for wide commit messages (#764) 2024-11-29 09:21:53 +08:00
leo
58eeeab67b
enhance: set core.autocrlf to false when run git diff to get detail changes of selected file (#761) 2024-11-28 19:36:23 +08:00
github-actions[bot]
8f4d3fd957 doc: Update translation status and missing keys 2024-11-28 05:57:58 +00:00
Efrem Ropelato
ccf03ce2de
fix ita locale: add ResourceInclude en_US.axaml (#762)
* Italian translation

* fix ita locale: add ResourceInclude en_US.axaml
2024-11-28 13:57:46 +08:00
leo
315a226365
code_review: PR #759
* code indent
* update README.md
2024-11-28 09:48:07 +08:00
github-actions[bot]
ba0bb35ca6 doc: Update translation status and missing keys 2024-11-28 01:45:10 +00:00
Efrem Ropelato
e66179aeb8
Italian translation (#759) 2024-11-28 09:44:59 +08:00
leo
e224f59ea7
enhance: clear unhandled key modifer before running command (#748) 2024-11-27 20:21:01 +08:00
leo
1872148d98
fix: the way to deal with local changes did not update after radio toggle changed (#748) 2024-11-27 18:31:50 +08:00
leo
1c0d8a2697
fix: git rev-list do not support --decorate-refs-exclude (#746)
Do not use histories filters to query commit children
2024-11-27 17:06:44 +08:00
leo
d38d1b11e8
fix: typo in Text.Preference.General.ShowChildren 2024-11-27 15:27:57 +08:00
leo
c5d82eb719
ux: new style for ToggleButton.toggle_untracked 2024-11-27 11:10:44 +08:00
leo
c70f94cba1
ux: change Height of repository search bar 2024-11-27 10:08:20 +08:00
leo
cb9110baef
ux: new style for repository sub-view switcher 2024-11-27 10:02:26 +08:00
leo
4fc32b2b59
fix: crash due to font family name is an empty space (#745) 2024-11-27 09:17:18 +08:00
leo
bb41fcea3e
fix: DisplayRange is not updated when text diff view is opened for the first time 2024-11-26 19:52:13 +08:00
leo
a1c48dd11b
project: upgrade AvaloniaUI to 11.2.2 2024-11-26 14:39:58 +08:00
leo
78fcc0117e
ux: style for tooltip
Signed-off-by: leo <longshuang@msn.cn>
2024-11-25 11:42:48 +08:00
leo
7d3b996de0
Merge branch 'master' into develop 2024-11-25 09:38:28 +08:00
leo
ee82067940
Merge branch 'release/8.40' 2024-11-25 09:37:44 +08:00
leo
12deb1d2c3
version: Release 8.40
Signed-off-by: leo <longshuang@msn.cn>
2024-11-25 09:37:02 +08:00
Chiahong
57d4842435
localization: update zh_TW.axaml (#739) 2024-11-25 09:28:55 +08:00
github-actions[bot]
d0f9e994bb doc: Update translation status and missing keys 2024-11-25 01:28:48 +00:00
AquariusStar
772f1a93b4
localiztion: update (#738) 2024-11-25 09:28:36 +08:00
github-actions[bot]
55e3bfa2d4 doc: Update translation status and missing keys 2024-11-25 01:28:22 +00:00
Nils van Rijsinge
831462b594
Add missing de_DE keys (#737)
* localization: add missing de_DE keys

- CommitDetail.Info.Children, General.ShowChildren were added in cc5bb5f
- Text.Fetch.Force was added in 153a1f3
- Repository.HistoriesOrder... were added in b25f9bd
- SHALinkCM.NavigateTo was added in 12f7531

* localization: fix invalid XAML
2024-11-25 09:28:09 +08:00
Nils van Rijsinge
bf4080b773
fix: crash on goto to SHA, NullReferenceException (#741) 2024-11-25 09:24:16 +08:00
leo
4160f8ab9c
fix: only set tooltip if commit exists
Signed-off-by: leo <longshuang@msn.cn>
2024-11-24 21:43:31 +08:00
leo
b2e01f0d3e
feature: add tooltip for SHA in commit message presenter (#734)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-24 21:22:04 +08:00
leo
637f138d63
code_style: remove Rider warning
Signed-off-by: leo <longshuang@msn.cn>
2024-11-24 20:28:32 +08:00
github-actions[bot]
f820c0ccac doc: Update translation status and missing keys 2024-11-24 03:06:15 +00:00
leo
457a1e79c7
code_review: PR #734
* remove unnecessary namespace using
* do NOT set tooltip currently, because CommitDetail.GetParent may cause UI lags and the tooltip DataTemplate is not provided.
* add translations for zh_CN and zh_TW

Signed-off-by: leo <longshuang@msn.cn>
2024-11-24 11:05:55 +08:00
github-actions[bot]
53220f9a36 doc: Update translation status and missing keys 2024-11-24 02:53:30 +00:00
Dmitrij D. Czarkoff
12f75315bd
feat: context menu for a commit in commit message (#734)
* feat: context menu for a commit in commit message

When a commit message happens to contain a commit link and the user elects to right-click it, instead of navigating them to the commit,  present a menu with options to navigate to it or to copy SHA.

* feat: show commit tooltip as well

`_lastHover` in the `if` is also swapped for `match`for consistency with the block body
2024-11-24 10:53:16 +08:00
leo
693940368b
code_style: remove unused variable
Signed-off-by: leo <longshuang@msn.cn>
2024-11-24 10:20:40 +08:00
Dmitrij D. Czarkoff
e3d6ee0f40
fix: better https regex (#735)
Fixes #733
2024-11-24 10:15:17 +08:00
Dmitrij D. Czarkoff
546f628470
fix: don't reverse commit order when cherry-picking (#736)
Fixes #726.  Looks like a980cc987d isn't sufficient.  It sorts the commits according to the ordering in history,  but then CherryPick ViewModel reverses the order.

This commit changes CherryPick ViewModel to use string.Join on the commit list without reordering,  so that the ordering is controlled entirely by the caller.
2024-11-24 09:32:47 +08:00
leo
cd96a28545
fix: typo in English (#731)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-22 18:47:06 +08:00
Martin Garstenauer
3ae3c587d8
fix: typo in English (#731) 2024-11-22 18:43:45 +08:00
leo
c78e2e59d9
enhance: git format-patch
* use `--output=<file>` instead of `-o <dir>` to avoid failure because the directory cannot be created
* make generated patches in order when format multiple commits

Signed-off-by: leo <longshuang@msn.cn>
2024-11-22 18:40:59 +08:00
leo
c50508d4ac
fix: try to fix the issue that the branch tree did not update after deleting multiple branches (#729)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-22 10:42:53 +08:00
github-actions[bot]
378e8d3ea3 doc: Update translation status and missing keys 2024-11-22 01:40:15 +00:00
leo
153a1f30b2
feature: supports toggle --force option for git fetch command (#721)
* Background auto fetch will always disable this option
* This option is not add to pull operation

Signed-off-by: leo <longshuang@msn.cn>
2024-11-22 09:39:50 +08:00
leo
c1c743f2ff
readme: add tips for Linux users
Signed-off-by: leo <longshuang@msn.cn>
2024-11-22 09:17:56 +08:00
leo
1e148c032d
localization: update English translations
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 21:10:15 +08:00
leo
13504d1831
ux: make sure Icons.Eye center aligned
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 21:01:06 +08:00
leo
8a95a17b0e
ux: re-order menu items
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 20:55:59 +08:00
github-actions[bot]
f545ceeb70 doc: Update translation status and missing keys 2024-11-21 12:51:19 +00:00
leo
8bd5bd864e
feature: add context menu to switch histories filter mode to selected commit
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 20:50:51 +08:00
leo
e6e1e4e82e
fix: can not type characters with accent (#716)
Leaves the `X11PlatformOptions.EnableIme` unsetted, since Avalonia will auto enable it when `LANG` contains `zh`/`ja`/`vi`/`ko`

Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 19:23:59 +08:00
leo
f0d8285416
enhance: only supports using local bare repository as remote (#706)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 14:53:43 +08:00
leo
d98765364d
feature: supports using local repository as remote (#706)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 14:49:32 +08:00
leo
b407dd97a1
enhance: reduce repository scanning time (#728)
* skip special folders, such as `node_modules`, `.svn`, `.vs` .etc.
* change max scanning depth to 5

Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 14:18:41 +08:00
leo
069dc255d1
enhance: skip scanning sub folders if current is not a git repository but has .git subfolder/file (#728)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 12:56:12 +08:00
leo
d3eca59036
refactor: rewrite the way to make sure scan repositories panel shows at least 0.5s (#728)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 12:14:11 +08:00
leo
8342702103
feature: add save as path menu item for commit change (#724)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 10:19:00 +08:00
leo
22157a5c98
fix: tooltip of parent SHA textblock is not closed properly (#727)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 10:06:16 +08:00
leo
a980cc987d
fix: wired ordering when cherry-pick multiple commits (#726)
Since the items in `ListBox.SelectedItems`  are not ordered by their position in the list, but in the order user selected, it need be sorted before `cherry-pick`

Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 09:57:43 +08:00
leo
142987f73d
enhance: use user instead of system to supports OpenAI's o1-preview and o1-mini model (#725)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-21 09:31:38 +08:00
leo
b3ebd84af5
enhance: outputs the response body if OpenAI fails
Signed-off-by: leo <longshuang@msn.cn>
2024-11-20 19:44:58 +08:00
leo
efac161b12
refactor: update Repository.HistoriesFilterMode in Repository.RefreshHistoriesFilters
Signed-off-by: leo <longshuang@msn.cn>
2024-11-20 16:52:30 +08:00
leo
839dab494b
ux: expand height of commit message box in commit template settings (#720)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-20 14:39:53 +08:00
leo
86d7541a7c
enhance: histories filter
* set upstream branch using the same filter mode when change the filter mode of local branch
* also excludes the decorators when current filter mode is excluding.

Signed-off-by: leo <longshuang@msn.cn>
2024-11-20 11:27:43 +08:00
leo
4796024483
fix: modified the translation of Text.CommitDetail.Info.Committer by mistake
Signed-off-by: leo <longshuang@msn.cn>
2024-11-20 10:21:59 +08:00
github-actions[bot]
892c74406f doc: Update translation status and missing keys 2024-11-20 01:57:08 +00:00
leo
71e09ee045
localization: add missing translations for zh_CN and zh_TW (#710)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-20 09:56:51 +08:00
github-actions[bot]
15eaa9eeab doc: Update translation status and missing keys 2024-11-20 01:43:12 +00:00
leo
ab2156bfc2
code_review: PR #710
* SourceGit.Commands.* should not reference SourceGit.ViewModels.*
* remove unused namespace using
* update translations for zh_CN and zh_TW
* use WrapPanel instead of inner ScrollViewer
* some other UI/UX changes

Signed-off-by: leo <longshuang@msn.cn>
2024-11-20 09:42:48 +08:00
github-actions[bot]
dd0580d0f5 doc: Update translation status and missing keys 2024-11-20 01:17:50 +00:00
Dmitrij D. Czarkoff
cc5bb5f6d4
Show the list of children in the commit details (#710)
* feature: add children list to the commit base info view

Useful for navigation between the commits.

* feature: use repository filters to limit children search
* feature: execute children search asynchronously
* feature: respect global commit limit for a good measure
* fix: input lines may contain several commits

The first commit is always the immediate child, so take only 40 initial characters of the line

* fix: hide children behind the preference
* feature: make parents and children scrollable
2024-11-20 09:17:36 +08:00
Jean Franz
cc1eb55cf0
update pt-BR strings (#722)
* fix: update pt-BR strings
* doc: Update translation status and missing keys

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-20 09:16:44 +08:00
leo
7a9c8d7444
ux: enable TextTrimming for author name in FileHistories
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 20:07:49 +08:00
aikawayataro
8021cd8566
enhance: introduce template engine for commit templates (#704) (#719) 2024-11-19 19:46:44 +08:00
leo
73687689ce
ux: min height of change block in minimap
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 16:45:07 +08:00
leo
b452e13453
localization: update Text.Repository.HistoriesOrder.ByDate
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 14:42:59 +08:00
leo
814529a690
feature: add hotkeys to stage/unstage/discard block or selected lines in text diff view (#718)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 12:12:54 +08:00
github-actions[bot]
00804e453e doc: Update translation status and missing keys 2024-11-19 03:33:55 +00:00
leo
b25f9bdb6c
feature: supports switch histories order mode (#705)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 11:32:13 +08:00
leo
f45bed6f92
fix: avoid NRE
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 10:31:17 +08:00
leo
3be90b2ef6
Merge branch 'master' into develop 2024-11-19 09:53:24 +08:00
leo
f7ef61f1ce
Merge branch 'release/8.39' 2024-11-19 09:53:03 +08:00
leo
0da46cb90b
version: Release 8.39
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 09:52:52 +08:00
leo
8b3d129890
code_review: PR #711
* SourceGit.Commands.* should not reference code in SourceGit.ViewModels.

Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 09:46:06 +08:00
Dmitrij D. Czarkoff
309db6e362
enhance: slightly improve statistics (#711)
* use preference MaxHistoryCommits
* use current culture to adjust first days of the week
2024-11-19 09:35:32 +08:00
leo
5b55e3530d
ux: better drop shadow effect for notifications
Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 09:34:09 +08:00
leo
d07a664166
code_review: PR #714
* remove `string.ToLower` warning
* override `OnLoaded` method directly
* clean namespace using

Signed-off-by: leo <longshuang@msn.cn>
2024-11-19 09:27:31 +08:00
Enner Pérez
ea1d966d27
feat: Reset Mode Hotkey (#714) 2024-11-19 09:14:53 +08:00
Dmitrij D. Czarkoff
f4618afee6
feature: switch WinMerge from 3-way to 2-way UI (#712) 2024-11-18 09:03:27 +08:00
leo
3b09ea45f5
feature: add change minimap for text diff view
Signed-off-by: leo <longshuang@msn.cn>
2024-11-17 21:49:33 +08:00
github-actions[bot]
b7abf2ee50 doc: Update translation status and missing keys 2024-11-17 03:16:44 +00:00
Nils van Rijsinge
6f256f6f5b
Add and improve de_DE keys (#709)
* localization: add missing de_DE keys

added for #690

* localization: improve de_DE keys

- mostly code review suggestions from #664
- ClearAllCommitsFilter is not an action of deleting (löschen)
2024-11-17 11:16:31 +08:00
Dmitrij D. Czarkoff
5301645f8b
fix: in commit view get file histories by commit (#708)
When file histories are accessed from the commit details view, run git log for the inspected commit.  Previously the log was ran against current branch regardless whether the inspected commit belongs to that branch.
2024-11-17 11:14:56 +08:00
leo
882878dbe5
refactor: text diff view go to next/prev change
Signed-off-by: leo <longshuang@msn.cn>
2024-11-16 18:24:37 +08:00
leo
52c7388a38
project: upgrade to .NET 9 (#694)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-16 16:06:30 +08:00
leo
134c71064e
feature: add buttons to go to prev/next change in text diff view (#616)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-16 15:17:29 +08:00
leo
cd137e222c
feature: enable --no-ext-diff for git diff command
Signed-off-by: leo <longshuang@msn.cn>
2024-11-16 09:26:13 +08:00
leo
8d84d0f6a1
enhance: improve update filter mode performance
Signed-off-by: leo <longshuang@msn.cn>
2024-11-16 09:14:57 +08:00
leo
4b6bb70f20
fix: parent commit's tooltip does not close when move mouse out of bound fast
Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 16:04:42 +08:00
leo
bd85b41da7
ux: clear histories filter button style
Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 14:50:18 +08:00
leo
5861482455
fix: wrong format
Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 11:55:18 +08:00
leo
30741b0f25
project: upgrade dependencies
* upgrade Avalonia to 11.1.4
* upgrade LiveChartsCore.SkiaSharpView.Avalonia to 2.0.0-rc4.5
* upgrade TextMateSharp to 1.0.64

Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 11:51:13 +08:00
leo
e78b58cb81
localization: remove duplicated keys
Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 11:49:49 +08:00
leo
a5f37800f6
code_style: remove unused var
Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 10:52:39 +08:00
leo
4835c3f1e9
enhance: do NOT trigger double clicking events when user click the blank area of ListBox
Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 10:50:52 +08:00
leo
a5606e80d4
refactor: move codes from Views.FilterModeSwitchButton to ViewModels.Repository
Signed-off-by: leo <longshuang@msn.cn>
2024-11-15 10:19:39 +08:00
github-actions[bot]
66842b1d0d doc: Update translation status and missing keys 2024-11-15 01:19:12 +00:00
AquariusStar
63dfde7cb8
localization: update translation for russian (#700) 2024-11-15 09:18:55 +08:00
leo
a824adf6d3
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 21:15:40 +08:00
leo
28c93da73b
ux: show Unset menu item only if it is necessary (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 21:12:18 +08:00
leo
04697093a8
localization: update Text.Repository.FilterCommits.Default (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 20:56:49 +08:00
leo
1298a22b00
ux: use dynamic icon for filter tips.
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 20:53:59 +08:00
leo
44557c066c
enhance: clear histories filter if there's a filter that has different modes with the new one (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 20:22:08 +08:00
leo
a53787c754
fix: git rebase --continue fail (#693)
* fix the exit code when start `SourceGit` as core editor (rebasing).
* redesign the layout of working copy page for in-progress states.

Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 19:19:58 +08:00
github-actions[bot]
bb90c86649 doc: Update translation status and missing keys 2024-11-14 07:21:47 +00:00
leo
ca5bc4b4df
refactor: rewrite the histories filter function to supports both include and exclude modes (#690)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 15:15:48 +08:00
leo
e3ffe3ef6c
enhance: supports Azure OpenAI REST API (#695)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-14 14:56:21 +08:00
github-actions[bot]
3c5a4741bf doc: Update translation status and missing keys 2024-11-14 01:18:29 +00:00
TheGthr
7ffebec8a6
Add missing fr_FR keys (#696)
* localization: add missing fr_FR keys

---------

Co-authored-by: Theo GAUTHIER <theo.gauthier@soprasteria.com>
2024-11-14 09:18:09 +08:00
leo
ea4e968404
ux: repository left panel layout
Signed-off-by: leo <longshuang@msn.cn>
2024-11-13 11:35:48 +08:00
leo
fd5c1f5105
code_review: PR #692
* remove unnecessary namespace using
* move `Commands.Branch.HasRemote` to `Commands.Remote.HasBranch`
* remove `Commands.Branch.DeleteRemoteTracking` and check branch in `Commands.Branch.DeleteRemote` directly

Signed-off-by: leo <longshuang@msn.cn>
2024-11-13 10:04:28 +08:00
Alberto de la Cruz
8935bdd4c9
feat: delete orphan remote tracking branches (#692)
* feat: remove orphan remote-tracking branches

- Allow user remove local remote-tracking branches without remotes (ie. remote was removed on merge request).
- Included 'DeleteRemoteTracking' and 'HasRemote' util methods to handle this case.

* fix: delete both case (local & remote-tracking)

- We have local and remote-tracking but not a remote branch. We need to remove both or only the tracking based on the checkbox and on the 'hasRemote' condition
2024-11-13 09:33:35 +08:00
aikawayataro
c16a412aa3
fix: SourceGit misspelled as "Source Git" (#689) 2024-11-12 19:55:42 +08:00
aikawayataro
146f383aae
enhance: depend on SO in rpm package (#688)
* enhance: ensure LF line endings used with package manifests
* enhance: depend on shared object instead of package

Back in 211c263, I changed the dependencies to depend on package instead of shared object. This worked well, but introduced some problems for distros other than Fedora (81f76f0). I did this because of problems with the arm64 package, but now I think `__isa_bits` is a reasonable workaround.

* refactor: remove pointless variable checks

`set -u` was introduced in 6461765
2024-11-12 19:50:16 +08:00
leo
5e60780c9f
ux: new tooltip style
Signed-off-by: leo <longshuang@msn.cn>
2024-11-12 18:28:35 +08:00
leo
f66e9c828a
ux: layout for parent commit tooltip
Signed-off-by: leo <longshuang@msn.cn>
2024-11-12 18:14:00 +08:00
Nils van Rijsinge
b0a5a033c6
Add missing de_DE keys (#687)
* localization: add missing de_DE keys

- SaveAsPatch: 6486095
- VisualLine: 1a8acbf
- Hotkeys (Fetch, Pull, Push, CreateBranchOnCommit): d50b2c0
- IssueLinkCM: 163e8cc
- Appearance.FontSize: 774ec65

* doc: Update translation status and missing keys
2024-11-12 18:09:28 +08:00
leo
6e4f971733
feature: show tooltip of parent commit when hover the parent SHA
Signed-off-by: leo <longshuang@msn.cn>
2024-11-12 17:59:50 +08:00
leo
1f158eeded
refactor: use --tags instead of --force for git fetch command if Fetch without tags is turned off (#684)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-12 09:43:24 +08:00
leo
503f700fc2
refactor: open selected revision file (#681)
* Instead of opening the file from current worktree, save the selected revision file to the temp dir and the open it with default editor
* Do NOT set the `IsEnable` property, since the revision file is always available

Signed-off-by: leo <longshuang@msn.cn>
2024-11-11 20:24:17 +08:00
github-actions[bot]
db66ba82a6 doc: Update translation status and missing keys 2024-11-11 06:22:28 +00:00
AquariusStar
d3e1796492
localization: update translation for russian (#680) 2024-11-11 14:22:16 +08:00
leo
050b1d1188
enhance: supports issue link in keywords (#678)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-11 12:16:29 +08:00
github-actions[bot]
0842beb51d doc: Update translation status and missing keys 2024-11-11 03:01:20 +00:00
leo
774ec65ef6
ux: layout for font size settings
Signed-off-by: leo <longshuang@msn.cn>
2024-11-11 11:01:02 +08:00
leo
13805f794a
Merge branch 'develop' 2024-11-11 10:29:09 +08:00
github-actions[bot]
79c1fb63d0 doc: Update translation status and missing keys 2024-11-11 02:26:54 +00:00
leo
82320f3494
revert: PR #673
* the `Commands.QueryCommitChildren` takes too much time when executes in a large repo

Signed-off-by: leo <longshuang@msn.cn>
2024-11-11 10:26:34 +08:00
leo
a969bd9c99
Merge branch 'master' into develop 2024-11-11 09:56:14 +08:00
leo
3ee56ddd29
Merge branch 'release/v8.38' 2024-11-11 09:55:55 +08:00
leo
7df6d32ad2
version: release 8.38
Signed-off-by: leo <longshuang@msn.cn>
2024-11-11 09:55:40 +08:00
leo
67cf23267a
feature: supports open selected revision file with default editor (#674)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-11 09:37:42 +08:00
github-actions[bot]
06656f625e doc: Update translation status and missing keys 2024-11-11 01:31:18 +00:00
leo
bbac6c1478
code_review: PR #673
* add translations for zh_CN and zh_TW
* hide `CHILDREN` line if it is empty

Signed-off-by: leo <longshuang@msn.cn>
2024-11-11 09:31:04 +08:00
github-actions[bot]
055835cac2 doc: Update translation status and missing keys 2024-11-11 01:25:03 +00:00
Dmitrij D. Czarkoff
03f96cc9f8
feature: add children list to the commit base info view (#673) 2024-11-11 09:24:49 +08:00
github-actions[bot]
e2e79fe1b3 doc: Update translation status and missing keys 2024-11-11 01:19:53 +00:00
Bernat Borràs Civil
8b3212e287
localization: update spanish translation (#676) 2024-11-11 09:19:41 +08:00
leo
8de37720fa
code_style: remove Rider warnings
Signed-off-by: leo <longshuang@msn.cn>
2024-11-10 13:19:25 +08:00
leo
daba8e5064
code_review: PR #672
* use formatted string instead of `CommitUrlTitle`

Signed-off-by: leo <longshuang@msn.cn>
2024-11-10 13:19:05 +08:00
Dmitrij D. Czarkoff
bbfc94d624
enhance: several commit links improvements (#672)
* Codeberge (https://codeberg.org/)
* Gitea (https://gitea.org/)
* sourcehut (https://git.sr.ht/)
2024-11-10 12:56:08 +08:00
github-actions[bot]
96c2d0b3ca doc: Update translation status and missing keys 2024-11-10 04:51:30 +00:00
Dmitrij D. Czarkoff
4924e960bf
feature: allow merging tags into branches (#671)
Adds "Merge {tag} into {branch}" menu item to tag menu in histories.
The rest is handled by already existing merge code.
2024-11-10 12:51:15 +08:00
github-actions[bot]
b974436c8a doc: Update translation status and missing keys 2024-11-08 13:25:59 +00:00
Katharina Sternbauer
3b4e037547
add missing german localization for v8.37 (#664)
Add the missing keys in the German translation file.
2024-11-08 21:25:47 +08:00
github-actions[bot]
467371d585 doc: Update translation status and missing keys 2024-11-08 13:25:36 +00:00
Fernando Medeiros
f47f1ac070
Adding missing pt_BR translation keys (#668) 2024-11-08 21:25:20 +08:00
Nils van Rijsinge
1877e37c9c
localization: adjust 4 DE translations (#665)
- use formulation of conventionalcommits.org
- "Aktiviere" was also used for other keys instead of "einschalten"
2024-11-08 19:24:51 +08:00
github-actions[bot]
f3d377fa59 doc: Update translation status and missing keys 2024-11-08 11:24:12 +00:00
AquariusStar
bfe824bbfc
update translation for russian (#666) 2024-11-08 19:23:59 +08:00
github-actions[bot]
9d054a3dbf doc: Update translation status and missing keys 2024-11-07 09:52:43 +00:00
leo
ef84891df1
feature: add new Editor Font Size configuration for all text editors (#661)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-07 17:52:23 +08:00
leo
ffeb63613c
fix: ignoring new files under folder creates invalid .gitignore entries (#663)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-07 17:18:04 +08:00
leo
243ce8b06d
project: use default optimization settings
Signed-off-by: leo <longshuang@msn.cn>
2024-11-07 11:31:51 +08:00
github-actions[bot]
4675b6edb8 doc: Update translation status and missing keys 2024-11-07 03:11:52 +00:00
leo
a919da6b4a
code_style: remove unused code and resources
Signed-off-by: leo <longshuang@msn.cn>
2024-11-07 11:11:35 +08:00
leo
45f4a5a4b1
ux: layout of floating panels (commands and notifications) (#659)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-07 11:07:47 +08:00
leo
88cec05e67
ux: do not use OpenAI logo
Signed-off-by: leo <longshuang@msn.cn>
2024-11-06 14:50:25 +08:00
github-actions[bot]
a715143a16 doc: Update translation status and missing keys 2024-11-06 04:36:13 +00:00
leo
9cb85081ab
feature: saving as patch supports multiple commits (#658)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-06 12:35:55 +08:00
leo
c72506d939
code_style: simplify the way detacting system preferred command key
Signed-off-by: leo <longshuang@msn.cn>
2024-11-06 10:36:10 +08:00
leo
d50b2c0298
code_review: PR #657
* add hotkey `Ctrl+Down/⌘+Down` to fetch directly
* keep translation keys of en_US in order
* add translations for zh_CN and zh_TW
* do NOT using namespace under `SourceGit`
* use `⇧` instead of `Shift` in hotkey tips
* hotkey mismatch on macOS
* hotkeys to start fetch/pull/push directly not work on macOS
* remove the hotkey of `Create Branch` context menu item
   - there are other objects (such as branch and tag) also have the `Create Branch` context menu item without hotkeys
   - on macOS, we already use `⌘+B` to create branch with selected commit, not `Ctrl + B`

Signed-off-by: leo <longshuang@msn.cn>
2024-11-06 10:25:44 +08:00
github-actions[bot]
dc49c1bf76 doc: Update translation status and missing keys 2024-11-06 01:15:14 +00:00
Fernando Medeiros
2e6eca26f7
Adding hotkeys for creating branch, pushing and pulling (#657) 2024-11-06 09:14:56 +08:00
leo
fdf30aa7cc
fix: custom action error message format
Signed-off-by: leo <longshuang@msn.cn>
2024-11-05 12:24:33 +08:00
leo
680cdca28d
feature: handle custom action error output
Signed-off-by: leo <longshuang@msn.cn>
2024-11-05 12:15:20 +08:00
leo
9d2c2df6b3
ux: issue link tooltip max width
Signed-off-by: leo <longshuang@msn.cn>
2024-11-05 11:00:04 +08:00
github-actions[bot]
c337d67bbe doc: Update translation status and missing keys 2024-11-05 01:48:51 +00:00
Bernat Borràs Civil
8f5dfcc209
Add missing translations in spanish (#655) 2024-11-05 09:48:37 +08:00
leo
dcf5093406
enhance: avoid that diff view refresh more than one times
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 18:21:07 +08:00
github-actions[bot]
a5aa2254f6 doc: Update translation status and missing keys 2024-11-04 08:49:32 +00:00
leo
6209326fe0
code_review: PR #652
* update localization for zh_CN and zh_TW
* change the icon for `Icons.Lines.All`
* reorder diff view toolbar buttons
* move private methods after protected

Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 16:49:15 +08:00
github-actions[bot]
8d4afafd2d doc: Update translation status and missing keys 2024-11-04 08:33:05 +00:00
Göran W
1a8acbf934
feature: diff - toggle show all lines (#615) (#652)
* Renamed 1 of 2 SyncScrollOffset props, for clarity

The property "SyncScrollOffset" in TextDiff is distinct from the one with the same name in TwoSideTextDiff. These two properties are used in separate (though slightly related) ways and are not really connected.

The one in TwoSideTextDiff is mainly used to keep the scroll-pos of the two SingleSideTextDiffPresenter views in sync (aligned), while the one in TextDiff is used only to preserve/reset the scroll-pos in the single CombinedTextDiffPresenter view when (re)loading Diff Content (so not really syncing anything).

To clarify this and to make the two properties more distinguishable, I renamed the one in TextDiff to simply "ScrollOffset".

* Added icon and string for "Show All Lines"

New StreamGeometry "Icons.Lines.All" using SVG path from "text_line_spacing_regular" at https://avaloniaui.github.io/icons.html.
New String "Text.Diff.VisualLines.All" for en_US locale (no translations yet).

* Implemented new TextDiff feature "Show All Lines" (toggle)

* Added new ToggleButton in DiffView toolbar, visible when IsTextDiff, disabling the buttons "Increase/Decrease Number of Visible Lines" when on.

* Added new Preference property "UseFullTextDiff".

* Added StyledProperty "UseFullTextDiffProperty" in TextDiffView, with a DataTemplate binding to the corresponding preference property.

* When changed, UseFullTextDiffProperty is handled identically as UseSideBySideDiffProperty (via new helper method RefreshContent(), for unification with OnDataContextChanged()).

* Added new method DiffContext.ToggleFullTextDiff() for changing the preference property and reloading the diff content.

* Implemented the new feature by overriding the "unified" (number of context lines) for Commands.Diff() with a very high number.

NOTE: The number used (~1 billion) is supposed to be the highest one working on Mac, according to this forum comment: https://stackoverflow.com/questions/28727424/for-git-diff-is-there-a-uinfinity-option-to-show-the-whole-file#comment135202820_28846576
2024-11-04 16:32:51 +08:00
leo
779b38be28
localization: change OpenAI to AI
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 16:04:19 +08:00
leo
ad01eb442d
localization: change OpenAI to AI
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 16:00:40 +08:00
leo
635396008d
fix: clicking Open in Browser context menu item of issue link does not work (#651)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 15:48:28 +08:00
github-actions[bot]
2f628b0f06 doc: Update translation status and missing keys 2024-11-04 07:35:07 +00:00
leo
fb9e342ee0
localization: add translations for zh_CN and zh_TW
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 15:34:50 +08:00
github-actions[bot]
25028efa4d doc: Update translation status and missing keys 2024-11-04 07:32:24 +00:00
leo
163e8cc0a4
feature: add context menu for issue link in commit details panel (#651)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 15:31:55 +08:00
leo
64860950c7
localization: update en_US
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 12:03:47 +08:00
leo
310c786693
feature: ignore case when finding visual studio solution file
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 11:54:18 +08:00
leo
921b8599df
Merge branch 'master' into develop 2024-11-04 10:07:37 +08:00
leo
9452b796a5
Merge branch 'release/v8.37' 2024-11-04 10:07:12 +08:00
leo
5966b8ac08
version: Release 8.37
Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 10:06:51 +08:00
leo
6b348fbd1a
code_review!: PR #648
* rewrite `Models.ExternalTool` to use `_execArgsGenerator` instead of `OpenCmdArgs` and `ArgTransform`
* remove dependency of `System.Linq` due to AOT limitations
* since the `Visual Studio` is only available on Windows, use `TryAdd` directly.
* update `README.md`

BREAKING CHANGE: now the key in `external_editors.json` uses the same name with external tool.

Signed-off-by: leo <longshuang@msn.cn>
2024-11-04 10:02:20 +08:00
Dmitrij D. Czarkoff
1d0098703e
feature: add support for Visual Studio as external tool (#648)
* feature: support Visual Studio external tool on Windows
* feature: when opening in Visual Studio, try to locate solution file
2024-11-04 09:22:16 +08:00
Chiahong
fba84c8297
fix: prevent crash in Custom Action when executable path is missing (#646) 2024-11-03 17:00:17 +08:00
Chiahong
06762615b6
localization: update zh_TW.axaml (#645) 2024-11-03 14:45:19 +08:00
leo
58fbb16347
code_review: PR #644
- use `AutoFocusBehaviour.IsEnable` instead of toggle focus by code in `OnOpened `

Signed-off-by: leo <longshuang@msn.cn>
2024-11-03 10:58:50 +08:00
Aliaksandr Liakhavets
794163fe1c
Set default focus on password text box (#644)
Co-authored-by: AleksandrLiakhavetsEPAM <97155822+AleksandrLiakhavetsEPAM@users.noreply.github.com>
2024-11-03 09:25:32 +08:00
github-actions[bot]
1fecbbb37f doc: Update translation status and missing keys 2024-11-02 03:12:01 +00:00
AquariusStar
174430338c
localiztion: update (#641) 2024-11-02 11:11:48 +08:00
leo
2f9e825b63
refactor: pass Models.Commit instead of just sha of it
Signed-off-by: leo <longshuang@msn.cn>
2024-11-01 18:10:22 +08:00
leo
ba3c72585d
enhance: use Inter as default font for all platforms (#639)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-01 17:54:21 +08:00
github-actions[bot]
26fe56e065 doc: Update translation status and missing keys 2024-11-01 09:25:17 +00:00
leo
a36058ec51
feature: supports custom actions (#638)
Signed-off-by: leo <longshuang@msn.cn>
2024-11-01 17:23:31 +08:00
leo
7c5de7e48c
enhance: do NOT restore fullscreen window on macOS
Signed-off-by: leo <longshuang@msn.cn>
2024-11-01 12:22:47 +08:00
leo
98612b0024
code_style: remove unused code
Signed-off-by: leo <longshuang@msn.cn>
2024-11-01 10:00:37 +08:00
leo
e3c0f7d496
refactor: rewrite chromeless window (#634)
* use system chrome instead of custom caption button on macOS
* move `BeginMoveWindow` and `MaximizeOrRestoreWindow` to `ChromelessWindow`
* better supports for fullscreen mode on macOS
* redesign the layout of title bar for all windows

Signed-off-by: leo <longshuang@msn.cn>
2024-11-01 09:38:42 +08:00
leo
1999e4bf47
ux: remove button padding and use content alignment to center text
Signed-off-by: leo <longshuang@msn.cn>
2024-10-31 20:02:31 +08:00
github-actions[bot]
39250466d5 doc: Update translation status and missing keys 2024-10-30 21:56:22 +00:00
AquariusStar
9b2e0bc5cf
localization: update (#632) 2024-10-31 05:56:06 +08:00
GadflyFang
cffcf3448e
fix: query file size quote filename (#629)
Signed-off-by: Gadfly <gadfly@gadfly.vip>
2024-10-30 18:48:41 +08:00
Masgalor
9816a5e8ba
fix: Make RPM builds compatible with OpenSUSE (libX11) (#628) 2024-10-30 18:45:25 +08:00
github-actions[bot]
0228bef1db doc: Update translation status and missing keys 2024-10-30 10:40:00 +00:00
leo
3cbffa6ff9
feature: add an option in repository configuration to enable --prune on fetch (#590)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 18:39:38 +08:00
leo
a4befd010a
code_review: PR #627
* add minimal height for both unstaged and staged changes view

Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 18:10:53 +08:00
yindf
2d7ea561e2
fix bug that stuck auto fetch when pull failed & make stage area resizeable (#627)
* fix watcher stuck by pull
* make stage area resizeable

---------

Co-authored-by: yindf <yindf@mail.jj.cn>
(cherry picked from commit a842aca042a73cb5fa3995794aae2a2e3540b37f)
2024-10-30 17:59:59 +08:00
leo
fe03512c5c
ux: tooltip of commit signing status icon
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 15:10:26 +08:00
leo
195325187d
ux: tooltip of commit signing status icon
* do NOT show signer if it is not available
* new tooltip style

Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 15:01:08 +08:00
GadflyFang
4e87b25765
enhance: show commit signer (#626)
Signed-off-by: Gadfly <gadfly@gadfly.vip>
2024-10-30 14:48:37 +08:00
leo
e680f8477e
readme: contributor image
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 13:07:30 +08:00
leo
f8f169d23a
fix: typo in commit signing status info
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 12:58:46 +08:00
leo
9abda2c6ab
ux: move the commit signing status icon to the last
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 10:27:14 +08:00
leo
81fc859a37
readme: keep the same order for locales
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 10:17:44 +08:00
leo
df3b4e424a
localization: add fallback locale for es_ES (#623)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 10:13:52 +08:00
leo
1adcf4dd80
enhance: do NOT query gpg.ssh.allowedSignersFile every time while getting commit's signing status
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 10:10:17 +08:00
leo
c2e83778cc
readme: keep the same order for locales
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 09:56:57 +08:00
leo
4a6cbddeac
refactor: select the previous tab while closing the actived one (#621)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 09:53:58 +08:00
leo
b175ab3a3e
code_review: PR #623
* keep locales in order
* update README.md

Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 09:47:33 +08:00
Masgalor
81f76f0771
fix: Make RPM builds compatible with OpenSUSE (#622) 2024-10-30 09:45:41 +08:00
leo
28fad000ab
project: add missing scripts to solution file
Signed-off-by: leo <longshuang@msn.cn>
2024-10-30 09:44:05 +08:00
github-actions[bot]
0474441240 doc: Update translation status and missing keys 2024-10-30 01:43:21 +00:00
jmmanzano
ca5f2f92ba
localization: added es_ES.axaml (#623)
localization: added es_ES.axaml
2024-10-30 09:43:10 +08:00
github-actions[bot]
30e0e84b63 doc: Update translation status and missing keys 2024-10-30 01:33:23 +00:00
AquariusStar
8f68e96607
loacaliztion: update translate (#624) 2024-10-30 09:33:10 +08:00
leo
279b1819a3
feature: show commit gpg sign status (#614)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-29 21:03:45 +08:00
leo
5c92fbdb37
fix: MinWidth not work while manually resizing window (#619)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-29 19:59:22 +08:00
leo
ee20eba047
ux: limit the minimal width/height of resizable panels (#619)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-29 16:51:54 +08:00
github-actions[bot]
acd61f49a8 doc: Update translation status and missing keys 2024-10-29 01:59:40 +00:00
leo
1442dcfe00
feature: allow fetch the latest remote changes into local branch which is not current branch (#617)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-29 09:59:13 +08:00
leo
489b57858f
enhance: improve NumericSort.Compare performance
Signed-off-by: leo <longshuang@msn.cn>
2024-10-29 09:36:26 +08:00
github-actions[bot]
651d313496 doc: Update translation status and missing keys 2024-10-28 13:37:13 +00:00
leo
498d2b54ae
feature: add per-repository setting for prefered OpenAI service
* If there is only one OpenAI service available, discard the setting of prefered OpenAI service. Instead, use it directly
* If there are multiple OpenAI service available, try to find the prefered one or show a context menu for users to choose the one they want to use

Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 21:36:10 +08:00
leo
48725a7937
code_review: PR #612
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 19:42:54 +08:00
ybeapps
a363f67f31
bug: fix int out of bounds for branch names with long numbers (#612) 2024-10-28 19:24:43 +08:00
leo
6c390d2f04
ux: layout of stage page
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 18:06:27 +08:00
leo
6cc0c54ac1
enhance: remember last selection of some options while stashing changes (#610)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 17:55:32 +08:00
leo
1418591b0b
refactor: rewrite command git stash push
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 16:58:53 +08:00
github-actions[bot]
a7cccd5c1d doc: Update translation status and missing keys 2024-10-28 08:52:00 +00:00
leo
566d36ca59
feature: add option to enable --keep-index option of git stash push command (#610)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 16:51:42 +08:00
leo
3e6e0befaa
readme: update macOS usage (#609)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 16:37:57 +08:00
github-actions[bot]
216d2d02bd doc: Update translation status and missing keys 2024-10-28 07:56:57 +00:00
leo
134d69d403
feature: supports generate commit message by OpenAI with selected staged changes (#608)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 15:56:38 +08:00
github-actions[bot]
9d1840f78c doc: Update translation status and missing keys 2024-10-28 03:55:59 +00:00
leo
bb47dc28ef
localization: copy Text.Preference.AI.Name from Text.Name for ru_RU
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 11:55:39 +08:00
github-actions[bot]
f1dc46c251 doc: Update translation status and missing keys 2024-10-28 03:27:59 +00:00
leo
148e2fa1e5
fix: delete wrong key by mistake
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 11:27:38 +08:00
github-actions[bot]
3490d62f3c doc: Update translation status and missing keys 2024-10-28 03:00:34 +00:00
leo
1044915be1
refactor: OpenAI integration
* supports configure multiple services
* supports select service when generate commit message by OpenAI

Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 11:00:11 +08:00
GadflyFang
8280287362
doc: add link on badges (#607)
Signed-off-by: Gadfly <gadfly@gadfly.vip>
2024-10-28 09:45:16 +08:00
leo
ff0354d606
Merge branch 'master' into develop 2024-10-28 09:33:41 +08:00
leo
bb29476a80
Merge branch 'release/v8.36' 2024-10-28 09:33:22 +08:00
leo
9caa20cef0
version: Release 8.36
Signed-off-by: leo <longshuang@msn.cn>
2024-10-28 09:33:10 +08:00
github-actions[bot]
6447590491 doc: Update translation status and missing keys 2024-10-28 01:28:10 +00:00
AquariusStar
bde648eae8
Localization: updating the translation (#606) 2024-10-28 09:27:58 +08:00
leo
a8ae887320
fix: wrong merge command for Meld (#603)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-27 16:56:38 +08:00
github-actions[bot]
34c3dd4df5 doc: Update translation status and missing keys 2024-10-27 08:40:10 +00:00
Chiahong
11bdfcdd79
localization: update zh_TW.axaml (#604) 2024-10-27 16:39:57 +08:00
GadflyFang
28773f0e2d
doc: Make the badges clickable and redirect to the TRANSLATION.md (#601)
* Make the badges clickable and redirect to the TRANSLATION.md
* Move localization check script file position

---------

Signed-off-by: Gadfly <gadfly@gadfly.vip>
2024-10-25 14:51:49 +08:00
github-actions[bot]
7e1624c2d6 doc: Update translation status and missing keys 2024-10-25 06:24:15 +00:00
leo
398b000136
localization: remove unused translations
Signed-off-by: leo <longshuang@msn.cn>
2024-10-25 14:23:53 +08:00
github-actions[bot]
b90a2b05f1 doc: Update translation status and missing keys 2024-10-25 06:22:50 +00:00
GadflyFang
32de28c16e
ci: add Localization Check CI (#600)
Signed-off-by: Gadfly <gadfly@gadfly.vip>
2024-10-25 14:22:38 +08:00
leo
fa4f0a6bd4
ux: move prompt settings to advanced
Signed-off-by: leo <longshuang@msn.cn>
2024-10-25 09:51:51 +08:00
Douglas Cunha
63f75dc589
refactor: improve pt_BR localization clarity and consistency
- Refactor pt_BR localization strings for improved clarity and consistency in UI text across various components.
- Add password masking to the API key input field.
2024-10-24 10:17:35 -03:00
GadflyFang
c08c307c7a
enhance: add GitLab Issue/MR sample rules (#598)
* enhance: add GitLab Issue/MR sample rules
* fix: remove blank in zh_CN

---------

Signed-off-by: Gadfly <gadfly@gadfly.vip>
2024-10-24 18:07:04 +08:00
leo
d3d71af0e8
enhance: only alloc temp buffer once time (#597)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-24 17:07:30 +08:00
leo
339bceef3d
fix: files should be displayed after folders (#597)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-24 17:00:03 +08:00
leo
76a7a2228f
feature: use numeric sorting for all trees (#597)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-24 15:11:10 +08:00
leo
12bb915bd8
code_review: PR #596
- Add `ViewModels.Preference.PrepareOpenAIPrompt()` method to generate default prompt instead of a const fallback value. Therefore, it is more convenient for us to modify the default value in the Preference dialog.
- Modify the default prompts. Rename `SubjectPrompt` to `GenerateSubjectPrompt`. Rename `SummaryPrompt` to `AnalyzeDiffPrompt`.
- Rewrite the way to build OpenAI user content for subject generation

Signed-off-by: leo <longshuang@msn.cn>
2024-10-24 10:22:06 +08:00
Douglas Cunha
2f68aed817
feat: improve commit message generation with AI prompts (#596)
- Refactor the commit message generation process to utilize default prompts and enhance clarity while eliminating redundancy.
- Added new properties for subject and summary prompts, while improving cancellation support in async task handling.
- feat: add AI prompts for commit message generation.
- Updated the formatting of the package reference for consistency in the project file.
- Add properties for managing OpenAI subject and summary prompts in the Preference view model.
- Refactor layout and add new input fields for AI subject and summary prompts in the preferences view.
2024-10-24 09:31:05 +08:00
leo
547c28adb8
fix: locks list does not update after unlock
Signed-off-by: leo <longshuang@msn.cn>
2024-10-23 16:55:22 +08:00
leo
a5594130ed
code_style: run dotnet format
Signed-off-by: leo <longshuang@msn.cn>
2024-10-23 15:28:09 +08:00
leo
d4302b4faa
refactor: render +/- marks after line number
Signed-off-by: leo <longshuang@msn.cn>
2024-10-23 15:19:59 +08:00
Katharina Sternbauer
5707d0b79a
translation: Add missing DE keys, fix misspelling (#594)
- Fix one misspelling where a "c" was missing before a "c" in the work Auschecken
- Add missing DE translations for new feature items
2024-10-23 14:27:22 +08:00
leo
d21a8f2449
refactor: rewrite OpenAI integration
Signed-off-by: leo <longshuang@msn.cn>
2024-10-23 14:05:40 +08:00
leo
f6e1e65a53
feature: add +/- in line number to indicate type of change (#593) 2024-10-23 12:03:22 +08:00
leo
06fd49ba92
feature: support --signoff for git commit command (#591)
Signed-off-by: leo <longshuang@msn.cn>
2024-10-23 09:46:27 +08:00
leo
b9d7f908c9
refactor: do NOT use the --prune parameter for git fetch command (#590) 2024-10-22 16:54:21 +08:00
leo
077e35b860
code_style: allowEmpty is not needed any more 2024-10-22 15:01:20 +08:00
leo
93e964dcb6
readme: add badges 2024-10-22 11:21:07 +08:00
leo
728d003717
code_review: PR #589
* do not using namespace `SourceGit.*`
* should use branch instead of repository
2024-10-22 10:06:53 +08:00
leo
1855b43750
feature: allow empty commit (#587) 2024-10-22 10:03:43 +08:00
Luis Frey
a8a7775b83
feature: add ${branch_name} option to commit templates (#589) 2024-10-22 09:44:53 +08:00
leo
6dac26d525
refactor: since there is a hotkey to stage and commit, remove the unsafe auto-stage configure 2024-10-22 09:29:49 +08:00
leo
31e7bef01d
docs: typo in readme 2024-10-21 20:28:49 +08:00
leo
bb45a5af8e
enhance: use \S instead of \w to supports emoji character 2024-10-21 17:07:56 +08:00
leo
3296f90feb
enhance: only show two chars when they are all ascii letters or digits (#585) 2024-10-21 16:58:15 +08:00
leo
a5e783da08
enhance: disable Fast-Forward for worktree which is not current branch 2024-10-21 16:39:57 +08:00
leo
3b1a54dffd
refactor: use git update-ref $LOCAL_BRANCH $REMOTE_BRANCH instead of git fetch $REMOTE $LOCAL_BRANCH $REMOTE_BRANCH to fast-forward local branch without checkout it first. 2024-10-21 16:20:34 +08:00
leo
00a2ec5abe
enhance: conventional commit message builder supports breaking changes prefix (#584) 2024-10-21 15:47:54 +08:00
Antony David
3804b0a828
fix(histories): handle commits with breaking changes (#584) 2024-10-21 15:41:31 +08:00
Dmitrij D. Czarkoff
bb6ceb03b9
fix: Display all parents even if there are more then 2 (#583) 2024-10-21 15:38:30 +08:00
leo
67b6a6d9d5
refactor: using custom PATH instead of reading it from zsh (#581)
* run `echo $PATH > ~/Library/Application\ Support/SourceGit/PATH` to generate to custom PATH file for SourceGit
2024-10-21 15:31:13 +08:00
leo
188bf02349
Merge branch 'master' into develop 2024-10-21 09:15:22 +08:00
476 changed files with 30453 additions and 10882 deletions

View file

@ -206,6 +206,9 @@ dotnet_diagnostic.CA1854.severity = warning
#CA2211:Non-constant fields should not be visible
dotnet_diagnostic.CA2211.severity = error
# IDE0005: remove used namespace using
dotnet_diagnostic.IDE0005.severity = error
# Wrapping preferences
csharp_wrap_before_ternary_opsigns = false
@ -292,3 +295,12 @@ indent_size = 2
end_of_line = lf
[*.{cmd,bat}]
end_of_line = crlf
# Package manifests
[{*.spec,control}]
end_of_line = lf
# YAML files
[*.{yml,yaml}]
indent_size = 2
end_of_line = lf

2
.gitattributes vendored
View file

@ -3,6 +3,8 @@
*.png binary
*.ico binary
*.sh text eol=lf
*.spec text eol=lf
control text eol=lf
*.bat text eol=crlf
*.cmd text eol=crlf
*.ps1 text eol=crlf

View file

@ -19,20 +19,31 @@ jobs:
os: macos-latest
runtime: osx-arm64
- name : Linux
os: ubuntu-20.04
os: ubuntu-latest
runtime: linux-x64
container: ubuntu:20.04
- name : Linux (arm64)
os: ubuntu-20.04
os: ubuntu-latest
runtime: linux-arm64
container: ubuntu:20.04
name: Build ${{ matrix.name }}
runs-on: ${{ matrix.os }}
container: ${{ matrix.container || '' }}
steps:
- name: Install common CLI tools
if: ${{ startsWith(matrix.runtime, 'linux-') }}
run: |
export DEBIAN_FRONTEND=noninteractive
ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime
apt-get update
apt-get install -y sudo
sudo apt-get install -y curl wget git unzip zip libicu66 tzdata clang
- name: Checkout sources
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
dotnet-version: 9.0.x
- name: Configure arm64 packages
if: ${{ matrix.runtime == 'linux-arm64' }}
run: |
@ -47,7 +58,7 @@ jobs:
if: ${{ matrix.runtime == 'linux-arm64' }}
run: |
sudo apt-get update
sudo apt-get install clang llvm gcc-aarch64-linux-gnu zlib1g-dev:arm64
sudo apt-get install -y llvm gcc-aarch64-linux-gnu
- name: Build
run: dotnet build -c Release
- name: Publish

View file

@ -0,0 +1,41 @@
name: Localization Check
on:
push:
branches: [ develop ]
paths:
- 'src/Resources/Locales/**'
workflow_dispatch:
workflow_call:
jobs:
localization-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Install dependencies
run: npm install fs-extra@11.2.0 path@0.12.7 xml2js@0.6.2
- name: Run localization check
run: node build/scripts/localization-check.js
- name: Commit changes
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
if [ -n "$(git status --porcelain)" ]; then
git add TRANSLATION.md src/Resources/Locales/*.axaml
git commit -m 'doc: Update translation status and sort locale files'
git push
else
echo "No changes to commit"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -3,16 +3,16 @@ on:
workflow_call:
inputs:
version:
description: Source Git package version
description: SourceGit package version
required: true
type: string
jobs:
windows-portable:
name: Package portable Windows app
runs-on: ubuntu-latest
windows:
name: Package Windows
runs-on: windows-2019
strategy:
matrix:
runtime: [win-x64, win-arm64]
runtime: [ win-x64, win-arm64 ]
steps:
- name: Checkout sources
uses: actions/checkout@v4
@ -22,10 +22,11 @@ jobs:
name: sourcegit.${{ matrix.runtime }}
path: build/SourceGit
- name: Package
shell: bash
env:
VERSION: ${{ inputs.version }}
RUNTIME: ${{ matrix.runtime }}
run: ./build/scripts/package.windows-portable.sh
run: ./build/scripts/package.windows.sh
- name: Upload package artifact
uses: actions/upload-artifact@v4
with:
@ -36,7 +37,7 @@ jobs:
with:
name: sourcegit.${{ matrix.runtime }}
osx-app:
name: Package OSX app
name: Package macOS
runs-on: macos-latest
strategy:
matrix:
@ -69,6 +70,7 @@ jobs:
linux:
name: Package Linux
runs-on: ubuntu-latest
container: ubuntu:20.04
strategy:
matrix:
runtime: [linux-x64, linux-arm64]
@ -77,9 +79,10 @@ jobs:
uses: actions/checkout@v4
- name: Download package dependencies
run: |
sudo add-apt-repository universe
sudo apt-get update
sudo apt-get install desktop-file-utils rpm libfuse2
export DEBIAN_FRONTEND=noninteractive
ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime
apt-get update
apt-get install -y curl wget git dpkg-dev fakeroot tzdata zip unzip desktop-file-utils rpm libfuse2 file build-essential binutils
- name: Download build
uses: actions/download-artifact@v4
with:
@ -89,6 +92,7 @@ jobs:
env:
VERSION: ${{ inputs.version }}
RUNTIME: ${{ matrix.runtime }}
APPIMAGE_EXTRACT_AND_RUN: 1
run: |
mkdir build/SourceGit
tar -xf "build/sourcegit.${{ matrix.runtime }}.tar" -C build/SourceGit

View file

@ -38,7 +38,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAG: ${{ github.ref_name }}
VERSION: ${{ needs.version.outputs.version }}
run: gh release create "$TAG" -t "Release $VERSION" --notes-from-tag
run: gh release create "$TAG" -t "$VERSION" --notes-from-tag
- name: Download artifacts
uses: actions/download-artifact@v4
with:

6
.gitignore vendored
View file

@ -23,6 +23,10 @@ ehthumbs_vista.db
bin/
obj/
# ignore ci node files
node_modules/
package.json
package-lock.json
build/resources/
build/SourceGit/
@ -33,3 +37,5 @@ build/*.deb
build/*.rpm
build/*.AppImage
SourceGit.app/
build.command
src/Properties/launchSettings.json

View file

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2024 sourcegit
Copyright (c) 2025 sourcegit
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

120
README.md
View file

@ -1,22 +1,26 @@
# SourceGit
# SourceGit - Opensource Git GUI client.
Opensource Git GUI client.
[![stars](https://img.shields.io/github/stars/sourcegit-scm/sourcegit.svg)](https://github.com/sourcegit-scm/sourcegit/stargazers)
[![forks](https://img.shields.io/github/forks/sourcegit-scm/sourcegit.svg)](https://github.com/sourcegit-scm/sourcegit/forks)
[![license](https://img.shields.io/github/license/sourcegit-scm/sourcegit.svg)](LICENSE)
[![latest](https://img.shields.io/github/v/release/sourcegit-scm/sourcegit.svg)](https://github.com/sourcegit-scm/sourcegit/releases/latest)
[![downloads](https://img.shields.io/github/downloads/sourcegit-scm/sourcegit/total)](https://github.com/sourcegit-scm/sourcegit/releases)
## Highlights
* Supports Windows/macOS/Linux
* Opensource/Free
* Fast
* English/Français/Deutsch/Português/Русский/简体中文/繁體中文
* Deutsch/English/Español/Français/Italiano/Português/Русский/Українська/简体中文/繁體中文/日本語/தமிழ் (Tamil)
* Built-in light/dark themes
* Customize theme
* Visual commit graph
* Supports SSH access with each remote
* GIT commands with GUI
* Clone/Fetch/Pull/Push...
* Merge/Rebase/Reset/Revert/Amend/Cherry-pick...
* Amend/Reword
* Interactive rebase (Basic)
* Merge/Rebase/Reset/Revert/Cherry-pick...
* Amend/Reword/Squash
* Interactive rebase
* Branches
* Remotes
* Tags
@ -31,32 +35,40 @@ Opensource Git GUI client.
* Revision Diffs
* Branch Diff
* Image Diff - Side-By-Side/Swipe/Blend
* Git command logs
* Search commits
* GitFlow
* Git LFS
* Bisect
* Issue Link
* Workspace
* Custom Action
* Using AI to generate commit message (C# port of [anjerodev/commitollama](https://github.com/anjerodev/commitollama))
> [!WARNING]
> **Linux** only tested on **Debian 12** on both **X11** & **Wayland**.
## Translation Status
You can find the current translation status in [TRANSLATION.md](https://github.com/sourcegit-scm/sourcegit/blob/develop/TRANSLATION.md)
## How to Use
**To use this tool, you need to install Git(>=2.23.0) first.**
**To use this tool, you need to install Git(>=2.25.1) first.**
You can download the latest stable from [Releases](https://github.com/sourcegit-scm/sourcegit/releases/latest) or download workflow artifacts from [Github Actions](https://github.com/sourcegit-scm/sourcegit/actions) to try this app based on latest commits.
You can download the latest stable from [Releases](https://github.com/sourcegit-scm/sourcegit/releases/latest) or download workflow artifacts from [GitHub Actions](https://github.com/sourcegit-scm/sourcegit/actions) to try this app based on latest commits.
This software creates a folder `$"{System.Environment.SpecialFolder.ApplicationData}/SourceGit"`, which is platform-dependent, to store user settings, downloaded avatars and crash logs.
| OS | PATH |
|---------|-----------------------------------------------------|
| Windows | `C:\Users\USER_NAME\AppData\Roaming\SourceGit` |
| Windows | `%APPDATA%\SourceGit` |
| Linux | `${HOME}/.config/SourceGit` or `${HOME}/.sourcegit` |
| macOS | `${HOME}/Library/Application Support/SourceGit` |
> [!TIP]
> You can open the app data dir from the main menu.
> * You can open this data storage directory from the main menu `Open Data Storage Directory`.
> * You can create a `data` folder next to the `SourceGit` executable to force this app to store data (user settings, downloaded avatars and crash logs) into it (Portable-Mode). Only works on Windows.
For **Windows** users:
@ -67,60 +79,91 @@ For **Windows** users:
```
> [!NOTE]
> `winget` will install this software as a commandline tool. You need run `SourceGit` from console or `Win+R` at the first time. Then you can add it to the taskbar.
* You can install the latest stable by `scoope` with follow commands:
* You can install the latest stable by `scoop` with follow commands:
```shell
scoop bucket add extras
scoop install sourcegit
```
* Portable versions can be found in [Releases](https://github.com/sourcegit-scm/sourcegit/releases/latest)
* Pre-built binaries can be found in [Releases](https://github.com/sourcegit-scm/sourcegit/releases/latest)
For **macOS** users:
* Download `sourcegit_x.y.osx-x64.zip` or `sourcegit_x.y.osx-arm64.zip` from Releases. `x64` for Intel and `arm64` for Apple Silicon.
* Move `SourceGit.app` to `Applications` folder.
* Make sure your mac trusts all software from anywhere. For more information, search `spctl --master-disable`.
* Thanks [@ybeapps](https://github.com/ybeapps) for making `SourceGit` available on `Homebrew`. You can simply install it with following command:
```shell
brew tap ybeapps/homebrew-sourcegit
brew install --cask --no-quarantine sourcegit
```
* If you want to install `SourceGit.app` from GitHub Release manually, you need run following command to make sure it works:
```shell
sudo xattr -cr /Applications/SourceGit.app
```
* Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your mac.
* You may need to run `sudo xattr -cr /Applications/SourceGit.app` to make sure the software works.
* You can run `echo $PATH > ~/Library/Application\ Support/SourceGit/PATH` to generate a custom PATH env file to introduce `PATH` env to SourceGit.
For **Linux** users:
* `xdg-open` must be installed to support open native file manager.
* Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your linux.
* Thanks [@aikawayataro](https://github.com/aikawayataro) for providing `rpm` and `deb` repositories, hosted on [Codeberg](https://codeberg.org/yataro/-/packages).
`deb` how to:
```shell
curl https://codeberg.org/api/packages/yataro/debian/repository.key | sudo tee /etc/apt/keyrings/sourcegit.asc
echo "deb [signed-by=/etc/apt/keyrings/sourcegit.asc, arch=amd64,arm64] https://codeberg.org/api/packages/yataro/debian generic main" | sudo tee /etc/apt/sources.list.d/sourcegit.list
sudo apt update
sudo apt install sourcegit
```
`rpm` how to:
```shell
curl https://codeberg.org/api/packages/yataro/rpm.repo | sed -e 's/gpgcheck=1/gpgcheck=0/' > sourcegit.repo
# Fedora 41 and newer
sudo dnf config-manager addrepo --from-repofile=./sourcegit.repo
# Fedora 40 and earlier
sudo dnf config-manager --add-repo ./sourcegit.repo
sudo dnf install sourcegit
```
If your distribution isn't using `dnf`, please refer to the documentation of your distribution on how to add an `rpm` repository.
* `AppImage` files can be found on [AppImage hub](https://appimage.github.io/SourceGit/), `xdg-open` (`xdg-utils`) must be installed to support open native file manager.
* Make sure [git-credential-manager](https://github.com/git-ecosystem/git-credential-manager/releases) is installed on your Linux.
* Maybe you need to set environment variable `AVALONIA_SCREEN_SCALE_FACTORS`. See https://github.com/AvaloniaUI/Avalonia/wiki/Configuring-X11-per-monitor-DPI.
* If you can NOT type accented characters, such as `ê`, `ó`, try to set the environment variable `AVALONIA_IM_MODULE` to `none`.
## OpenAI
This software supports using OpenAI or other AI service that has an OpenAI comaptible HTTP API to generate commit message. You need configurate the service in `Preference` window.
This software supports using OpenAI or other AI service that has an OpenAI compatible HTTP API to generate commit message. You need configurate the service in `Preference` window.
For `OpenAI`:
* `Server` must be `https://api.openai.com/v1/chat/completions`
* `Server` must be `https://api.openai.com/v1`
For other AI service:
* The `Server` should fill in a URL equivalent to OpenAI's `https://api.openai.com/v1/chat/completions`. For example, when using `Ollama`, it should be `http://localhost:11434/v1/chat/completions` instead of `http://localhost:11434/api/generate`
* The `Server` should fill in a URL equivalent to OpenAI's `https://api.openai.com/v1`. For example, when using `Ollama`, it should be `http://localhost:11434/v1` instead of `http://localhost:11434/api/generate`
* The `API Key` is optional that depends on the service
## External Tools
This app supports open repository in external tools listed in the table below.
| Tool | Windows | macOS | Linux | KEY IN `external_editors.json` |
|-------------------------------|---------|-------|-------|--------------------------------|
| Visual Studio Code | YES | YES | YES | VSCODE |
| Visual Studio Code - Insiders | YES | YES | YES | VSCODE_INSIDERS |
| VSCodium | YES | YES | YES | VSCODIUM |
| JetBrains Fleet | YES | YES | YES | FLEET |
| Sublime Text | YES | YES | YES | SUBLIME_TEXT |
| Zed | NO | YES | YES | ZED |
| Tool | Windows | macOS | Linux |
|-------------------------------|---------|-------|-------|
| Visual Studio Code | YES | YES | YES |
| Visual Studio Code - Insiders | YES | YES | YES |
| VSCodium | YES | YES | YES |
| Fleet | YES | YES | YES |
| Sublime Text | YES | YES | YES |
| Zed | NO | YES | YES |
| Visual Studio | YES | NO | NO |
> [!NOTE]
> This app will try to find those tools based on some pre-defined or expected locations automatically. If you are using one portable version of these tools, it will not be detected by this app.
> To solve this problem you can add a file named `external_editors.json` in app data dir and provide the path directly. For example:
> To solve this problem you can add a file named `external_editors.json` in app data storage directory and provide the path directly. For example:
```json
{
"tools": {
"VSCODE": "D:\\VSCode\\Code.exe"
"Visual Studio Code": "D:\\VSCode\\Code.exe"
}
}
```
@ -146,6 +189,19 @@ This app supports open repository in external tools listed in the table below.
Everyone is welcome to submit a PR. Please make sure your PR is based on the latest `develop` branch and the target branch of PR is `develop`.
In short, here are the commands to get started once [.NET tools are installed](https://dotnet.microsoft.com/en-us/download):
```sh
dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org
dotnet restore
dotnet build
dotnet run --project src/SourceGit.csproj
```
Thanks to all the people who contribute.
[![Contributors](https://contrib.rocks/image?repo=sourcegit-scm/sourcegit&columns=10)](https://github.com/sourcegit-scm/sourcegit/graphs/contributors)
[![Contributors](https://contrib.rocks/image?repo=sourcegit-scm/sourcegit&columns=20)](https://github.com/sourcegit-scm/sourcegit/graphs/contributors)
## Third-Party Components
For detailed license information, see [THIRD-PARTY-LICENSES.md](THIRD-PARTY-LICENSES.md).

View file

@ -13,9 +13,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{F45A
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{67B6D05F-A000-40BA-ADB4-C9065F880D7B}"
ProjectSection(SolutionItems) = preProject
.github\workflows\build.yml = .github\workflows\build.yml
.github\workflows\ci.yml = .github\workflows\ci.yml
.github\workflows\package.yml = .github\workflows\package.yml
.github\workflows\release.yml = .github\workflows\release.yml
.github\workflows\localization-check.yml = .github\workflows\localization-check.yml
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{49A7C2D6-558C-4FAA-8F5D-EEE81497AED7}"
@ -58,6 +60,8 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DEBIAN", "DEBIAN", "{F101849D-BDB7-40D4-A516-751150C3CCFC}"
ProjectSection(SolutionItems) = preProject
build\resources\deb\DEBIAN\control = build\resources\deb\DEBIAN\control
build\resources\deb\DEBIAN\preinst = build\resources\deb\DEBIAN\preinst
build\resources\deb\DEBIAN\prerm = build\resources\deb\DEBIAN\prerm
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "rpm", "rpm", "{9BA0B044-0CC9-46F8-B551-204F149BF45D}"
@ -75,9 +79,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "appimage", "appimage", "{5D
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{C54D4001-9940-477C-A0B6-E795ED0A3209}"
ProjectSection(SolutionItems) = preProject
build\scripts\localization-check.js = build\scripts\localization-check.js
build\scripts\package.linux.sh = build\scripts\package.linux.sh
build\scripts\package.osx-app.sh = build\scripts\package.osx-app.sh
build\scripts\package.windows-portable.sh = build\scripts\package.windows-portable.sh
build\scripts\package.windows.sh = build\scripts\package.windows.sh
EndProjectSection
EndProject
Global

86
THIRD-PARTY-LICENSES.md Normal file
View file

@ -0,0 +1,86 @@
# Third-Party Licenses
This project incorporates components from the following third parties:
## Packages
### AvaloniaUI
- **Source**: https://github.com/AvaloniaUI/Avalonia
- **Version**: 11.2.5
- **License**: MIT License
- **License Link**: https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md
### AvaloniaEdit
- **Source**: https://github.com/AvaloniaUI/AvaloniaEdit
- **Version**: 11.2.0
- **License**: MIT License
- **License Link**: https://github.com/AvaloniaUI/AvaloniaEdit/blob/master/LICENSE
### LiveChartsCore.SkiaSharpView.Avalonia
- **Source**: https://github.com/beto-rodriguez/LiveCharts2
- **Version**: 2.0.0-rc5.4
- **License**: MIT License
- **License Link**: https://github.com/beto-rodriguez/LiveCharts2/blob/master/LICENSE
### TextMateSharp
- **Source**: https://github.com/danipen/TextMateSharp
- **Version**: 1.0.66
- **License**: MIT License
- **License Link**: https://github.com/danipen/TextMateSharp/blob/master/LICENSE.md
### OpenAI .NET SDK
- **Source**: https://github.com/openai/openai-dotnet
- **Version**: 2.2.0-beta2
- **License**: MIT License
- **License Link**: https://github.com/openai/openai-dotnet/blob/main/LICENSE
### Azure.AI.OpenAI
- **Source**: https://github.com/Azure/azure-sdk-for-net
- **Version**: 2.2.0-beta2
- **License**: MIT License
- **License Link**: https://github.com/Azure/azure-sdk-for-net/blob/main/LICENSE.txt
## Fonts
### JetBrainsMono
- **Source**: https://github.com/JetBrains/JetBrainsMono
- **Commit**: v2.304
- **License**: SIL Open Font License, Version 1.1
- **License Link**: https://github.com/JetBrains/JetBrainsMono/blob/v2.304/OFL.txt
## Grammar Files
### haxe-TmLanguage
- **Source**: https://github.com/vshaxe/haxe-TmLanguage
- **Commit**: ddad8b4c6d0781ac20be0481174ec1be772c5da5
- **License**: MIT License
- **License Link**: https://github.com/vshaxe/haxe-TmLanguage/blob/ddad8b4c6d0781ac20be0481174ec1be772c5da5/LICENSE.md
### coc-toml
- **Source**: https://github.com/kkiyama117/coc-toml
- **Commit**: aac3e0c65955c03314b2733041b19f903b7cc447
- **License**: MIT License
- **License Link**: https://github.com/kkiyama117/coc-toml/blob/aac3e0c65955c03314b2733041b19f903b7cc447/LICENSE
### eclipse-buildship
- **Source**: https://github.com/eclipse/buildship
- **Commit**: 6bb773e7692f913dec27105129ebe388de34e68b
- **License**: Eclipse Public License 1.0
- **License Link**: https://github.com/eclipse-buildship/buildship/blob/6bb773e7692f913dec27105129ebe388de34e68b/README.md
### vscode-jsp-lang
- **Source**: https://github.com/samuel-weinhardt/vscode-jsp-lang
- **Commit**: 0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355
- **License**: MIT License
- **License Link**: https://github.com/samuel-weinhardt/vscode-jsp-lang/blob/0e89ecdb13650dbbe5a1e85b47b2e1530bf2f355/LICENSE

511
TRANSLATION.md Normal file
View file

@ -0,0 +1,511 @@
# Translation Status
This document shows the translation status of each locale file in the repository.
## Details
### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)
### ![de__DE](https://img.shields.io/badge/de__DE-96.14%25-yellow)
<details>
<summary>Missing keys in de_DE.axaml</summary>
- Text.Avatar.Load
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
- Text.CommitDetail.Changes.Count
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Pull.RecurseSubmodules
- Text.Repository.ClearStashes
- Text.Repository.ShowSubmodulesAsTree
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status
- Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited
- Text.Submodule.Status.RevisionChanged
- Text.Submodule.Status.Unmerged
- Text.Submodule.URL
- Text.WorkingCopy.ResetAuthor
</details>
### ![es__ES](https://img.shields.io/badge/es__ES-%E2%88%9A-brightgreen)
### ![fr__FR](https://img.shields.io/badge/fr__FR-92.03%25-yellow)
<details>
<summary>Missing keys in fr_FR.axaml</summary>
- Text.Avatar.Load
- Text.Bisect
- Text.Bisect.Abort
- Text.Bisect.Bad
- Text.Bisect.Detecting
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.ClearStashes
- Text.Repository.Search.ByContent
- Text.Repository.ShowSubmodulesAsTree
- Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status
- Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited
- Text.Submodule.Status.RevisionChanged
- Text.Submodule.Status.Unmerged
- Text.Submodule.URL
- Text.ViewLogs
- Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete
- Text.WorkingCopy.ConfirmCommitWithFilter
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
- Text.WorkingCopy.Conflicts.UseMine
- Text.WorkingCopy.Conflicts.UseTheirs
- Text.WorkingCopy.ResetAuthor
</details>
### ![it__IT](https://img.shields.io/badge/it__IT-97.38%25-yellow)
<details>
<summary>Missing keys in it_IT.axaml</summary>
- Text.Avatar.Load
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
- Text.CommitDetail.Changes.Count
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Pull.RecurseSubmodules
- Text.Repository.ClearStashes
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.WorkingCopy.ResetAuthor
</details>
### ![ja__JP](https://img.shields.io/badge/ja__JP-91.78%25-yellow)
<details>
<summary>Missing keys in ja_JP.axaml</summary>
- Text.Avatar.Load
- Text.Bisect
- Text.Bisect.Abort
- Text.Bisect.Bad
- Text.Bisect.Detecting
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
- Text.BranchCM.CompareWithCurrent
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.ClearStashes
- Text.Repository.FilterCommits
- Text.Repository.Search.ByContent
- Text.Repository.ShowSubmodulesAsTree
- Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status
- Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited
- Text.Submodule.Status.RevisionChanged
- Text.Submodule.Status.Unmerged
- Text.Submodule.URL
- Text.ViewLogs
- Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete
- Text.WorkingCopy.ConfirmCommitWithFilter
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
- Text.WorkingCopy.Conflicts.UseMine
- Text.WorkingCopy.Conflicts.UseTheirs
- Text.WorkingCopy.ResetAuthor
</details>
### ![pt__BR](https://img.shields.io/badge/pt__BR-83.81%25-yellow)
<details>
<summary>Missing keys in pt_BR.axaml</summary>
- Text.AIAssistant.Regen
- Text.AIAssistant.Use
- Text.ApplyStash
- Text.ApplyStash.DropAfterApply
- Text.ApplyStash.RestoreIndex
- Text.ApplyStash.Stash
- Text.Avatar.Load
- Text.Bisect
- Text.Bisect.Abort
- Text.Bisect.Bad
- Text.Bisect.Detecting
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
- Text.BranchCM.CustomAction
- Text.BranchCM.MergeMultiBranches
- Text.BranchCM.ResetToSelectedCommit
- Text.BranchUpstreamInvalid
- Text.Checkout.RecurseSubmodules
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
- Text.Clone.RecurseSubmodules
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
- Text.CommitCM.Merge
- Text.CommitCM.MergeMultiple
- Text.CommitDetail.Changes.Count
- Text.CommitDetail.Files.Search
- Text.CommitDetail.Info.Children
- Text.CommitMessageTextBox.SubjectCount
- Text.Configure.CustomAction.Scope.Branch
- Text.Configure.CustomAction.WaitForExit
- Text.Configure.Git.PreferredMergeMode
- Text.Configure.IssueTracker.AddSampleGiteeIssue
- Text.Configure.IssueTracker.AddSampleGiteePullRequest
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CopyFullPath
- Text.CreateBranch.Name.WarnSpace
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.DeleteRepositoryNode.Path
- Text.DeleteRepositoryNode.TipForGroup
- Text.DeleteRepositoryNode.TipForRepository
- Text.Diff.First
- Text.Diff.Last
- Text.Diff.Submodule.Deleted
- Text.Diff.UseBlockNavigation
- Text.Fetch.Force
- Text.FileCM.ResolveUsing
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.Clone
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.InProgress.CherryPick.Head
- Text.InProgress.Merge.Operating
- Text.InProgress.Rebase.StoppedAt
- Text.InProgress.Revert.Head
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Merge.Source
- Text.MergeMultiple
- Text.MergeMultiple.CommitChanges
- Text.MergeMultiple.Strategy
- Text.MergeMultiple.Targets
- Text.Preferences.AI.Streaming
- Text.Preferences.Appearance.EditorTabWidth
- Text.Preferences.General.DateFormat
- Text.Preferences.General.ShowChildren
- Text.Preferences.General.ShowTagsInGraph
- Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Preferences.Git.SSLVerify
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.ClearStashes
- Text.Repository.FilterCommits
- Text.Repository.HistoriesLayout
- Text.Repository.HistoriesLayout.Horizontal
- Text.Repository.HistoriesLayout.Vertical
- Text.Repository.HistoriesOrder
- Text.Repository.Notifications.Clear
- Text.Repository.OnlyHighlightCurrentBranchInHistories
- Text.Repository.Search.ByContent
- Text.Repository.ShowSubmodulesAsTree
- Text.Repository.Skip
- Text.Repository.Tags.OrderByCreatorDate
- Text.Repository.Tags.OrderByName
- Text.Repository.Tags.Sort
- Text.Repository.UseRelativeTimeInHistories
- Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.SetUpstream
- Text.SetUpstream.Local
- Text.SetUpstream.Unset
- Text.SetUpstream.Upstream
- Text.SHALinkCM.NavigateTo
- Text.Stash.AutoRestore
- Text.Stash.AutoRestore.Tip
- Text.StashCM.SaveAsPatch
- Text.Submodule.Deinit
- Text.Submodule.Status
- Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited
- Text.Submodule.Status.RevisionChanged
- Text.Submodule.Status.Unmerged
- Text.Submodule.URL
- Text.ViewLogs
- Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete
- Text.WorkingCopy.CommitToEdit
- Text.WorkingCopy.ConfirmCommitWithFilter
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
- Text.WorkingCopy.Conflicts.UseMine
- Text.WorkingCopy.Conflicts.UseTheirs
- Text.WorkingCopy.ResetAuthor
- Text.WorkingCopy.SignOff
</details>
### ![ru__RU](https://img.shields.io/badge/ru__RU-99.75%25-yellow)
<details>
<summary>Missing keys in ru_RU.axaml</summary>
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
</details>
### ![ta__IN](https://img.shields.io/badge/ta__IN-91.91%25-yellow)
<details>
<summary>Missing keys in ta_IN.axaml</summary>
- Text.Avatar.Load
- Text.Bisect
- Text.Bisect.Abort
- Text.Bisect.Bad
- Text.Bisect.Detecting
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
- Text.BranchCM.CompareWithCurrent
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount
- Text.Configure.Git.PreferredMergeMode
- Text.ConfirmEmptyCommit.Continue
- Text.ConfirmEmptyCommit.NoLocalChanges
- Text.ConfirmEmptyCommit.StageAllThenCommit
- Text.ConfirmEmptyCommit.WithLocalChanges
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.ClearStashes
- Text.Repository.Search.ByContent
- Text.Repository.ShowSubmodulesAsTree
- Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status
- Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited
- Text.Submodule.Status.RevisionChanged
- Text.Submodule.Status.Unmerged
- Text.Submodule.URL
- Text.UpdateSubmodules.Target
- Text.ViewLogs
- Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete
- Text.WorkingCopy.Conflicts.OpenExternalMergeTool
- Text.WorkingCopy.Conflicts.OpenExternalMergeToolAllConflicts
- Text.WorkingCopy.Conflicts.UseMine
- Text.WorkingCopy.Conflicts.UseTheirs
- Text.WorkingCopy.ResetAuthor
</details>
### ![uk__UA](https://img.shields.io/badge/uk__UA-93.15%25-yellow)
<details>
<summary>Missing keys in uk_UA.axaml</summary>
- Text.Avatar.Load
- Text.Bisect
- Text.Bisect.Abort
- Text.Bisect.Bad
- Text.Bisect.Detecting
- Text.Bisect.Good
- Text.Bisect.Skip
- Text.Bisect.WaitingForRange
- Text.BranchCM.ResetToSelectedCommit
- Text.Checkout.RecurseSubmodules
- Text.Checkout.WithFastForward
- Text.Checkout.WithFastForward.Upstream
- Text.CommitCM.CopyAuthor
- Text.CommitCM.CopyCommitter
- Text.CommitCM.CopySubject
- Text.CommitDetail.Changes.Count
- Text.CommitMessageTextBox.SubjectCount
- Text.ConfigureWorkspace.Name
- Text.CreateBranch.OverwriteExisting
- Text.DeinitSubmodule
- Text.DeinitSubmodule.Force
- Text.DeinitSubmodule.Path
- Text.Diff.Submodule.Deleted
- Text.GitFlow.FinishWithPush
- Text.GitFlow.FinishWithSquash
- Text.Hotkeys.Global.SwitchWorkspace
- Text.Hotkeys.Global.SwitchTab
- Text.Hotkeys.TextEditor.OpenExternalMergeTool
- Text.Launcher.Workspaces
- Text.Launcher.Pages
- Text.Preferences.Git.IgnoreCRAtEOLInDiff
- Text.Pull.RecurseSubmodules
- Text.Repository.BranchSort
- Text.Repository.BranchSort.ByCommitterDate
- Text.Repository.BranchSort.ByName
- Text.Repository.ClearStashes
- Text.Repository.Search.ByContent
- Text.Repository.ShowSubmodulesAsTree
- Text.Repository.ViewLogs
- Text.Repository.Visit
- Text.ResetWithoutCheckout
- Text.ResetWithoutCheckout.MoveTo
- Text.ResetWithoutCheckout.Target
- Text.Submodule.Deinit
- Text.Submodule.Status
- Text.Submodule.Status.Modified
- Text.Submodule.Status.NotInited
- Text.Submodule.Status.RevisionChanged
- Text.Submodule.Status.Unmerged
- Text.Submodule.URL
- Text.ViewLogs
- Text.ViewLogs.Clear
- Text.ViewLogs.CopyLog
- Text.ViewLogs.Delete
- Text.WorkingCopy.ResetAuthor
</details>
### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen)
### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen)

View file

@ -1 +1 @@
8.35
2025.22

View file

@ -5,11 +5,11 @@
## How to build this project manually
1. Make sure [.NET SDK 8](https://dotnet.microsoft.com/en-us/download) is installed on your machine.
1. Make sure [.NET SDK 9](https://dotnet.microsoft.com/en-us/download) is installed on your machine.
2. Clone this project
3. Run the follow command under the project root dir
```sh
dotnet publish -c Release -r $RUNTIME_IDENTIFIER -o $DESTINATION_FOLDER src/SourceGit.csproj
```
> [!NOTE]
> Please replace the `$RUNTIME_IDENTIFIER` with one of `win-x64`,`win-arm64`,`linux-x64`,`linux-arm64`,`osx-x64`,`osx-arm64`, and replece the `$DESTINATION_FOLDER` with the real path that will store the output executable files.
> Please replace the `$RUNTIME_IDENTIFIER` with one of `win-x64`,`win-arm64`,`linux-x64`,`linux-arm64`,`osx-x64`,`osx-arm64`, and replace the `$DESTINATION_FOLDER` with the real path that will store the output executable files.

View file

@ -1,5 +1,5 @@
[Desktop Entry]
Name=Source Git
Name=SourceGit
Comment=Open-source & Free Git GUI Client
Exec=/opt/sourcegit/sourcegit
Icon=/usr/share/icons/sourcegit.png

View file

@ -1,7 +1,8 @@
Package: sourcegit
Version: 8.23
Version: 2025.10
Priority: optional
Depends: libx11-6, libice6, libsm6
Depends: libx11-6, libice6, libsm6, libicu | libicu76 | libicu74 | libicu72 | libicu71 | libicu70 | libicu69 | libicu68 | libicu67 | libicu66 | libicu65 | libicu63 | libicu60 | libicu57 | libicu55 | libicu52, xdg-utils
Architecture: amd64
Installed-Size: 60440
Maintainer: longshuang@msn.cn
Description: Open-source & Free Git GUI Client

View file

@ -0,0 +1,32 @@
#!/bin/sh
set -e
# summary of how this script can be called:
# * <new-preinst> `install'
# * <new-preinst> `install' <old-version>
# * <new-preinst> `upgrade' <old-version>
# * <old-preinst> `abort-upgrade' <new-version>
# for details, see http://www.debian.org/doc/debian-policy/
case "$1" in
install|upgrade)
# Check if SourceGit is running and stop it
if pgrep -f '/opt/sourcegit/sourcegit' > /dev/null; then
echo "Stopping running SourceGit instance..."
pkill -f '/opt/sourcegit/sourcegit' || true
# Give the process a moment to terminate
sleep 1
fi
;;
abort-upgrade)
;;
*)
echo "preinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0

View file

@ -0,0 +1,35 @@
#!/bin/sh
set -e
# summary of how this script can be called:
# * <prerm> `remove'
# * <old-prerm> `upgrade' <new-version>
# * <new-prerm> `failed-upgrade' <old-version>
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
# * <deconfigured's-prerm> `deconfigure' `in-favour'
# <package-being-installed> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
remove|upgrade|deconfigure)
if pgrep -f '/opt/sourcegit/sourcegit' > /dev/null; then
echo "Stopping running SourceGit instance..."
pkill -f '/opt/sourcegit/sourcegit' || true
# Give the process a moment to terminate
sleep 1
fi
;;
failed-upgrade)
;;
*)
echo "prerm called with unknown argument \`$1'" >&2
exit 1
;;
esac
exit 0

View file

@ -5,8 +5,10 @@ Summary: Open-source & Free Git Gui Client
License: MIT
URL: https://sourcegit-scm.github.io/
Source: https://github.com/sourcegit-scm/sourcegit/archive/refs/tags/v%_version.tar.gz
Requires: libX11
Requires: libSM
Requires: libX11.so.6()(%{__isa_bits}bit)
Requires: libSM.so.6()(%{__isa_bits}bit)
Requires: libicu
Requires: xdg-utils
%define _build_id_links none

View file

@ -0,0 +1,83 @@
const fs = require('fs-extra');
const path = require('path');
const xml2js = require('xml2js');
const repoRoot = path.join(__dirname, '../../');
const localesDir = path.join(repoRoot, 'src/Resources/Locales');
const enUSFile = path.join(localesDir, 'en_US.axaml');
const outputFile = path.join(repoRoot, 'TRANSLATION.md');
const parser = new xml2js.Parser();
async function parseXml(filePath) {
const data = await fs.readFile(filePath);
return parser.parseStringPromise(data);
}
async function filterAndSortTranslations(localeData, enUSKeys, enUSData) {
const strings = localeData.ResourceDictionary['x:String'];
// Remove keys that don't exist in English file
const filtered = strings.filter(item => enUSKeys.has(item.$['x:Key']));
// Sort based on the key order in English file
const enUSKeysArray = enUSData.ResourceDictionary['x:String'].map(item => item.$['x:Key']);
filtered.sort((a, b) => {
const aIndex = enUSKeysArray.indexOf(a.$['x:Key']);
const bIndex = enUSKeysArray.indexOf(b.$['x:Key']);
return aIndex - bIndex;
});
return filtered;
}
async function calculateTranslationRate() {
const enUSData = await parseXml(enUSFile);
const enUSKeys = new Set(enUSData.ResourceDictionary['x:String'].map(item => item.$['x:Key']));
const files = (await fs.readdir(localesDir)).filter(file => file !== 'en_US.axaml' && file.endsWith('.axaml'));
const lines = [];
lines.push('# Translation Status');
lines.push('This document shows the translation status of each locale file in the repository.');
lines.push(`## Details`);
lines.push(`### ![en_US](https://img.shields.io/badge/en__US-%E2%88%9A-brightgreen)`);
for (const file of files) {
const locale = file.replace('.axaml', '').replace('_', '__');
const filePath = path.join(localesDir, file);
const localeData = await parseXml(filePath);
const localeKeys = new Set(localeData.ResourceDictionary['x:String'].map(item => item.$['x:Key']));
const missingKeys = [...enUSKeys].filter(key => !localeKeys.has(key));
// Sort and clean up extra translations
const sortedAndCleaned = await filterAndSortTranslations(localeData, enUSKeys, enUSData);
localeData.ResourceDictionary['x:String'] = sortedAndCleaned;
// Save the updated file
const builder = new xml2js.Builder({
headless: true,
renderOpts: { pretty: true, indent: ' ' }
});
let xmlStr = builder.buildObject(localeData);
// Add an empty line before the first x:String
xmlStr = xmlStr.replace(' <x:String', '\n <x:String');
await fs.writeFile(filePath, xmlStr + '\n', 'utf8');
if (missingKeys.length > 0) {
const progress = ((enUSKeys.size - missingKeys.length) / enUSKeys.size) * 100;
const badgeColor = progress >= 75 ? 'yellow' : 'red';
lines.push(`### ![${locale}](https://img.shields.io/badge/${locale}-${progress.toFixed(2)}%25-${badgeColor})`);
lines.push(`<details>\n<summary>Missing keys in ${file}</summary>\n\n${missingKeys.map(key => `- ${key}`).join('\n')}\n\n</details>`)
} else {
lines.push(`### ![${locale}](https://img.shields.io/badge/${locale}-%E2%88%9A-brightgreen)`);
}
}
const content = lines.join('\n\n');
console.log(content);
await fs.writeFile(outputFile, content, 'utf8');
}
calculateTranslationRate().catch(err => console.error(err));

View file

@ -5,16 +5,6 @@ set -o
set -u
set pipefail
if [[ -z "$VERSION" ]]; then
echo "Provide the version as environment variable VERSION"
exit 1
fi
if [[ -z "$RUNTIME" ]]; then
echo "Provide the runtime as environment variable RUNTIME"
exit 1
fi
arch=
appimage_arch=
target=
@ -66,8 +56,15 @@ cp -f SourceGit/* resources/deb/opt/sourcegit
ln -rsf resources/deb/opt/sourcegit/sourcegit resources/deb/usr/bin
cp -r resources/_common/applications resources/deb/usr/share
cp -r resources/_common/icons resources/deb/usr/share
sed -i -e "s/^Version:.*/Version: $VERSION/" -e "s/^Architecture:.*/Architecture: $arch/" resources/deb/DEBIAN/control
dpkg-deb --root-owner-group --build resources/deb "sourcegit_$VERSION-1_$arch.deb"
# Calculate installed size in KB
installed_size=$(du -sk resources/deb | cut -f1)
# Update the control file
sed -i -e "s/^Version:.*/Version: $VERSION/" \
-e "s/^Architecture:.*/Architecture: $arch/" \
-e "s/^Installed-Size:.*/Installed-Size: $installed_size/" \
resources/deb/DEBIAN/control
# Build deb package with gzip compression
dpkg-deb -Zgzip --root-owner-group --build resources/deb "sourcegit_$VERSION-1_$arch.deb"
rpmbuild -bb --target="$target" resources/rpm/SPECS/build.spec --define "_topdir $(pwd)/resources/rpm" --define "_version $VERSION"
mv "resources/rpm/RPMS/$target/sourcegit-$VERSION-1.$target.rpm" ./

View file

@ -5,16 +5,6 @@ set -o
set -u
set pipefail
if [[ -z "$VERSION" ]]; then
echo "Provide the version as environment variable VERSION"
exit 1
fi
if [[ -z "$RUNTIME" ]]; then
echo "Provide the runtime as environment variable RUNTIME"
exit 1
fi
cd build
mkdir -p SourceGit.app/Contents/Resources

View file

@ -1,22 +0,0 @@
#!/usr/bin/env bash
set -e
set -o
set -u
set pipefail
if [[ -z "$VERSION" ]]; then
echo "Provide the version as environment variable VERSION"
exit 1
fi
if [[ -z "$RUNTIME" ]]; then
echo "Provide the runtime as environment variable RUNTIME"
exit 1
fi
cd build
rm -rf SourceGit/*.pdb
zip "sourcegit_$VERSION.$RUNTIME.zip" -r SourceGit

View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -e
set -o
set -u
set pipefail
cd build
rm -rf SourceGit/*.pdb
if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" || "$OSTYPE" == "win32" ]]; then
powershell -Command "Compress-Archive -Path SourceGit -DestinationPath \"sourcegit_$VERSION.$RUNTIME.zip\" -Force"
else
zip "sourcegit_$VERSION.$RUNTIME.zip" -r SourceGit
fi

View file

@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.0",
"version": "9.0.0",
"rollForward": "latestMajor",
"allowPrerelease": false
}

View file

@ -25,12 +25,34 @@ namespace SourceGit
private Action<object> _action = null;
}
public static readonly Command OpenPreferenceCommand = new Command(_ => OpenDialog(new Views.Preference()));
public static readonly Command OpenHotkeysCommand = new Command(_ => OpenDialog(new Views.Hotkeys()));
public static bool IsCheckForUpdateCommandVisible
{
get
{
#if DISABLE_UPDATE_DETECTION
return false;
#else
return true;
#endif
}
}
public static readonly Command OpenPreferencesCommand = new Command(_ => ShowWindow(new Views.Preferences(), false));
public static readonly Command OpenHotkeysCommand = new Command(_ => ShowWindow(new Views.Hotkeys(), false));
public static readonly Command OpenAppDataDirCommand = new Command(_ => Native.OS.OpenInFileManager(Native.OS.DataDir));
public static readonly Command OpenAboutCommand = new Command(_ => OpenDialog(new Views.About()));
public static readonly Command CheckForUpdateCommand = new Command(_ => Check4Update(true));
public static readonly Command OpenAboutCommand = new Command(_ => ShowWindow(new Views.About(), false));
public static readonly Command CheckForUpdateCommand = new Command(_ => (Current as App)?.Check4Update(true));
public static readonly Command QuitCommand = new Command(_ => Quit(0));
public static readonly Command CopyTextBlockCommand = new Command(p => CopyTextBlock(p as TextBlock));
public static readonly Command CopyTextBlockCommand = new Command(p =>
{
var textBlock = p as TextBlock;
if (textBlock == null)
return;
if (textBlock.Inlines is { Count: > 0 } inlines)
CopyText(inlines.Text);
else if (!string.IsNullOrEmpty(textBlock.Text))
CopyText(textBlock.Text);
});
}
}

View file

@ -46,11 +46,9 @@ namespace SourceGit
[JsonSerializable(typeof(Models.ExternalToolPaths))]
[JsonSerializable(typeof(Models.InteractiveRebaseJobCollection))]
[JsonSerializable(typeof(Models.JetBrainsState))]
[JsonSerializable(typeof(Models.OpenAIChatRequest))]
[JsonSerializable(typeof(Models.OpenAIChatResponse))]
[JsonSerializable(typeof(Models.ThemeOverrides))]
[JsonSerializable(typeof(Models.Version))]
[JsonSerializable(typeof(Models.RepositorySettings))]
[JsonSerializable(typeof(ViewModels.Preference))]
[JsonSerializable(typeof(ViewModels.Preferences))]
internal partial class JsonCodeGen : JsonSerializerContext { }
}

View file

@ -14,10 +14,15 @@
<ResourceInclude x:Key="de_DE" Source="/Resources/Locales/de_DE.axaml"/>
<ResourceInclude x:Key="en_US" Source="/Resources/Locales/en_US.axaml"/>
<ResourceInclude x:Key="fr_FR" Source="/Resources/Locales/fr_FR.axaml"/>
<ResourceInclude x:Key="it_IT" Source="/Resources/Locales/it_IT.axaml"/>
<ResourceInclude x:Key="pt_BR" Source="/Resources/Locales/pt_BR.axaml"/>
<ResourceInclude x:Key="uk_UA" Source="/Resources/Locales/uk_UA.axaml"/>
<ResourceInclude x:Key="ru_RU" Source="/Resources/Locales/ru_RU.axaml"/>
<ResourceInclude x:Key="zh_CN" Source="/Resources/Locales/zh_CN.axaml"/>
<ResourceInclude x:Key="zh_TW" Source="/Resources/Locales/zh_TW.axaml"/>
<ResourceInclude x:Key="es_ES" Source="/Resources/Locales/es_ES.axaml"/>
<ResourceInclude x:Key="ja_JP" Source="/Resources/Locales/ja_JP.axaml"/>
<ResourceInclude x:Key="ta_IN" Source="/Resources/Locales/ta_IN.axaml"/>
</ResourceDictionary>
</Application.Resources>
@ -30,10 +35,10 @@
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="{DynamicResource Text.About.Menu}" Command="{x:Static s:App.OpenAboutCommand}"/>
<NativeMenuItem Header="{DynamicResource Text.Hotkeys}" Command="{x:Static s:App.OpenHotkeysCommand}"/>
<NativeMenuItem Header="{DynamicResource Text.SelfUpdate}" Command="{x:Static s:App.CheckForUpdateCommand}"/>
<NativeMenuItem Header="{DynamicResource Text.Hotkeys}" Command="{x:Static s:App.OpenHotkeysCommand}" Gesture="F1"/>
<NativeMenuItem Header="{DynamicResource Text.SelfUpdate}" Command="{x:Static s:App.CheckForUpdateCommand}" IsVisible="{x:Static s:App.IsCheckForUpdateCommandVisible}"/>
<NativeMenuItemSeparator/>
<NativeMenuItem Header="{DynamicResource Text.Preference}" Command="{x:Static s:App.OpenPreferenceCommand}" Gesture="⌘+,"/>
<NativeMenuItem Header="{DynamicResource Text.Preferences}" Command="{x:Static s:App.OpenPreferencesCommand}" Gesture="⌘+,"/>
<NativeMenuItem Header="{DynamicResource Text.OpenAppDataDir}" Command="{x:Static s:App.OpenAppDataDirCommand}"/>
<NativeMenuItemSeparator/>
<NativeMenuItem Header="{DynamicResource Text.Quit}" Command="{x:Static s:App.QuitCommand}" Gesture="⌘+Q"/>

View file

@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Avalonia;
@ -22,6 +25,7 @@ namespace SourceGit
{
public partial class App : Application
{
#region App Entry Point
[STAThread]
public static void Main(string[] args)
{
@ -34,15 +38,14 @@ namespace SourceGit
TaskScheduler.UnobservedTaskException += (_, e) =>
{
LogException(e.Exception);
e.SetObserved();
};
try
{
if (TryLaunchedAsRebaseTodoEditor(args, out int exitTodo))
if (TryLaunchAsRebaseTodoEditor(args, out int exitTodo))
Environment.Exit(exitTodo);
else if (TryLaunchedAsRebaseMessageEditor(args, out int exitMessage))
else if (TryLaunchAsRebaseMessageEditor(args, out int exitMessage))
Environment.Exit(exitMessage);
else
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
@ -59,6 +62,10 @@ namespace SourceGit
builder.UsePlatformDetect();
builder.LogToTrace();
builder.WithInterFont();
builder.With(new FontManagerOptions()
{
DefaultFamilyName = "fonts:Inter#Inter"
});
builder.ConfigureFonts(manager =>
{
var monospace = new EmbeddedFontCollection(
@ -71,38 +78,71 @@ namespace SourceGit
return builder;
}
public override void Initialize()
public static void LogException(Exception ex)
{
AvaloniaXamlLoader.Load(this);
var pref = ViewModels.Preference.Instance;
pref.PropertyChanged += (_, _) => pref.Save();
SetLocale(pref.Locale);
SetTheme(pref.Theme, pref.ThemeOverrides);
SetFonts(pref.DefaultFontFamily, pref.MonospaceFontFamily, pref.OnlyUseMonoFontInEditor);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
BindingPlugins.DataValidators.RemoveAt(0);
if (TryLaunchedAsCoreEditor(desktop))
if (ex == null)
return;
if (TryLaunchedAsAskpass(desktop))
return;
var builder = new StringBuilder();
builder.Append($"Crash::: {ex.GetType().FullName}: {ex.Message}\n\n");
builder.Append("----------------------------\n");
builder.Append($"Version: {Assembly.GetExecutingAssembly().GetName().Version}\n");
builder.Append($"OS: {Environment.OSVersion}\n");
builder.Append($"Framework: {AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName}\n");
builder.Append($"Source: {ex.Source}\n");
builder.Append($"Thread Name: {Thread.CurrentThread.Name ?? "Unnamed"}\n");
builder.Append($"User: {Environment.UserName}\n");
builder.Append($"App Start Time: {Process.GetCurrentProcess().StartTime}\n");
builder.Append($"Exception Time: {DateTime.Now}\n");
builder.Append($"Memory Usage: {Process.GetCurrentProcess().PrivateMemorySize64 / 1024 / 1024} MB\n");
builder.Append($"---------------------------\n\n");
builder.Append(ex);
TryLaunchedAsNormal(desktop);
}
var time = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
var file = Path.Combine(Native.OS.DataDir, $"crash_{time}.log");
File.WriteAllText(file, builder.ToString());
}
#endregion
public static void OpenDialog(Window window)
#region Utility Functions
public static void ShowWindow(object data, bool showAsDialog)
{
var impl = (Views.ChromelessWindow target, bool isDialog) =>
{
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } owner })
window.ShowDialog(owner);
{
if (isDialog)
target.ShowDialog(owner);
else
target.Show(owner);
}
else
{
target.Show();
}
};
if (data is Views.ChromelessWindow window)
{
impl(window, showAsDialog);
return;
}
var dataTypeName = data.GetType().FullName;
if (string.IsNullOrEmpty(dataTypeName) || !dataTypeName.Contains(".ViewModels.", StringComparison.Ordinal))
return;
var viewTypeName = dataTypeName.Replace(".ViewModels.", ".Views.");
var viewType = Type.GetType(viewTypeName);
if (viewType == null || !viewType.IsSubclassOf(typeof(Views.ChromelessWindow)))
return;
window = Activator.CreateInstance(viewType) as Views.ChromelessWindow;
if (window != null)
{
window.DataContext = data;
impl(window, showAsDialog);
}
}
public static void RaiseException(string context, string message)
@ -200,6 +240,9 @@ namespace SourceGit
app._fontsOverrides = null;
}
defaultFont = app.FixFontFamilyName(defaultFont);
monospaceFont = app.FixFontFamilyName(monospaceFont);
var resDic = new ResourceDictionary();
if (!string.IsNullOrEmpty(defaultFont))
resDic.Add("Fonts.Default", new FontFamily(defaultFont));
@ -223,7 +266,7 @@ namespace SourceGit
if (onlyUseMonospaceFontInEditor)
{
if (string.IsNullOrEmpty(defaultFont))
resDic.Add("Fonts.Primary", new FontFamily("fonts:Inter#Inter, $Default"));
resDic.Add("Fonts.Primary", new FontFamily("fonts:Inter#Inter"));
else
resDic.Add("Fonts.Primary", new FontFamily(defaultFont));
}
@ -258,7 +301,7 @@ namespace SourceGit
return await clipboard.GetTextAsync();
}
}
return default;
return null;
}
public static string Text(string key, params object[] args)
@ -280,8 +323,7 @@ namespace SourceGit
icon.Height = 12;
icon.Stretch = Stretch.Uniform;
var geo = Current?.FindResource(key) as StreamGeometry;
if (geo != null)
if (Current?.FindResource(key) is StreamGeometry geo)
icon.Data = geo;
return icon;
@ -295,26 +337,11 @@ namespace SourceGit
return null;
}
public static ViewModels.Launcher GetLauncer()
public static ViewModels.Launcher GetLauncher()
{
return Current is App app ? app._launcher : null;
}
public static ViewModels.Repository FindOpenedRepository(string repoPath)
{
if (Current is App app && app._launcher != null)
{
foreach (var page in app._launcher.Pages)
{
var id = page.Node.Id.Replace("\\", "/");
if (id == repoPath && page.Data is ViewModels.Repository repo)
return repo;
}
}
return null;
}
public static void Quit(int exitCode)
{
if (Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
@ -327,94 +354,68 @@ namespace SourceGit
Environment.Exit(exitCode);
}
}
#endregion
private static void CopyTextBlock(TextBlock textBlock)
#region Overrides
public override void Initialize()
{
if (textBlock == null)
return;
AvaloniaXamlLoader.Load(this);
if (textBlock.Inlines is { Count: > 0 } inlines)
CopyText(inlines.Text);
else if (!string.IsNullOrEmpty(textBlock.Text))
CopyText(textBlock.Text);
var pref = ViewModels.Preferences.Instance;
pref.PropertyChanged += (_, _) => pref.Save();
SetLocale(pref.Locale);
SetTheme(pref.Theme, pref.ThemeOverrides);
SetFonts(pref.DefaultFontFamily, pref.MonospaceFontFamily, pref.OnlyUseMonoFontInEditor);
}
private static void LogException(Exception ex)
public override void OnFrameworkInitializationCompleted()
{
if (ex == null)
return;
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
BindingPlugins.DataValidators.RemoveAt(0);
var builder = new StringBuilder();
builder.Append($"Crash::: {ex.GetType().FullName}: {ex.Message}\n\n");
builder.Append("----------------------------\n");
builder.Append($"Version: {Assembly.GetExecutingAssembly().GetName().Version}\n");
builder.Append($"OS: {Environment.OSVersion.ToString()}\n");
builder.Append($"Framework: {AppDomain.CurrentDomain.SetupInformation.TargetFrameworkName}\n");
builder.Append($"Source: {ex.Source}\n");
builder.Append($"---------------------------\n\n");
builder.Append(ex.StackTrace);
while (ex.InnerException != null)
// Disable tooltip if window is not active.
ToolTip.ToolTipOpeningEvent.AddClassHandler<Control>((c, e) =>
{
ex = ex.InnerException;
builder.Append($"\n\nInnerException::: {ex.GetType().FullName}: {ex.Message}\n");
builder.Append(ex.StackTrace);
}
var time = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
var file = Path.Combine(Native.OS.DataDir, $"crash_{time}.log");
File.WriteAllText(file, builder.ToString());
}
private static void Check4Update(bool manually = false)
{
Task.Run(async () =>
{
try
{
// Fetch lastest release information.
var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) };
var data = await client.GetStringAsync("https://sourcegit-scm.github.io/data/version.json");
// Parse json into Models.Version.
var ver = JsonSerializer.Deserialize(data, JsonCodeGen.Default.Version);
if (ver == null)
return;
// Check if already up-to-date.
if (!ver.IsNewVersion)
{
if (manually)
ShowSelfUpdateResult(new Models.AlreadyUpToDate());
return;
}
// Should not check ignored tag if this is called manually.
if (!manually)
{
var pref = ViewModels.Preference.Instance;
if (ver.TagName == pref.IgnoreUpdateTag)
return;
}
ShowSelfUpdateResult(ver);
}
catch (Exception e)
{
if (manually)
ShowSelfUpdateResult(e);
}
var topLevel = TopLevel.GetTopLevel(c);
if (topLevel is not Window { IsActive: true })
e.Cancel = true;
});
if (TryLaunchAsCoreEditor(desktop))
return;
if (TryLaunchAsAskpass(desktop))
return;
_ipcChannel = new Models.IpcChannel();
if (!_ipcChannel.IsFirstInstance)
{
var arg = desktop.Args is { Length: > 0 } ? desktop.Args[0].Trim() : string.Empty;
if (!string.IsNullOrEmpty(arg))
{
if (arg.StartsWith('"') && arg.EndsWith('"'))
arg = arg.Substring(1, arg.Length - 2).Trim();
if (arg.Length > 0 && !Path.IsPathFullyQualified(arg))
arg = Path.GetFullPath(arg);
}
private static void ShowSelfUpdateResult(object data)
{
Dispatcher.UIThread.Post(() =>
{
OpenDialog(new Views.SelfUpdate() { DataContext = new ViewModels.SelfUpdate() { Data = data } });
});
_ipcChannel.SendToFirstInstance(arg);
Environment.Exit(0);
}
else
{
_ipcChannel.MessageReceived += TryOpenRepository;
desktop.Exit += (_, _) => _ipcChannel.Dispose();
TryLaunchAsNormal(desktop);
}
}
}
#endregion
private static bool TryLaunchedAsRebaseTodoEditor(string[] args, out int exitCode)
private static bool TryLaunchAsRebaseTodoEditor(string[] args, out int exitCode)
{
exitCode = -1;
@ -467,39 +468,57 @@ namespace SourceGit
return true;
}
private static bool TryLaunchedAsRebaseMessageEditor(string[] args, out int exitCode)
private static bool TryLaunchAsRebaseMessageEditor(string[] args, out int exitCode)
{
exitCode = -1;
if (args.Length <= 1 || !args[0].Equals("--rebase-message-editor", StringComparison.Ordinal))
return false;
exitCode = 0;
var file = args[1];
var filename = Path.GetFileName(file);
if (!filename.Equals("COMMIT_EDITMSG", StringComparison.OrdinalIgnoreCase))
return true;
var jobsFile = Path.Combine(Path.GetDirectoryName(file)!, "sourcegit_rebase_jobs.json");
if (!File.Exists(jobsFile))
var gitDir = Path.GetDirectoryName(file)!;
var origHeadFile = Path.Combine(gitDir, "rebase-merge", "orig-head");
var ontoFile = Path.Combine(gitDir, "rebase-merge", "onto");
var doneFile = Path.Combine(gitDir, "rebase-merge", "done");
var jobsFile = Path.Combine(gitDir, "sourcegit_rebase_jobs.json");
if (!File.Exists(ontoFile) || !File.Exists(origHeadFile) || !File.Exists(doneFile) || !File.Exists(jobsFile))
return true;
var origHead = File.ReadAllText(origHeadFile).Trim();
var onto = File.ReadAllText(ontoFile).Trim();
var collection = JsonSerializer.Deserialize(File.ReadAllText(jobsFile), JsonCodeGen.Default.InteractiveRebaseJobCollection);
var doneFile = Path.Combine(Path.GetDirectoryName(file)!, "rebase-merge", "done");
if (!File.Exists(doneFile))
if (!collection.Onto.Equals(onto) || !collection.OrigHead.Equals(origHead))
return true;
var done = File.ReadAllText(doneFile).Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
if (done.Length > collection.Jobs.Count)
var done = File.ReadAllText(doneFile).Trim().Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
if (done.Length == 0)
return true;
var job = collection.Jobs[done.Length - 1];
var current = done[^1].Trim();
var match = REG_REBASE_TODO().Match(current);
if (!match.Success)
return true;
var sha = match.Groups[1].Value;
foreach (var job in collection.Jobs)
{
if (job.SHA.StartsWith(sha))
{
File.WriteAllText(file, job.Message);
break;
}
}
exitCode = 0;
return true;
}
private bool TryLaunchedAsCoreEditor(IClassicDesktopStyleApplicationLifetime desktop)
private bool TryLaunchAsCoreEditor(IClassicDesktopStyleApplicationLifetime desktop)
{
var args = desktop.Args;
if (args == null || args.Length <= 1 || !args[0].Equals("--core-editor", StringComparison.Ordinal))
@ -507,14 +526,18 @@ namespace SourceGit
var file = args[1];
if (!File.Exists(file))
{
desktop.Shutdown(-1);
else
desktop.MainWindow = new Views.StandaloneCommitMessageEditor(file);
return true;
}
private bool TryLaunchedAsAskpass(IClassicDesktopStyleApplicationLifetime desktop)
var editor = new Views.StandaloneCommitMessageEditor();
editor.SetFile(file);
desktop.MainWindow = editor;
return true;
}
private bool TryLaunchAsAskpass(IClassicDesktopStyleApplicationLifetime desktop)
{
var launchAsAskpass = Environment.GetEnvironmentVariable("SOURCEGIT_LAUNCH_AS_ASKPASS");
if (launchAsAskpass is not "TRUE")
@ -523,30 +546,158 @@ namespace SourceGit
var args = desktop.Args;
if (args?.Length > 0)
{
desktop.MainWindow = new Views.Askpass(args[0]);
var askpass = new Views.Askpass();
askpass.TxtDescription.Text = args[0];
desktop.MainWindow = askpass;
return true;
}
return false;
}
private void TryLaunchedAsNormal(IClassicDesktopStyleApplicationLifetime desktop)
private void TryLaunchAsNormal(IClassicDesktopStyleApplicationLifetime desktop)
{
Native.OS.SetupEnternalTools();
Native.OS.SetupExternalTools();
Models.AvatarManager.Instance.Start();
string startupRepo = null;
if (desktop.Args != null && desktop.Args.Length == 1 && Directory.Exists(desktop.Args[0]))
startupRepo = desktop.Args[0];
var pref = ViewModels.Preferences.Instance;
pref.SetCanModify();
_launcher = new ViewModels.Launcher(startupRepo);
desktop.MainWindow = new Views.Launcher() { DataContext = _launcher };
desktop.ShutdownMode = ShutdownMode.OnMainWindowClose;
var pref = ViewModels.Preference.Instance;
#if !DISABLE_UPDATE_DETECTION
if (pref.ShouldCheck4UpdateOnStartup())
Check4Update();
#endif
}
private void TryOpenRepository(string repo)
{
if (!string.IsNullOrEmpty(repo) && Directory.Exists(repo))
{
var test = new Commands.QueryRepositoryRootPath(repo).ReadToEnd();
if (test.IsSuccess && !string.IsNullOrEmpty(test.StdOut))
{
Dispatcher.UIThread.Invoke(() =>
{
var node = ViewModels.Preferences.Instance.FindOrAddNodeByRepositoryPath(test.StdOut.Trim(), null, false);
ViewModels.Welcome.Instance.Refresh();
_launcher?.OpenRepositoryInTab(node, null);
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: Views.Launcher wnd })
wnd.BringToTop();
});
return;
}
}
Dispatcher.UIThread.Invoke(() =>
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: Views.Launcher launcher })
launcher.BringToTop();
});
}
private void Check4Update(bool manually = false)
{
Task.Run(async () =>
{
try
{
// Fetch latest release information.
var client = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) };
var data = await client.GetStringAsync("https://sourcegit-scm.github.io/data/version.json");
// Parse JSON into Models.Version.
var ver = JsonSerializer.Deserialize(data, JsonCodeGen.Default.Version);
if (ver == null)
return;
// Check if already up-to-date.
if (!ver.IsNewVersion)
{
if (manually)
ShowSelfUpdateResult(new Models.AlreadyUpToDate());
return;
}
// Should not check ignored tag if this is called manually.
if (!manually)
{
var pref = ViewModels.Preferences.Instance;
if (ver.TagName == pref.IgnoreUpdateTag)
return;
}
ShowSelfUpdateResult(ver);
}
catch (Exception e)
{
if (manually)
ShowSelfUpdateResult(new Models.SelfUpdateFailed(e));
}
});
}
private void ShowSelfUpdateResult(object data)
{
Dispatcher.UIThread.Post(() =>
{
ShowWindow(new ViewModels.SelfUpdate() { Data = data }, true);
});
}
private string FixFontFamilyName(string input)
{
if (string.IsNullOrEmpty(input))
return string.Empty;
var parts = input.Split(',');
var trimmed = new List<string>();
foreach (var part in parts)
{
var t = part.Trim();
if (string.IsNullOrEmpty(t))
continue;
// Collapse multiple spaces into single space
var prevChar = '\0';
var sb = new StringBuilder();
foreach (var c in t)
{
if (c == ' ' && prevChar == ' ')
continue;
sb.Append(c);
prevChar = c;
}
var name = sb.ToString();
if (name.Contains('#', StringComparison.Ordinal))
{
if (!name.Equals("fonts:Inter#Inter", StringComparison.Ordinal) &&
!name.Equals("fonts:SourceGit#JetBrains Mono", StringComparison.Ordinal))
continue;
}
trimmed.Add(name);
}
return trimmed.Count > 0 ? string.Join(',', trimmed) : string.Empty;
}
[GeneratedRegex(@"^[a-z]+\s+([a-fA-F0-9]{4,40})(\s+.*)?$")]
private static partial Regex REG_REBASE_TODO();
private Models.IpcChannel _ipcChannel = null;
private ViewModels.Launcher _launcher = null;
private ResourceDictionary _activeLocale = null;
private ResourceDictionary _themeOverrides = null;

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embeded controls.
Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="SourceGit.Desktop"/>

View file

@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Add : Command
{
@ -12,20 +9,18 @@ namespace SourceGit.Commands
Args = includeUntracked ? "add ." : "add -u .";
}
public Add(string repo, List<Models.Change> changes)
public Add(string repo, Models.Change change)
{
WorkingDirectory = repo;
Context = repo;
var builder = new StringBuilder();
builder.Append("add --");
foreach (var c in changes)
{
builder.Append(" \"");
builder.Append(c.Path);
builder.Append("\"");
Args = $"add -- \"{change.Path}\"";
}
Args = builder.ToString();
public Add(string repo, string pathspecFromFile)
{
WorkingDirectory = repo;
Context = repo;
Args = $"add --pathspec-from-file=\"{pathspecFromFile}\"";
}
}
}

View file

@ -1,23 +1,12 @@
using System;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Archive : Command
{
public Archive(string repo, string revision, string saveTo, Action<string> outputHandler)
public Archive(string repo, string revision, string saveTo)
{
WorkingDirectory = repo;
Context = repo;
Args = $"archive --format=zip --verbose --output=\"{saveTo}\" {revision}";
TraitErrorAsOutput = true;
_outputHandler = outputHandler;
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private readonly Action<string> _outputHandler;
}
}

View file

@ -1,46 +1,8 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public partial class AssumeUnchanged
public class AssumeUnchanged : Command
{
[GeneratedRegex(@"^(\w)\s+(.+)$")]
private static partial Regex REG_PARSE();
class ViewCommand : Command
{
public ViewCommand(string repo)
{
WorkingDirectory = repo;
Args = "ls-files -v";
RaiseError = false;
}
public List<string> Result()
{
Exec();
return _outs;
}
protected override void OnReadline(string line)
{
var match = REG_PARSE().Match(line);
if (!match.Success)
return;
if (match.Groups[1].Value == "h")
{
_outs.Add(match.Groups[2].Value);
}
}
private readonly List<string> _outs = new List<string>();
}
class ModCommand : Command
{
public ModCommand(string repo, string file, bool bAdd)
public AssumeUnchanged(string repo, string file, bool bAdd)
{
var mode = bAdd ? "--assume-unchanged" : "--no-assume-unchanged";
@ -49,27 +11,4 @@ namespace SourceGit.Commands
Args = $"update-index {mode} -- \"{file}\"";
}
}
public AssumeUnchanged(string repo)
{
_repo = repo;
}
public List<string> View()
{
return new ViewCommand(_repo).Result();
}
public void Add(string file)
{
new ModCommand(_repo, file, true).Exec();
}
public void Remove(string file)
{
new ModCommand(_repo, file, false).Exec();
}
private readonly string _repo;
}
}

13
src/Commands/Bisect.cs Normal file
View file

@ -0,0 +1,13 @@
namespace SourceGit.Commands
{
public class Bisect : Command
{
public Bisect(string repo, string subcmd)
{
WorkingDirectory = repo;
Context = repo;
RaiseError = false;
Args = $"bisect {subcmd}";
}
}
}

View file

@ -21,10 +21,17 @@ namespace SourceGit.Commands
public Models.BlameData Result()
{
var succ = Exec();
if (!succ)
var rs = ReadToEnd();
if (!rs.IsSuccess)
return _result;
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
return new Models.BlameData();
ParseLine(line);
if (_result.IsBinary)
break;
}
if (_needUnifyCommitSHA)
@ -42,14 +49,9 @@ namespace SourceGit.Commands
return _result;
}
protected override void OnReadline(string line)
private void ParseLine(string line)
{
if (_result.IsBinary)
return;
if (string.IsNullOrEmpty(line))
return;
if (line.IndexOf('\0', StringComparison.Ordinal) >= 0)
if (line.Contains('\0', StringComparison.Ordinal))
{
_result.IsBinary = true;
_result.LineInfos.Clear();
@ -65,7 +67,7 @@ namespace SourceGit.Commands
var commit = match.Groups[1].Value;
var author = match.Groups[2].Value;
var timestamp = int.Parse(match.Groups[3].Value);
var when = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime().ToString("yyyy/MM/dd");
var when = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime().ToString(_dateFormat);
var info = new Models.BlameLineInfo()
{
@ -87,6 +89,7 @@ namespace SourceGit.Commands
private readonly Models.BlameData _result = new Models.BlameData();
private readonly StringBuilder _content = new StringBuilder();
private readonly string _dateFormat = Models.DateTimeFormat.Active.DateOnly;
private string _lastSHA = string.Empty;
private bool _needUnifyCommitSHA = false;
private int _minSHALen = 64;

View file

@ -1,30 +1,52 @@
namespace SourceGit.Commands
using System.Text;
namespace SourceGit.Commands
{
public static class Branch
{
public static bool Create(string repo, string name, string basedOn)
public static string ShowCurrent(string repo)
{
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Args = $"branch {name} {basedOn}";
cmd.Args = $"branch --show-current";
return cmd.ReadToEnd().StdOut.Trim();
}
public static bool Create(string repo, string name, string basedOn, bool force, Models.ICommandLog log)
{
var builder = new StringBuilder();
builder.Append("branch ");
if (force)
builder.Append("-f ");
builder.Append(name);
builder.Append(" ");
builder.Append(basedOn);
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Args = builder.ToString();
cmd.Log = log;
return cmd.Exec();
}
public static bool Rename(string repo, string name, string to)
public static bool Rename(string repo, string name, string to, Models.ICommandLog log)
{
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Args = $"branch -M {name} {to}";
cmd.Log = log;
return cmd.Exec();
}
public static bool SetUpstream(string repo, string name, string upstream)
public static bool SetUpstream(string repo, string name, string upstream, Models.ICommandLog log)
{
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Log = log;
if (string.IsNullOrEmpty(upstream))
cmd.Args = $"branch {name} --unset-upstream";
@ -34,22 +56,27 @@
return cmd.Exec();
}
public static bool DeleteLocal(string repo, string name)
public static bool DeleteLocal(string repo, string name, Models.ICommandLog log)
{
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Args = $"branch -D {name}";
cmd.Log = log;
return cmd.Exec();
}
public static bool DeleteRemote(string repo, string remote, string name)
public static bool DeleteRemote(string repo, string remote, string name, Models.ICommandLog log)
{
bool exists = new Remote(repo).HasBranch(remote, name);
if (exists)
return new Push(repo, remote, $"refs/heads/{name}", true) { Log = log }.Exec();
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
cmd.Args = $"push {remote} --delete {name}";
cmd.Args = $"branch -D -r {remote}/{name}";
cmd.Log = log;
return cmd.Exec();
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
@ -12,19 +11,37 @@ namespace SourceGit.Commands
Context = repo;
}
public bool Branch(string branch, Action<string> onProgress)
public bool Branch(string branch, bool force)
{
Args = $"checkout --recurse-submodules --progress {branch}";
TraitErrorAsOutput = true;
_outputHandler = onProgress;
var builder = new StringBuilder();
builder.Append("checkout --progress ");
if (force)
builder.Append("--force ");
builder.Append(branch);
Args = builder.ToString();
return Exec();
}
public bool Branch(string branch, string basedOn, Action<string> onProgress)
public bool Branch(string branch, string basedOn, bool force, bool allowOverwrite)
{
Args = $"checkout --recurse-submodules --progress -b {branch} {basedOn}";
TraitErrorAsOutput = true;
_outputHandler = onProgress;
var builder = new StringBuilder();
builder.Append("checkout --progress ");
if (force)
builder.Append("--force ");
builder.Append(allowOverwrite ? "-B " : "-b ");
builder.Append(branch);
builder.Append(" ");
builder.Append(basedOn);
Args = builder.ToString();
return Exec();
}
public bool Commit(string commitId, bool force)
{
var option = force ? "--force" : string.Empty;
Args = $"checkout {option} --detach --progress {commitId}";
return Exec();
}
@ -61,20 +78,5 @@ namespace SourceGit.Commands
Args = $"checkout --no-overlay {revision} -- \"{file}\"";
return Exec();
}
public bool Commit(string commitId, Action<string> onProgress)
{
Args = $"checkout --detach --progress {commitId}";
TraitErrorAsOutput = true;
_outputHandler = onProgress;
return Exec();
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private Action<string> _outputHandler;
}
}

View file

@ -1,31 +1,12 @@
using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Clean : Command
{
public Clean(string repo, bool includeIgnored)
public Clean(string repo)
{
WorkingDirectory = repo;
Context = repo;
Args = includeIgnored ? "clean -qfdx" : "clean -qfd";
}
public Clean(string repo, List<string> files)
{
var builder = new StringBuilder();
builder.Append("clean -qfd --");
foreach (var f in files)
{
builder.Append(" \"");
builder.Append(f);
builder.Append("\"");
}
WorkingDirectory = repo;
Context = repo;
Args = builder.ToString();
Args = "clean -qfdx";
}
}
}

View file

@ -1,18 +1,13 @@
using System;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Clone : Command
{
private readonly Action<string> _notifyProgress;
public Clone(string ctx, string path, string url, string localName, string sshKey, string extraArgs, Action<string> ouputHandler)
public Clone(string ctx, string path, string url, string localName, string sshKey, string extraArgs)
{
Context = ctx;
WorkingDirectory = path;
TraitErrorAsOutput = true;
SSHKey = sshKey;
Args = "clone --progress --verbose --recurse-submodules ";
Args = "clone --progress --verbose ";
if (!string.IsNullOrEmpty(extraArgs))
Args += $"{extraArgs} ";
@ -21,13 +16,6 @@ namespace SourceGit.Commands
if (!string.IsNullOrEmpty(localName))
Args += localName;
_notifyProgress = ouputHandler;
}
protected override void OnReadline(string line)
{
_notifyProgress?.Invoke(line);
}
}
}

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Avalonia.Threading;
@ -10,11 +11,6 @@ namespace SourceGit.Commands
{
public partial class Command
{
public class CancelToken
{
public bool Requested { get; set; } = false;
}
public class ReadToEndResult
{
public bool IsSuccess { get; set; } = false;
@ -30,81 +26,51 @@ namespace SourceGit.Commands
}
public string Context { get; set; } = string.Empty;
public CancelToken Cancel { get; set; } = null;
public CancellationToken CancellationToken { get; set; } = CancellationToken.None;
public string WorkingDirectory { get; set; } = null;
public EditorType Editor { get; set; } = EditorType.CoreEditor; // Only used in Exec() mode
public string SSHKey { get; set; } = string.Empty;
public string Args { get; set; } = string.Empty;
public bool RaiseError { get; set; } = true;
public bool TraitErrorAsOutput { get; set; } = false;
public Models.ICommandLog Log { get; set; } = null;
public bool Exec()
{
Log?.AppendLine($"$ git {Args}\n");
var start = CreateGitStartInfo();
var errs = new List<string>();
var proc = new Process() { StartInfo = start };
var isCancelled = false;
proc.OutputDataReceived += (_, e) =>
{
if (Cancel != null && Cancel.Requested)
{
isCancelled = true;
proc.CancelErrorRead();
proc.CancelOutputRead();
if (!proc.HasExited)
proc.Kill(true);
return;
}
if (e.Data != null)
OnReadline(e.Data);
};
proc.ErrorDataReceived += (_, e) =>
{
if (Cancel != null && Cancel.Requested)
{
isCancelled = true;
proc.CancelErrorRead();
proc.CancelOutputRead();
if (!proc.HasExited)
proc.Kill(true);
return;
}
if (string.IsNullOrEmpty(e.Data))
return;
if (TraitErrorAsOutput)
OnReadline(e.Data);
// Ignore progress messages
if (e.Data.StartsWith("remote: Enumerating objects:", StringComparison.Ordinal))
return;
if (e.Data.StartsWith("remote: Counting objects:", StringComparison.Ordinal))
return;
if (e.Data.StartsWith("remote: Compressing objects:", StringComparison.Ordinal))
return;
if (e.Data.StartsWith("Filtering content:", StringComparison.Ordinal))
return;
if (REG_PROGRESS().IsMatch(e.Data))
return;
errs.Add(e.Data);
};
proc.OutputDataReceived += (_, e) => HandleOutput(e.Data, errs);
proc.ErrorDataReceived += (_, e) => HandleOutput(e.Data, errs);
var dummy = null as Process;
var dummyProcLock = new object();
try
{
proc.Start();
// It not safe, please only use `CancellationToken` in readonly commands.
if (CancellationToken.CanBeCanceled)
{
dummy = proc;
CancellationToken.Register(() =>
{
lock (dummyProcLock)
{
if (dummy is { HasExited: false })
dummy.Kill();
}
});
}
}
catch (Exception e)
{
if (RaiseError)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(Context, e.Message);
});
}
Dispatcher.UIThread.Post(() => App.RaiseException(Context, e.Message));
Log?.AppendLine(string.Empty);
return false;
}
@ -112,18 +78,27 @@ namespace SourceGit.Commands
proc.BeginErrorReadLine();
proc.WaitForExit();
if (dummy != null)
{
lock (dummyProcLock)
{
dummy = null;
}
}
int exitCode = proc.ExitCode;
proc.Close();
Log?.AppendLine(string.Empty);
if (!isCancelled && exitCode != 0 && errs.Count > 0)
if (!CancellationToken.IsCancellationRequested && exitCode != 0)
{
if (RaiseError)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(Context, string.Join("\n", errs));
});
var errMsg = string.Join("\n", errs).Trim();
if (!string.IsNullOrEmpty(errMsg))
Dispatcher.UIThread.Post(() => App.RaiseException(Context, errMsg));
}
return false;
}
@ -162,11 +137,6 @@ namespace SourceGit.Commands
return rs;
}
protected virtual void OnReadline(string line)
{
// Implemented by derived class
}
private ProcessStartInfo CreateGitStartInfo()
{
var start = new ProcessStartInfo();
@ -191,9 +161,12 @@ namespace SourceGit.Commands
if (!start.Environment.ContainsKey("GIT_SSH_COMMAND") && !string.IsNullOrEmpty(SSHKey))
start.Environment.Add("GIT_SSH_COMMAND", $"ssh -i '{SSHKey}'");
// Force using en_US.UTF-8 locale to avoid GCM crash
// Force using en_US.UTF-8 locale
if (OperatingSystem.IsLinux())
start.Environment.Add("LANG", "en_US.UTF-8");
{
start.Environment.Add("LANG", "C");
start.Environment.Add("LC_ALL", "C");
}
// Force using this app as git editor.
switch (Editor)
@ -219,6 +192,28 @@ namespace SourceGit.Commands
return start;
}
private void HandleOutput(string line, List<string> errs)
{
line ??= string.Empty;
Log?.AppendLine(line);
// Lines to hide in error message.
if (line.Length > 0)
{
if (line.StartsWith("remote: Enumerating objects:", StringComparison.Ordinal) ||
line.StartsWith("remote: Counting objects:", StringComparison.Ordinal) ||
line.StartsWith("remote: Compressing objects:", StringComparison.Ordinal) ||
line.StartsWith("Filtering content:", StringComparison.Ordinal) ||
line.StartsWith("hint:", StringComparison.Ordinal))
return;
if (REG_PROGRESS().IsMatch(line))
return;
}
errs.Add(line);
}
[GeneratedRegex(@"\d+%")]
private static partial Regex REG_PROGRESS();
}

View file

@ -4,19 +4,36 @@ namespace SourceGit.Commands
{
public class Commit : Command
{
public Commit(string repo, string message, bool amend, bool allowEmpty = false)
public Commit(string repo, string message, bool signOff, bool amend, bool resetAuthor)
{
var file = Path.GetTempFileName();
File.WriteAllText(file, message);
_tmpFile = Path.GetTempFileName();
File.WriteAllText(_tmpFile, message);
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
Args = $"commit --file=\"{file}\"";
Args = $"commit --allow-empty --file=\"{_tmpFile}\"";
if (signOff)
Args += " --signoff";
if (amend)
Args += " --amend --no-edit";
if (allowEmpty)
Args += " --allow-empty";
Args += resetAuthor ? " --amend --reset-author --no-edit" : " --amend --no-edit";
}
public bool Run()
{
var succ = Exec();
try
{
File.Delete(_tmpFile);
}
catch
{
// Ignore
}
return succ;
}
private readonly string _tmpFile;
}
}

View file

@ -6,8 +6,10 @@ namespace SourceGit.Commands
{
public partial class CompareRevisions : Command
{
[GeneratedRegex(@"^(\s?[\w\?]{1,4})\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)
{
@ -18,18 +20,44 @@ namespace SourceGit.Commands
Args = $"diff --name-status {based} {end}";
}
public CompareRevisions(string repo, string start, string end, string path)
{
WorkingDirectory = repo;
Context = repo;
var based = string.IsNullOrEmpty(start) ? "-R" : start;
Args = $"diff --name-status {based} {end} -- \"{path}\"";
}
public List<Models.Change> Result()
{
Exec();
_changes.Sort((l, r) => string.Compare(l.Path, r.Path, StringComparison.Ordinal));
var rs = ReadToEnd();
if (!rs.IsSuccess)
return _changes;
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
ParseLine(line);
_changes.Sort((l, r) => Models.NumericSort.Compare(l.Path, r.Path));
return _changes;
}
protected override void OnReadline(string line)
private void ParseLine(string line)
{
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;
@ -48,10 +76,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);

View file

@ -29,7 +29,7 @@ namespace SourceGit.Commands
var rs = new Dictionary<string, string>();
if (output.IsSuccess)
{
var lines = output.StdOut.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
var lines = output.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var idx = line.IndexOf('=', StringComparison.Ordinal);

View file

@ -8,7 +8,7 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = "status -uno --ignore-submodules=dirty --porcelain";
Args = "--no-optional-locks status -uno --ignore-submodules=all --porcelain";
}
public int Result()
@ -16,7 +16,7 @@ namespace SourceGit.Commands
var rs = ReadToEnd();
if (rs.IsSuccess)
{
var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries);
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
return lines.Length;
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
@ -8,6 +8,10 @@ namespace SourceGit.Commands
{
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
private static partial Regex REG_INDICATOR();
[GeneratedRegex(@"^index\s([0-9a-f]{6,40})\.\.([0-9a-f]{6,40})(\s[1-9]{6})?")]
private static partial Regex REG_HASH_CHANGE();
private const string PREFIX_LFS_NEW = "+version https://git-lfs.github.com/spec/";
private const string PREFIX_LFS_DEL = "-version https://git-lfs.github.com/spec/";
private const string PREFIX_LFS_MODIFY = " version https://git-lfs.github.com/spec/";
@ -24,34 +28,48 @@ namespace SourceGit.Commands
Context = repo;
if (ignoreWhitespace)
Args = $"diff --patch --ignore-cr-at-eol --ignore-all-space --unified={unified} {opt}";
Args = $"diff --no-ext-diff --patch --ignore-all-space --unified={unified} {opt}";
else if (Models.DiffOption.IgnoreCRAtEOL)
Args = $"diff --no-ext-diff --patch --ignore-cr-at-eol --unified={unified} {opt}";
else
Args = $"diff --patch --ignore-cr-at-eol --unified={unified} {opt}";
Args = $"diff --no-ext-diff --patch --unified={unified} {opt}";
}
public Models.DiffResult Result()
{
Exec();
var rs = ReadToEnd();
var start = 0;
var end = rs.StdOut.IndexOf('\n', start);
while (end > 0)
{
var line = rs.StdOut.Substring(start, end - start);
ParseLine(line);
if (_result.IsBinary || _result.IsLFS)
start = end + 1;
end = rs.StdOut.IndexOf('\n', start);
}
if (start < rs.StdOut.Length)
ParseLine(rs.StdOut.Substring(start));
if (_result.IsBinary || _result.IsLFS || _result.TextDiff.Lines.Count == 0)
{
_result.TextDiff = null;
}
else
{
ProcessInlineHighlights();
if (_result.TextDiff.Lines.Count == 0)
_result.TextDiff = null;
else
_result.TextDiff.MaxLineNumber = Math.Max(_newLine, _oldLine);
}
return _result;
}
protected override void OnReadline(string line)
private void ParseLine(string line)
{
if (_result.IsBinary)
return;
if (line.StartsWith("old mode ", StringComparison.Ordinal))
{
_result.OldMode = line.Substring(9);
@ -64,8 +82,17 @@ namespace SourceGit.Commands
return;
}
if (_result.IsBinary)
if (line.StartsWith("deleted file mode ", StringComparison.Ordinal))
{
_result.OldMode = line.Substring(18);
return;
}
if (line.StartsWith("new file mode ", StringComparison.Ordinal))
{
_result.NewMode = line.Substring(14);
return;
}
if (_result.IsLFS)
{
@ -78,7 +105,7 @@ namespace SourceGit.Commands
}
else if (line.StartsWith("-size ", StringComparison.Ordinal))
{
_result.LFSDiff.Old.Size = long.Parse(line.Substring(6));
_result.LFSDiff.Old.Size = long.Parse(line.AsSpan(6));
}
}
else if (ch == '+')
@ -89,36 +116,52 @@ namespace SourceGit.Commands
}
else if (line.StartsWith("+size ", StringComparison.Ordinal))
{
_result.LFSDiff.New.Size = long.Parse(line.Substring(6));
_result.LFSDiff.New.Size = long.Parse(line.AsSpan(6));
}
}
else if (line.StartsWith(" size ", StringComparison.Ordinal))
{
_result.LFSDiff.New.Size = _result.LFSDiff.Old.Size = long.Parse(line.Substring(6));
_result.LFSDiff.New.Size = _result.LFSDiff.Old.Size = long.Parse(line.AsSpan(6));
}
return;
}
if (_result.TextDiff.Lines.Count == 0)
{
var match = REG_INDICATOR().Match(line);
if (!match.Success)
{
if (line.StartsWith("Binary", StringComparison.Ordinal))
{
_result.IsBinary = true;
return;
}
if (string.IsNullOrEmpty(_result.OldHash))
{
var match = REG_HASH_CHANGE().Match(line);
if (!match.Success)
return;
_result.OldHash = match.Groups[1].Value;
_result.NewHash = match.Groups[2].Value;
}
else
{
var match = REG_INDICATOR().Match(line);
if (!match.Success)
return;
_oldLine = int.Parse(match.Groups[1].Value);
_newLine = int.Parse(match.Groups[2].Value);
_result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0));
_last = new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0);
_result.TextDiff.Lines.Add(_last);
}
}
else
{
if (line.Length == 0)
{
ProcessInlineHighlights();
_result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Normal, "", _oldLine, _newLine));
_last = new Models.TextDiffLine(Models.TextDiffLineType.Normal, "", _oldLine, _newLine);
_result.TextDiff.Lines.Add(_last);
_oldLine++;
_newLine++;
return;
@ -134,7 +177,8 @@ namespace SourceGit.Commands
return;
}
_deleted.Add(new Models.TextDiffLine(Models.TextDiffLineType.Deleted, line.Substring(1), _oldLine, 0));
_last = new Models.TextDiffLine(Models.TextDiffLineType.Deleted, line.Substring(1), _oldLine, 0);
_deleted.Add(_last);
_oldLine++;
}
else if (ch == '+')
@ -146,7 +190,8 @@ namespace SourceGit.Commands
return;
}
_added.Add(new Models.TextDiffLine(Models.TextDiffLineType.Added, line.Substring(1), 0, _newLine));
_last = new Models.TextDiffLine(Models.TextDiffLineType.Added, line.Substring(1), 0, _newLine);
_added.Add(_last);
_newLine++;
}
else if (ch != '\\')
@ -157,7 +202,8 @@ namespace SourceGit.Commands
{
_oldLine = int.Parse(match.Groups[1].Value);
_newLine = int.Parse(match.Groups[2].Value);
_result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0));
_last = new Models.TextDiffLine(Models.TextDiffLineType.Indicator, line, 0, 0);
_result.TextDiff.Lines.Add(_last);
}
else
{
@ -168,11 +214,16 @@ namespace SourceGit.Commands
return;
}
_result.TextDiff.Lines.Add(new Models.TextDiffLine(Models.TextDiffLineType.Normal, line.Substring(1), _oldLine, _newLine));
_last = new Models.TextDiffLine(Models.TextDiffLineType.Normal, line.Substring(1), _oldLine, _newLine);
_result.TextDiff.Lines.Add(_last);
_oldLine++;
_newLine++;
}
}
else if (line.Equals("\\ No newline at end of file", StringComparison.Ordinal))
{
_last.NoNewLineEndOfFile = true;
}
}
}
@ -223,6 +274,7 @@ namespace SourceGit.Commands
private readonly Models.DiffResult _result = new Models.DiffResult();
private readonly List<Models.TextDiffLine> _deleted = new List<Models.TextDiffLine>();
private readonly List<Models.TextDiffLine> _added = new List<Models.TextDiffLine>();
private Models.TextDiffLine _last = null;
private int _oldLine = 0;
private int _newLine = 0;
}

View file

@ -1,39 +1,95 @@
using System;
using System.Collections.Generic;
using System.IO;
using Avalonia.Threading;
namespace SourceGit.Commands
{
public static class Discard
{
public static void All(string repo, bool includeIgnored)
/// <summary>
/// Discard all local changes (unstaged & staged)
/// </summary>
/// <param name="repo"></param>
/// <param name="includeIgnored"></param>
/// <param name="log"></param>
public static void All(string repo, bool includeIgnored, Models.ICommandLog log)
{
new Restore(repo).Exec();
new Clean(repo, includeIgnored).Exec();
var changes = new QueryLocalChanges(repo).Result();
try
{
foreach (var c in changes)
{
if (c.WorkTree == Models.ChangeState.Untracked ||
c.WorkTree == Models.ChangeState.Added ||
c.Index == Models.ChangeState.Added ||
c.Index == Models.ChangeState.Renamed)
{
var fullPath = Path.Combine(repo, c.Path);
if (Directory.Exists(fullPath))
Directory.Delete(fullPath, true);
else
File.Delete(fullPath);
}
}
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(repo, $"Failed to discard changes. Reason: {e.Message}");
});
}
public static void Changes(string repo, List<Models.Change> changes)
{
var needClean = new List<string>();
var needCheckout = new List<string>();
new Reset(repo, "HEAD", "--hard") { Log = log }.Exec();
if (includeIgnored)
new Clean(repo) { Log = log }.Exec();
}
/// <summary>
/// Discard selected changes (only unstaged).
/// </summary>
/// <param name="repo"></param>
/// <param name="changes"></param>
/// <param name="log"></param>
public static void Changes(string repo, List<Models.Change> changes, Models.ICommandLog log)
{
var restores = new List<string>();
try
{
foreach (var c in changes)
{
if (c.WorkTree == Models.ChangeState.Untracked || c.WorkTree == Models.ChangeState.Added)
needClean.Add(c.Path);
{
var fullPath = Path.Combine(repo, c.Path);
if (Directory.Exists(fullPath))
Directory.Delete(fullPath, true);
else
needCheckout.Add(c.Path);
File.Delete(fullPath);
}
else
{
restores.Add(c.Path);
}
}
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() =>
{
App.RaiseException(repo, $"Failed to discard changes. Reason: {e.Message}");
});
}
for (int i = 0; i < needClean.Count; i += 10)
if (restores.Count > 0)
{
var count = Math.Min(10, needClean.Count - i);
new Clean(repo, needClean.GetRange(i, count)).Exec();
}
for (int i = 0; i < needCheckout.Count; i += 10)
{
var count = Math.Min(10, needCheckout.Count - i);
new Restore(repo, needCheckout.GetRange(i, count), "--worktree --recurse-submodules").Exec();
var pathSpecFile = Path.GetTempFileName();
File.WriteAllLines(pathSpecFile, restores);
new Restore(repo, pathSpecFile, false) { Log = log }.Exec();
File.Delete(pathSpecFile);
}
}
}

View file

@ -0,0 +1,86 @@
using System;
using System.Diagnostics;
using System.Text;
using Avalonia.Threading;
namespace SourceGit.Commands
{
public static class ExecuteCustomAction
{
public static void Run(string repo, string file, string args)
{
var start = new ProcessStartInfo();
start.FileName = file;
start.Arguments = args;
start.UseShellExecute = false;
start.CreateNoWindow = true;
start.WorkingDirectory = repo;
try
{
Process.Start(start);
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, e.Message));
}
}
public static void RunAndWait(string repo, string file, string args, Models.ICommandLog log)
{
var start = new ProcessStartInfo();
start.FileName = file;
start.Arguments = args;
start.UseShellExecute = false;
start.CreateNoWindow = true;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.StandardOutputEncoding = Encoding.UTF8;
start.StandardErrorEncoding = Encoding.UTF8;
start.WorkingDirectory = repo;
log?.AppendLine($"$ {file} {args}\n");
var proc = new Process() { StartInfo = start };
var builder = new StringBuilder();
proc.OutputDataReceived += (_, e) =>
{
if (e.Data != null)
log?.AppendLine(e.Data);
};
proc.ErrorDataReceived += (_, e) =>
{
if (e.Data != null)
{
log?.AppendLine(e.Data);
builder.AppendLine(e.Data);
}
};
try
{
proc.Start();
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
proc.WaitForExit();
var exitCode = proc.ExitCode;
if (exitCode != 0)
{
var errMsg = builder.ToString().Trim();
if (!string.IsNullOrEmpty(errMsg))
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, errMsg));
}
}
catch (Exception e)
{
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, e.Message));
}
proc.Close();
}
}
}

View file

@ -1,44 +1,31 @@
using System;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Fetch : Command
{
public Fetch(string repo, string remote, bool prune, bool noTags, Action<string> outputHandler)
public Fetch(string repo, string remote, bool noTags, bool force)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
Args = "fetch --progress --verbose ";
if (prune)
Args += "--prune ";
if (noTags)
Args += "--no-tags ";
else
Args += "--tags ";
if (force)
Args += "--force ";
Args += remote;
}
public Fetch(string repo, string remote, string localBranch, string remoteBranch, Action<string> outputHandler)
public Fetch(string repo, Models.Branch local, Models.Branch remote)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
Args = $"fetch --progress --verbose {remote} {remoteBranch}:{localBranch}";
SSHKey = new Config(repo).Get($"remote.{remote.Remote}.sshkey");
Args = $"fetch --progress --verbose {remote.Remote} {remote.Name}:{local.Name}";
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private readonly Action<string> _outputHandler;
}
}

View file

@ -6,7 +6,8 @@
{
WorkingDirectory = repo;
Context = repo;
Args = $"format-patch {commit} -1 -o \"{saveTo}\"";
Editor = EditorType.None;
Args = $"format-patch {commit} -1 --output=\"{saveTo}\"";
}
}
}

View file

@ -1,23 +1,12 @@
using System;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class GC : Command
{
public GC(string repo, Action<string> outputHandler)
public GC(string repo)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
Args = "gc --prune=now";
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private readonly Action<string> _outputHandler;
}
}

View file

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Text;
using System.Threading;
using Avalonia.Threading;
namespace SourceGit.Commands
{
/// <summary>
@ -20,100 +22,78 @@ namespace SourceGit.Commands
}
}
public GenerateCommitMessage(string repo, List<Models.Change> changes, CancellationToken cancelToken, Action<string> onProgress)
public GenerateCommitMessage(Models.OpenAIService service, string repo, List<Models.Change> changes, CancellationToken cancelToken, Action<string> onResponse)
{
_service = service;
_repo = repo;
_changes = changes;
_cancelToken = cancelToken;
_onProgress = onProgress;
_onResponse = onResponse;
}
public string Result()
public void Exec()
{
try
{
var summaries = new List<string>();
_onResponse?.Invoke("Waiting for pre-file analyzing to completed...\n\n");
var responseBuilder = new StringBuilder();
var summaryBuilder = new StringBuilder();
foreach (var change in _changes)
{
if (_cancelToken.IsCancellationRequested)
return "";
return;
_onProgress?.Invoke($"Analyzing {change.Path}...");
var summary = GenerateChangeSummary(change);
summaries.Add(summary);
responseBuilder.Append("- ");
summaryBuilder.Append("- ");
var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd();
if (rs.IsSuccess)
{
_service.Chat(
_service.AnalyzeDiffPrompt,
$"Here is the `git diff` output: {rs.StdOut}",
_cancelToken,
update =>
{
responseBuilder.Append(update);
summaryBuilder.Append(update);
_onResponse?.Invoke($"Waiting for pre-file analyzing to completed...\n\n{responseBuilder}");
});
}
responseBuilder.Append("\n");
summaryBuilder.Append("(file: ");
summaryBuilder.Append(change.Path);
summaryBuilder.Append(")\n");
}
if (_cancelToken.IsCancellationRequested)
return "";
return;
_onProgress?.Invoke($"Generating commit message...");
var builder = new StringBuilder();
builder.Append(GenerateSubject(string.Join("", summaries)));
builder.Append("\n");
foreach (var summary in summaries)
var responseBody = responseBuilder.ToString();
var subjectBuilder = new StringBuilder();
_service.Chat(
_service.GenerateSubjectPrompt,
$"Here are the summaries changes:\n{summaryBuilder}",
_cancelToken,
update =>
{
builder.Append("\n- ");
builder.Append(summary.Trim());
}
return builder.ToString();
subjectBuilder.Append(update);
_onResponse?.Invoke($"{subjectBuilder}\n\n{responseBody}");
});
}
catch (Exception e)
{
App.RaiseException(_repo, $"Failed to generate commit message: {e}");
return "";
Dispatcher.UIThread.Post(() => App.RaiseException(_repo, $"Failed to generate commit message: {e}"));
}
}
private string GenerateChangeSummary(Models.Change change)
{
var rs = new GetDiffContent(_repo, new Models.DiffOption(change, false)).ReadToEnd();
var diff = rs.IsSuccess ? rs.StdOut : "unknown change";
var prompt = new StringBuilder();
prompt.AppendLine("You are an expert developer specialist in creating commits.");
prompt.AppendLine("Provide a super concise one sentence overall changes summary of the user `git diff` output following strictly the next rules:");
prompt.AppendLine("- Do not use any code snippets, imports, file routes or bullets points.");
prompt.AppendLine("- Do not mention the route of file that has been change.");
prompt.AppendLine("- Simply describe the MAIN GOAL of the changes.");
prompt.AppendLine("- Output directly the summary in plain text.`");
var rsp = Models.OpenAI.Chat(prompt.ToString(), $"Here is the `git diff` output: {diff}", _cancelToken);
if (rsp != null && rsp.Choices.Count > 0)
return rsp.Choices[0].Message.Content;
return string.Empty;
}
private string GenerateSubject(string summary)
{
var prompt = new StringBuilder();
prompt.AppendLine("You are an expert developer specialist in creating commits messages.");
prompt.AppendLine("Your only goal is to retrieve a single commit message.");
prompt.AppendLine("Based on the provided user changes, combine them in ONE SINGLE commit message retrieving the global idea, following strictly the next rules:");
prompt.AppendLine("- Assign the commit {type} according to the next conditions:");
prompt.AppendLine(" feat: Only when adding a new feature.");
prompt.AppendLine(" fix: When fixing a bug.");
prompt.AppendLine(" docs: When updating documentation.");
prompt.AppendLine(" style: When changing elements styles or design and/or making changes to the code style (formatting, missing semicolons, etc.) without changing the code logic.");
prompt.AppendLine(" test: When adding or updating tests. ");
prompt.AppendLine(" chore: When making changes to the build process or auxiliary tools and libraries. ");
prompt.AppendLine(" revert: When undoing a previous commit.");
prompt.AppendLine(" refactor: When restructuring code without changing its external behavior, or is any of the other refactor types.");
prompt.AppendLine("- Do not add any issues numeration, explain your output nor introduce your answer.");
prompt.AppendLine("- Output directly only one commit message in plain text with the next format: {type}: {commit_message}.");
prompt.AppendLine("- Be as concise as possible, keep the message under 50 characters.");
var rsp = Models.OpenAI.Chat(prompt.ToString(), $"Here are the summaries changes: {summary}", _cancelToken);
if (rsp != null && rsp.Choices.Count > 0)
return rsp.Choices[0].Message.Content;
return string.Empty;
}
private Models.OpenAIService _service;
private string _repo;
private List<Models.Change> _changes;
private CancellationToken _cancelToken;
private Action<string> _onProgress;
private Action<string> _onResponse;
}
}

View file

@ -1,52 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
using Avalonia.Threading;
namespace SourceGit.Commands
{
public static class GitFlow
{
public class BranchDetectResult
public static bool Init(string repo, string master, string develop, string feature, string release, string hotfix, string version, Models.ICommandLog log)
{
public bool IsGitFlowBranch { get; set; } = false;
public string Type { get; set; } = string.Empty;
public string Prefix { get; set; } = string.Empty;
}
public static bool IsEnabled(string repo, List<Models.Branch> branches)
{
var localBrancheNames = new HashSet<string>();
foreach (var branch in branches)
{
if (branch.IsLocal)
localBrancheNames.Add(branch.Name);
}
var config = new Config(repo).ListAll();
if (!config.TryGetValue("gitflow.branch.master", out string master) || !localBrancheNames.Contains(master))
return false;
if (!config.TryGetValue("gitflow.branch.develop", out string develop) || !localBrancheNames.Contains(develop))
return false;
return config.ContainsKey("gitflow.prefix.feature") &&
config.ContainsKey("gitflow.prefix.release") &&
config.ContainsKey("gitflow.prefix.hotfix");
}
public static bool Init(string repo, List<Models.Branch> branches, string master, string develop, string feature, string release, string hotfix, string version)
{
var current = branches.Find(x => x.IsCurrent);
var masterBranch = branches.Find(x => x.Name == master);
if (masterBranch == null && current != null)
Branch.Create(repo, master, current.Head);
var devBranch = branches.Find(x => x.Name == develop);
if (devBranch == null && current != null)
Branch.Create(repo, develop, current.Head);
var config = new Config(repo);
config.Set("gitflow.branch.master", master);
config.Set("gitflow.branch.develop", develop);
@ -61,104 +21,72 @@ namespace SourceGit.Commands
init.WorkingDirectory = repo;
init.Context = repo;
init.Args = "flow init -d";
init.Log = log;
return init.Exec();
}
public static string GetPrefix(string repo, string type)
public static bool Start(string repo, Models.GitFlowBranchType type, string name, Models.ICommandLog log)
{
return new Config(repo).Get($"gitflow.prefix.{type}");
}
public static BranchDetectResult DetectType(string repo, List<Models.Branch> branches, string branch)
{
var rs = new BranchDetectResult();
var localBrancheNames = new HashSet<string>();
foreach (var b in branches)
{
if (b.IsLocal)
localBrancheNames.Add(b.Name);
}
var config = new Config(repo).ListAll();
if (!config.TryGetValue("gitflow.branch.master", out string master) || !localBrancheNames.Contains(master))
return rs;
if (!config.TryGetValue("gitflow.branch.develop", out string develop) || !localBrancheNames.Contains(develop))
return rs;
if (!config.TryGetValue("gitflow.prefix.feature", out var feature) ||
!config.TryGetValue("gitflow.prefix.release", out var release) ||
!config.TryGetValue("gitflow.prefix.hotfix", out var hotfix))
return rs;
if (branch.StartsWith(feature, StringComparison.Ordinal))
{
rs.IsGitFlowBranch = true;
rs.Type = "feature";
rs.Prefix = feature;
}
else if (branch.StartsWith(release, StringComparison.Ordinal))
{
rs.IsGitFlowBranch = true;
rs.Type = "release";
rs.Prefix = release;
}
else if (branch.StartsWith(hotfix, StringComparison.Ordinal))
{
rs.IsGitFlowBranch = true;
rs.Type = "hotfix";
rs.Prefix = hotfix;
}
return rs;
}
public static bool Start(string repo, string type, string name)
{
if (!SUPPORTED_BRANCH_TYPES.Contains(type))
{
Dispatcher.UIThread.Post(() =>
{
App.RaiseException(repo, "Bad branch type!!!");
});
return false;
}
var start = new Command();
start.WorkingDirectory = repo;
start.Context = repo;
start.Args = $"flow {type} start {name}";
return start.Exec();
}
public static bool Finish(string repo, string type, string name, bool keepBranch)
switch (type)
{
if (!SUPPORTED_BRANCH_TYPES.Contains(type))
{
Dispatcher.UIThread.Post(() =>
{
App.RaiseException(repo, "Bad branch type!!!");
});
case Models.GitFlowBranchType.Feature:
start.Args = $"flow feature start {name}";
break;
case Models.GitFlowBranchType.Release:
start.Args = $"flow release start {name}";
break;
case Models.GitFlowBranchType.Hotfix:
start.Args = $"flow hotfix start {name}";
break;
default:
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, "Bad git-flow branch type!!!"));
return false;
}
var option = keepBranch ? "-k" : string.Empty;
start.Log = log;
return start.Exec();
}
public static bool Finish(string repo, Models.GitFlowBranchType type, string name, bool squash, bool push, bool keepBranch, Models.ICommandLog log)
{
var builder = new StringBuilder();
builder.Append("flow ");
switch (type)
{
case Models.GitFlowBranchType.Feature:
builder.Append("feature");
break;
case Models.GitFlowBranchType.Release:
builder.Append("release");
break;
case Models.GitFlowBranchType.Hotfix:
builder.Append("hotfix");
break;
default:
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, "Bad git-flow branch type!!!"));
return false;
}
builder.Append(" finish ");
if (squash)
builder.Append("--squash ");
if (push)
builder.Append("--push ");
if (keepBranch)
builder.Append("-k ");
builder.Append(name);
var finish = new Command();
finish.WorkingDirectory = repo;
finish.Context = repo;
finish.Args = $"flow {type} finish {option} {name}";
finish.Args = builder.ToString();
finish.Log = log;
return finish.Exec();
}
private static readonly List<string> SUPPORTED_BRANCH_TYPES = new List<string>()
{
"feature",
"release",
"bugfix",
"hotfix",
"support",
};
}
}

View file

@ -8,7 +8,14 @@ namespace SourceGit.Commands
{
var file = Path.Combine(repo, ".gitignore");
if (!File.Exists(file))
{
File.WriteAllLines(file, [pattern]);
return;
}
var org = File.ReadAllText(file);
if (!org.EndsWith('\n'))
File.AppendAllLines(file, ["", pattern]);
else
File.AppendAllLines(file, [pattern]);
}

View file

@ -0,0 +1,24 @@
using System.IO;
namespace SourceGit.Commands
{
public class IsBareRepository : Command
{
public IsBareRepository(string path)
{
WorkingDirectory = path;
Args = "rev-parse --is-bare-repository";
}
public bool Result()
{
if (!Directory.Exists(Path.Combine(WorkingDirectory, "refs")) ||
!Directory.Exists(Path.Combine(WorkingDirectory, "objects")) ||
!File.Exists(Path.Combine(WorkingDirectory, "HEAD")))
return false;
var rs = ReadToEnd();
return rs.IsSuccess && rs.StdOut.Trim() == "true";
}
}
}

View file

@ -11,7 +11,7 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = $"diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904 {commit} --numstat -- \"{path}\"";
Args = $"diff {Models.Commit.EmptyTreeSHA1} {commit} --numstat -- \"{path}\"";
RaiseError = false;
}

View file

@ -0,0 +1,17 @@
namespace SourceGit.Commands
{
public class IsCommitSHA : Command
{
public IsCommitSHA(string repo, string hash)
{
WorkingDirectory = repo;
Args = $"cat-file -t {hash}";
}
public bool Result()
{
var rs = ReadToEnd();
return rs.IsSuccess && rs.StdOut.Trim().Equals("commit");
}
}
}

View file

@ -10,5 +10,10 @@
Context = repo;
Args = $"diff -a --ignore-cr-at-eol --check {opt}";
}
public bool Result()
{
return ReadToEnd().IsSuccess;
}
}
}

View file

@ -7,26 +7,18 @@ namespace SourceGit.Commands
{
public partial class LFS
{
[GeneratedRegex(@"^(.+)\s+(\w+)\s+\w+:(\d+)$")]
[GeneratedRegex(@"^(.+)\s+([\w.]+)\s+\w+:(\d+)$")]
private static partial Regex REG_LOCK();
class SubCmd : Command
private class SubCmd : Command
{
public SubCmd(string repo, string args, Action<string> onProgress)
public SubCmd(string repo, string args, Models.ICommandLog log)
{
WorkingDirectory = repo;
Context = repo;
Args = args;
TraitErrorAsOutput = true;
_outputHandler = onProgress;
Log = log;
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private readonly Action<string> _outputHandler;
}
public LFS(string repo)
@ -44,35 +36,35 @@ namespace SourceGit.Commands
return content.Contains("git lfs pre-push");
}
public bool Install()
public bool Install(Models.ICommandLog log)
{
return new SubCmd(_repo, "lfs install --local", null).Exec();
return new SubCmd(_repo, "lfs install --local", log).Exec();
}
public bool Track(string pattern, bool isFilenameMode = false)
public bool Track(string pattern, bool isFilenameMode, Models.ICommandLog log)
{
var opt = isFilenameMode ? "--filename" : "";
return new SubCmd(_repo, $"lfs track {opt} \"{pattern}\"", null).Exec();
return new SubCmd(_repo, $"lfs track {opt} \"{pattern}\"", log).Exec();
}
public void Fetch(string remote, Action<string> outputHandler)
public void Fetch(string remote, Models.ICommandLog log)
{
new SubCmd(_repo, $"lfs fetch {remote}", outputHandler).Exec();
new SubCmd(_repo, $"lfs fetch {remote}", log).Exec();
}
public void Pull(string remote, Action<string> outputHandler)
public void Pull(string remote, Models.ICommandLog log)
{
new SubCmd(_repo, $"lfs pull {remote}", outputHandler).Exec();
new SubCmd(_repo, $"lfs pull {remote}", log).Exec();
}
public void Push(string remote, Action<string> outputHandler)
public void Push(string remote, Models.ICommandLog log)
{
new SubCmd(_repo, $"lfs push {remote}", outputHandler).Exec();
new SubCmd(_repo, $"lfs push {remote}", log).Exec();
}
public void Prune(Action<string> outputHandler)
public void Prune(Models.ICommandLog log)
{
new SubCmd(_repo, "lfs prune", outputHandler).Exec();
new SubCmd(_repo, "lfs prune", log).Exec();
}
public List<Models.LFSLock> Locks(string remote)
@ -82,7 +74,7 @@ namespace SourceGit.Commands
var rs = cmd.ReadToEnd();
if (rs.IsSuccess)
{
var lines = rs.StdOut.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_LOCK().Match(line);
@ -101,21 +93,21 @@ namespace SourceGit.Commands
return locks;
}
public bool Lock(string remote, string file)
public bool Lock(string remote, string file, Models.ICommandLog log)
{
return new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", null).Exec();
return new SubCmd(_repo, $"lfs lock --remote={remote} \"{file}\"", log).Exec();
}
public bool Unlock(string remote, string file, bool force)
public bool Unlock(string remote, string file, bool force, Models.ICommandLog log)
{
var opt = force ? "-f" : "";
return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", null).Exec();
return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} \"{file}\"", log).Exec();
}
public bool Unlock(string remote, long id, bool force)
public bool Unlock(string remote, long id, bool force, Models.ICommandLog log)
{
var opt = force ? "-f" : "";
return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} --id={id}", null).Exec();
return new SubCmd(_repo, $"lfs unlock --remote={remote} {opt} --id={id}", log).Exec();
}
private readonly string _repo;

View file

@ -1,23 +1,36 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
{
public class Merge : Command
{
public Merge(string repo, string source, string mode, Action<string> outputHandler)
public Merge(string repo, string source, string mode)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
Args = $"merge --progress {source} {mode}";
}
protected override void OnReadline(string line)
public Merge(string repo, List<string> targets, bool autoCommit, string strategy)
{
_outputHandler?.Invoke(line);
WorkingDirectory = repo;
Context = repo;
var builder = new StringBuilder();
builder.Append("merge --progress ");
if (!string.IsNullOrEmpty(strategy))
builder.Append($"--strategy={strategy} ");
if (!autoCommit)
builder.Append("--no-commit ");
foreach (var t in targets)
{
builder.Append(t);
builder.Append(' ');
}
private readonly Action<string> _outputHandler = null;
Args = builder.ToString();
}
}
}

View file

@ -13,15 +13,18 @@ namespace SourceGit.Commands
cmd.Context = repo;
cmd.RaiseError = true;
// NOTE: If no <file> names are specified, 'git mergetool' will run the merge tool program on every file with merge conflicts.
var fileArg = string.IsNullOrEmpty(file) ? "" : $"\"{file}\"";
if (toolType == 0)
{
cmd.Args = $"mergetool \"{file}\"";
cmd.Args = $"mergetool {fileArg}";
return cmd.Exec();
}
if (!File.Exists(toolPath))
{
Dispatcher.UIThread.Post(() => App.RaiseException(repo, $"Can NOT found external merge tool in '{toolPath}'!"));
Dispatcher.UIThread.Post(() => App.RaiseException(repo, $"Can NOT find external merge tool in '{toolPath}'!"));
return false;
}
@ -32,7 +35,7 @@ namespace SourceGit.Commands
return false;
}
cmd.Args = $"-c mergetool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit \"{file}\"";
cmd.Args = $"-c mergetool.sourcegit.cmd=\"\\\"{toolPath}\\\" {supported.Cmd}\" -c mergetool.writeToTemp=true -c mergetool.keepBackup=false -c mergetool.trustExitCode=true mergetool --tool=sourcegit {fileArg}";
return cmd.Exec();
}
@ -51,7 +54,7 @@ namespace SourceGit.Commands
if (!File.Exists(toolPath))
{
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, $"Can NOT found external diff tool in '{toolPath}'!"));
Dispatcher.UIThread.Invoke(() => App.RaiseException(repo, $"Can NOT find external diff tool in '{toolPath}'!"));
return false;
}

View file

@ -1,31 +1,18 @@
using System;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Pull : Command
{
public Pull(string repo, string remote, string branch, bool useRebase, bool noTags, Action<string> outputHandler)
public Pull(string repo, string remote, string branch, bool useRebase)
{
_outputHandler = outputHandler;
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
Args = "pull --verbose --progress --tags ";
Args = "pull --verbose --progress ";
if (useRebase)
Args += "--rebase ";
if (noTags)
Args += "--no-tags ";
Args += "--rebase=true ";
Args += $"{remote} {branch}";
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private readonly Action<string> _outputHandler;
}
}

View file

@ -1,16 +1,11 @@
using System;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Push : Command
{
public Push(string repo, string local, string remote, string remoteBranch, bool withTags, bool checkSubmodules, bool track, bool force, Action<string> onProgress)
public Push(string repo, string local, string remote, string remoteBranch, bool withTags, bool checkSubmodules, bool track, bool force)
{
_outputHandler = onProgress;
WorkingDirectory = repo;
Context = repo;
TraitErrorAsOutput = true;
SSHKey = new Config(repo).Get($"remote.{remote}.sshkey");
Args = "push --progress --verbose ";
@ -26,7 +21,7 @@ namespace SourceGit.Commands
Args += $"{remote} {local}:{remoteBranch}";
}
public Push(string repo, string remote, string tag, bool isDelete)
public Push(string repo, string remote, string refname, bool isDelete)
{
WorkingDirectory = repo;
Context = repo;
@ -36,14 +31,7 @@ namespace SourceGit.Commands
if (isDelete)
Args += "--delete ";
Args += $"{remote} refs/tags/{tag}";
Args += $"{remote} {refname}";
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private readonly Action<string> _outputHandler = null;
}
}

View file

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace SourceGit.Commands
{
public partial class QueryAssumeUnchangedFiles : Command
{
[GeneratedRegex(@"^(\w)\s+(.+)$")]
private static partial Regex REG_PARSE();
public QueryAssumeUnchangedFiles(string repo)
{
WorkingDirectory = repo;
Args = "ls-files -v";
RaiseError = false;
}
public List<string> Result()
{
var outs = new List<string>();
var rs = ReadToEnd();
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_PARSE().Match(line);
if (!match.Success)
continue;
if (match.Groups[1].Value == "h")
outs.Add(match.Groups[2].Value);
}
return outs;
}
}
}

View file

@ -14,22 +14,52 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = "branch -l --all -v --format=\"%(refname)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
Args = "branch -l --all -v --format=\"%(refname)%00%(committerdate:unix)%00%(objectname)%00%(HEAD)%00%(upstream)%00%(upstream:trackshort)\"";
}
public List<Models.Branch> Result()
public List<Models.Branch> Result(out int localBranchesCount)
{
localBranchesCount = 0;
var branches = new List<Models.Branch>();
var rs = ReadToEnd();
if (!rs.IsSuccess)
return branches;
var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries);
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
var remoteHeads = new Dictionary<string, string>();
foreach (var line in lines)
{
var b = ParseLine(line);
if (b != null)
{
branches.Add(b);
if (!b.IsLocal)
remoteHeads.Add(b.FullName, b.Head);
else
localBranchesCount++;
}
}
foreach (var b in branches)
{
if (b.IsLocal && !string.IsNullOrEmpty(b.Upstream))
{
if (remoteHeads.TryGetValue(b.Upstream, out var upstreamHead))
{
b.IsUpstreamGone = false;
if (b.TrackStatus == null)
b.TrackStatus = new QueryTrackStatus(WorkingDirectory, b.Head, upstreamHead).Result();
}
else
{
b.IsUpstreamGone = true;
if (b.TrackStatus == null)
b.TrackStatus = new Models.BranchTrackStatus();
}
}
}
return branches;
@ -38,7 +68,7 @@ namespace SourceGit.Commands
private Models.Branch ParseLine(string line)
{
var parts = line.Split('\0');
if (parts.Length != 5)
if (parts.Length != 6)
return null;
var branch = new Models.Branch();
@ -72,13 +102,16 @@ namespace SourceGit.Commands
}
branch.FullName = refName;
branch.Head = parts[1];
branch.IsCurrent = parts[2] == "*";
branch.Upstream = parts[3];
branch.CommitterDate = ulong.Parse(parts[1]);
branch.Head = parts[2];
branch.IsCurrent = parts[3] == "*";
branch.Upstream = parts[4];
branch.IsUpstreamGone = false;
if (branch.IsLocal && !string.IsNullOrEmpty(parts[4]) && !parts[4].Equals("=", StringComparison.Ordinal))
branch.TrackStatus = new QueryTrackStatus(WorkingDirectory, branch.Name, branch.Upstream).Result();
else
if (!branch.IsLocal ||
string.IsNullOrEmpty(branch.Upstream) ||
string.IsNullOrEmpty(parts[5]) ||
parts[5].Equals("=", StringComparison.Ordinal))
branch.TrackStatus = new Models.BranchTrackStatus();
return branch;

View file

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
namespace SourceGit.Commands
{
public class QueryCommitChildren : Command
{
public QueryCommitChildren(string repo, string commit, int max)
{
WorkingDirectory = repo;
Context = repo;
_commit = commit;
Args = $"rev-list -{max} --parents --branches --remotes --ancestry-path ^{commit}";
}
public List<string> Result()
{
var rs = ReadToEnd();
var outs = new List<string>();
if (rs.IsSuccess)
{
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line.Contains(_commit))
outs.Add(line.Substring(0, 40));
}
}
return outs;
}
private string _commit;
}
}

View file

@ -6,7 +6,7 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = $"show --no-show-signature --pretty=format:%B -s {sha}";
Args = $"show --no-show-signature --format=%B -s {sha}";
}
public string Result()

View file

@ -0,0 +1,34 @@
namespace SourceGit.Commands
{
public class QueryCommitSignInfo : Command
{
public QueryCommitSignInfo(string repo, string sha, bool useFakeSignersFile)
{
WorkingDirectory = repo;
Context = repo;
const string baseArgs = "show --no-show-signature --format=%G?%n%GS%n%GK -s";
const string fakeSignersFileArg = "-c gpg.ssh.allowedSignersFile=/dev/null";
Args = $"{(useFakeSignersFile ? fakeSignersFileArg : string.Empty)} {baseArgs} {sha}";
}
public Models.CommitSignInfo Result()
{
var rs = ReadToEnd();
if (!rs.IsSuccess)
return null;
var raw = rs.StdOut.Trim().ReplaceLineEndings("\n");
if (raw.Length <= 1)
return null;
var lines = raw.Split('\n');
return new Models.CommitSignInfo()
{
VerifyResult = lines[0][0],
Signer = lines[1],
Key = lines[2]
};
}
}
}

View file

@ -10,7 +10,7 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = "log --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + limits;
Args = $"log --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s {limits}";
_findFirstMerged = needFindHead;
}
@ -18,20 +18,20 @@ namespace SourceGit.Commands
{
string search = onlyCurrentBranch ? string.Empty : "--branches --remotes ";
if (method == Models.CommitSearchMethod.ByUser)
if (method == Models.CommitSearchMethod.ByAuthor)
{
search += $"-i --author=\"{filter}\" --committer=\"{filter}\"";
search += $"-i --author=\"{filter}\"";
}
else if (method == Models.CommitSearchMethod.ByFile)
else if (method == Models.CommitSearchMethod.ByCommitter)
{
search += $"-- \"{filter}\"";
search += $"-i --committer=\"{filter}\"";
}
else
else if (method == Models.CommitSearchMethod.ByMessage)
{
var argsBuilder = new StringBuilder();
argsBuilder.Append(search);
var words = filter.Split(new[] { ' ', '\t', '\r' }, StringSplitOptions.RemoveEmptyEntries);
var words = filter.Split([' ', '\t', '\r'], StringSplitOptions.RemoveEmptyEntries);
foreach (var word in words)
{
var escaped = word.Trim().Replace("\"", "\\\"", StringComparison.Ordinal);
@ -41,10 +41,18 @@ namespace SourceGit.Commands
search = argsBuilder.ToString();
}
else if (method == Models.CommitSearchMethod.ByFile)
{
search += $"-- \"{filter}\"";
}
else
{
search = $"-G\"{filter}\"";
}
WorkingDirectory = repo;
Context = repo;
Args = $"log -1000 --date-order --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s " + search;
Args = $"log -1000 --date-order --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s {search}";
_findFirstMerged = false;
}
@ -112,15 +120,7 @@ namespace SourceGit.Commands
if (data.Length < 8)
return;
var idx = data.IndexOf(' ', StringComparison.Ordinal);
if (idx == -1)
{
_current.Parents.Add(data);
return;
}
_current.Parents.Add(data.Substring(0, idx));
_current.Parents.Add(data.Substring(idx + 1));
_current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
}
private void MarkFirstMerged()
@ -128,7 +128,7 @@ namespace SourceGit.Commands
Args = $"log --since=\"{_commits[^1].CommitterTimeStr}\" --format=\"%H\"";
var rs = ReadToEnd();
var shas = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries);
var shas = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
if (shas.Length == 0)
return;

View file

@ -3,18 +3,18 @@ using System.Collections.Generic;
namespace SourceGit.Commands
{
public class QueryCommitsWithFullMessage : Command
public class QueryCommitsForInteractiveRebase : Command
{
public QueryCommitsWithFullMessage(string repo, string args)
public QueryCommitsForInteractiveRebase(string repo, string on)
{
_boundary = $"----- BOUNDARY OF COMMIT {Guid.NewGuid()} -----";
WorkingDirectory = repo;
Context = repo;
Args = $"log --date-order --no-show-signature --decorate=full --pretty=format:\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {args}";
Args = $"log --date-order --no-show-signature --decorate=full --format=\"%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%B%n{_boundary}\" {on}..HEAD";
}
public List<Models.CommitWithMessage> Result()
public List<Models.InteractiveCommit> Result()
{
var rs = ReadToEnd();
if (!rs.IsSuccess)
@ -29,7 +29,7 @@ namespace SourceGit.Commands
switch (nextPartIdx)
{
case 0:
_current = new Models.CommitWithMessage();
_current = new Models.InteractiveCommit();
_current.Commit.SHA = line;
_commits.Add(_current);
break;
@ -52,16 +52,28 @@ namespace SourceGit.Commands
_current.Commit.CommitterTime = ulong.Parse(line);
break;
default:
if (line.Equals(_boundary, StringComparison.Ordinal))
nextPartIdx = -1;
var boundary = rs.StdOut.IndexOf(_boundary, end + 1, StringComparison.Ordinal);
if (boundary > end)
{
_current.Message = rs.StdOut.Substring(start, boundary - start - 1);
end = boundary + _boundary.Length;
}
else
_current.Message += line;
{
_current.Message = rs.StdOut.Substring(start);
end = rs.StdOut.Length - 2;
}
nextPartIdx = -1;
break;
}
nextPartIdx++;
start = end + 1;
if (start >= rs.StdOut.Length - 1)
break;
end = rs.StdOut.IndexOf('\n', start);
}
@ -73,19 +85,11 @@ namespace SourceGit.Commands
if (data.Length < 8)
return;
var idx = data.IndexOf(' ', StringComparison.Ordinal);
if (idx == -1)
{
_current.Commit.Parents.Add(data);
return;
_current.Commit.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
}
_current.Commit.Parents.Add(data.Substring(0, idx));
_current.Commit.Parents.Add(data.Substring(idx + 1));
}
private List<Models.CommitWithMessage> _commits = new List<Models.CommitWithMessage>();
private Models.CommitWithMessage _current = null;
private string _boundary = "";
private List<Models.InteractiveCommit> _commits = [];
private Models.InteractiveCommit _current = null;
private readonly string _boundary;
}
}

View file

@ -1,21 +0,0 @@
namespace SourceGit.Commands
{
public class QueryCurrentRevisionFiles : Command
{
public QueryCurrentRevisionFiles(string repo)
{
WorkingDirectory = repo;
Context = repo;
Args = "ls-tree -r --name-only HEAD";
}
public string[] Result()
{
var rs = ReadToEnd();
if (rs.IsSuccess)
return rs.StdOut.Split('\n', System.StringSplitOptions.RemoveEmptyEntries);
return [];
}
}
}

View file

@ -35,5 +35,39 @@ namespace SourceGit.Commands
return stream;
}
public static Stream FromLFS(string repo, string oid, long size)
{
var starter = new ProcessStartInfo();
starter.WorkingDirectory = repo;
starter.FileName = Native.OS.GitExecutable;
starter.Arguments = $"lfs smudge";
starter.UseShellExecute = false;
starter.CreateNoWindow = true;
starter.WindowStyle = ProcessWindowStyle.Hidden;
starter.RedirectStandardInput = true;
starter.RedirectStandardOutput = true;
var stream = new MemoryStream();
try
{
var proc = new Process() { StartInfo = starter };
proc.Start();
proc.StandardInput.WriteLine("version https://git-lfs.github.com/spec/v1");
proc.StandardInput.WriteLine($"oid sha256:{oid}");
proc.StandardInput.WriteLine($"size {size}");
proc.StandardOutput.BaseStream.CopyTo(stream);
proc.WaitForExit();
proc.Close();
stream.Position = 0;
}
catch (Exception e)
{
App.RaiseException(repo, $"Failed to query file content: {e}");
}
return stream;
}
}
}

View file

@ -11,14 +11,11 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = $"ls-tree {revision} -l -- {file}";
Args = $"ls-tree {revision} -l -- \"{file}\"";
}
public long Result()
{
if (_result != 0)
return _result;
var rs = ReadToEnd();
if (rs.IsSuccess)
{
@ -29,7 +26,5 @@ namespace SourceGit.Commands
return 0;
}
private readonly long _result = 0;
}
}

View file

@ -0,0 +1,26 @@
using System.IO;
namespace SourceGit.Commands
{
public class QueryGitCommonDir : Command
{
public QueryGitCommonDir(string workDir)
{
WorkingDirectory = workDir;
Args = "rev-parse --git-common-dir";
RaiseError = false;
}
public string Result()
{
var rs = ReadToEnd().StdOut;
if (string.IsNullOrEmpty(rs))
return null;
rs = rs.Trim();
if (Path.IsPathRooted(rs))
return rs;
return Path.GetFullPath(Path.Combine(WorkingDirectory, rs));
}
}
}

View file

@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Avalonia.Threading;
namespace SourceGit.Commands
{
public partial class QueryLocalChanges : Command
@ -14,20 +16,25 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = $"status -u{UNTRACKED[includeUntracked ? 1 : 0]} --ignore-submodules=dirty --porcelain";
Args = $"--no-optional-locks status -u{UNTRACKED[includeUntracked ? 1 : 0]} --ignore-submodules=dirty --porcelain";
}
public List<Models.Change> Result()
{
Exec();
return _changes;
var outs = new List<Models.Change>();
var rs = ReadToEnd();
if (!rs.IsSuccess)
{
Dispatcher.UIThread.Post(() => App.RaiseException(Context, rs.StdErr));
return outs;
}
protected override void OnReadline(string line)
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_FORMAT().Match(line);
if (!match.Success)
return;
continue;
var change = new Models.Change() { Path = match.Groups[2].Value };
var status = match.Groups[1].Value;
@ -115,43 +122,44 @@ namespace SourceGit.Commands
case "CD":
change.Set(Models.ChangeState.Copied, Models.ChangeState.Deleted);
break;
case "DR":
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Renamed);
break;
case "DC":
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Copied);
break;
case "DD":
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Deleted);
change.ConflictReason = Models.ConflictReason.BothDeleted;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "AU":
change.Set(Models.ChangeState.Added, Models.ChangeState.Unmerged);
change.ConflictReason = Models.ConflictReason.AddedByUs;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "UD":
change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Deleted);
change.ConflictReason = Models.ConflictReason.DeletedByThem;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "UA":
change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Added);
change.ConflictReason = Models.ConflictReason.AddedByThem;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "DU":
change.Set(Models.ChangeState.Deleted, Models.ChangeState.Unmerged);
change.ConflictReason = Models.ConflictReason.DeletedByUs;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "AA":
change.Set(Models.ChangeState.Added, Models.ChangeState.Added);
change.ConflictReason = Models.ConflictReason.BothAdded;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "UU":
change.Set(Models.ChangeState.Unmerged, Models.ChangeState.Unmerged);
change.ConflictReason = Models.ConflictReason.BothModified;
change.Set(Models.ChangeState.None, Models.ChangeState.Conflicted);
break;
case "??":
change.Set(Models.ChangeState.Untracked, Models.ChangeState.Untracked);
change.Set(Models.ChangeState.None, Models.ChangeState.Untracked);
break;
default:
return;
}
_changes.Add(change);
if (change.Index != Models.ChangeState.None || change.WorkTree != Models.ChangeState.None)
outs.Add(change);
}
private readonly List<Models.Change> _changes = new List<Models.Change>();
return outs;
}
}
}

View file

@ -20,9 +20,12 @@ namespace SourceGit.Commands
if (!output.IsSuccess)
return rs;
var lines = output.StdOut.Split('\n');
var lines = output.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line.EndsWith("/HEAD", StringComparison.Ordinal))
continue;
if (line.StartsWith("refs/heads/", StringComparison.Ordinal))
rs.Add(new() { Name = line.Substring("refs/heads/".Length), Type = Models.DecoratorType.LocalBranchHead });
else if (line.StartsWith("refs/remotes/", StringComparison.Ordinal))

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace SourceGit.Commands
@ -17,15 +18,17 @@ namespace SourceGit.Commands
public List<Models.Remote> Result()
{
Exec();
return _loaded;
}
var outs = new List<Models.Remote>();
var rs = ReadToEnd();
if (!rs.IsSuccess)
return outs;
protected override void OnReadline(string line)
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_REMOTE().Match(line);
if (!match.Success)
return;
continue;
var remote = new Models.Remote()
{
@ -33,11 +36,13 @@ namespace SourceGit.Commands
URL = match.Groups[2].Value,
};
if (_loaded.Find(x => x.Name == remote.Name) != null)
return;
_loaded.Add(remote);
if (outs.Find(x => x.Name == remote.Name) != null)
continue;
outs.Add(remote);
}
private readonly List<Models.Remote> _loaded = new List<Models.Remote>();
return outs;
}
}
}

View file

@ -0,0 +1,21 @@
namespace SourceGit.Commands
{
public class QueryRevisionByRefName : Command
{
public QueryRevisionByRefName(string repo, string refname)
{
WorkingDirectory = repo;
Context = repo;
Args = $"rev-parse {refname}";
}
public string Result()
{
var rs = ReadToEnd();
if (rs.IsSuccess && !string.IsNullOrEmpty(rs.StdOut))
return rs.StdOut.Trim();
return null;
}
}
}

View file

@ -0,0 +1,27 @@
using System.Collections.Generic;
namespace SourceGit.Commands
{
public class QueryRevisionFileNames : Command
{
public QueryRevisionFileNames(string repo, string revision)
{
WorkingDirectory = repo;
Context = repo;
Args = $"ls-tree -r -z --name-only {revision}";
}
public List<string> Result()
{
var rs = ReadToEnd();
if (!rs.IsSuccess)
return [];
var lines = rs.StdOut.Split('\0', System.StringSplitOptions.RemoveEmptyEntries);
var outs = new List<string>();
foreach (var line in lines)
outs.Add(line);
return outs;
}
}
}

View file

@ -12,7 +12,7 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = $"ls-tree {sha}";
Args = $"ls-tree -z {sha}";
if (!string.IsNullOrEmpty(parentFolder))
Args += $" -- \"{parentFolder}\"";
@ -20,11 +20,27 @@ namespace SourceGit.Commands
public List<Models.Object> Result()
{
Exec();
var rs = ReadToEnd();
if (rs.IsSuccess)
{
var start = 0;
var end = rs.StdOut.IndexOf('\0', start);
while (end > 0)
{
var line = rs.StdOut.Substring(start, end - start);
Parse(line);
start = end + 1;
end = rs.StdOut.IndexOf('\0', start);
}
if (start < rs.StdOut.Length)
Parse(rs.StdOut.Substring(start));
}
return _objects;
}
protected override void OnReadline(string line)
private void Parse(string line)
{
var match = REG_FORMAT().Match(line);
if (!match.Success)

View file

@ -8,7 +8,7 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = $"show --no-show-signature --decorate=full --pretty=format:%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}";
Args = $"show --no-show-signature --decorate=full --format=%H%n%P%n%D%n%aN±%aE%n%at%n%cN±%cE%n%ct%n%s -s {sha}";
}
public Models.Commit Result()

View file

@ -6,25 +6,27 @@ namespace SourceGit.Commands
{
public partial class QueryStagedChangesWithAmend : Command
{
[GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} ([ACDMTUX])\d{0,6}\t(.*)$")]
[GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} ([ACDMT])\d{0,6}\t(.*)$")]
private static partial Regex REG_FORMAT1();
[GeneratedRegex(@"^:[\d]{6} ([\d]{6}) ([0-9a-f]{40}) [0-9a-f]{40} R\d{0,6}\t(.*\t.*)$")]
private static partial Regex REG_FORMAT2();
public QueryStagedChangesWithAmend(string repo)
public QueryStagedChangesWithAmend(string repo, string parent)
{
WorkingDirectory = repo;
Context = repo;
Args = "diff-index --cached -M HEAD^";
Args = $"diff-index --cached -M {parent}";
_parent = parent;
}
public List<Models.Change> Result()
{
var rs = ReadToEnd();
if (rs.IsSuccess)
{
if (!rs.IsSuccess)
return [];
var changes = new List<Models.Change>();
var lines = rs.StdOut.Split('\n', StringSplitOptions.RemoveEmptyEntries);
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_FORMAT2().Match(line);
@ -37,6 +39,7 @@ namespace SourceGit.Commands
{
FileMode = match.Groups[1].Value,
ObjectHash = match.Groups[2].Value,
ParentSHA = _parent,
},
};
change.Set(Models.ChangeState.Renamed);
@ -54,6 +57,7 @@ namespace SourceGit.Commands
{
FileMode = match.Groups[1].Value,
ObjectHash = match.Groups[2].Value,
ParentSHA = _parent,
},
};
@ -75,9 +79,6 @@ namespace SourceGit.Commands
case "T":
change.Set(Models.ChangeState.TypeChanged);
break;
case "U":
change.Set(Models.ChangeState.Unmerged);
break;
}
changes.Add(change);
}
@ -86,7 +87,6 @@ namespace SourceGit.Commands
return changes;
}
return [];
}
private readonly string _parent;
}
}

View file

@ -1,60 +0,0 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace SourceGit.Commands
{
public partial class QueryStashChanges : Command
{
[GeneratedRegex(@"^(\s?[\w\?]{1,4})\s+(.+)$")]
private static partial Regex REG_FORMAT();
public QueryStashChanges(string repo, string sha)
{
WorkingDirectory = repo;
Context = repo;
Args = $"diff --name-status --pretty=format: {sha}^ {sha}";
}
public List<Models.Change> Result()
{
Exec();
return _changes;
}
protected override void OnReadline(string line)
{
var match = REG_FORMAT().Match(line);
if (!match.Success)
return;
var change = new Models.Change() { Path = match.Groups[2].Value };
var status = match.Groups[1].Value;
switch (status[0])
{
case 'M':
change.Set(Models.ChangeState.Modified);
_changes.Add(change);
break;
case 'A':
change.Set(Models.ChangeState.Added);
_changes.Add(change);
break;
case 'D':
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);
break;
}
}
private readonly List<Models.Change> _changes = new List<Models.Change>();
}
}

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
namespace SourceGit.Commands
{
@ -8,41 +9,65 @@ namespace SourceGit.Commands
{
WorkingDirectory = repo;
Context = repo;
Args = "stash list --pretty=format:%H%n%ct%n%gd%n%s";
Args = "stash list --format=%H%n%P%n%ct%n%gd%n%s";
}
public List<Models.Stash> Result()
{
Exec();
return _stashes;
}
var outs = new List<Models.Stash>();
var rs = ReadToEnd();
if (!rs.IsSuccess)
return outs;
protected override void OnReadline(string line)
var nextPartIdx = 0;
var start = 0;
var end = rs.StdOut.IndexOf('\n', start);
while (end > 0)
{
switch (_nextLineIdx)
var line = rs.StdOut.Substring(start, end - start);
switch (nextPartIdx)
{
case 0:
_current = new Models.Stash() { SHA = line };
_stashes.Add(_current);
outs.Add(_current);
break;
case 1:
_current.Time = ulong.Parse(line);
ParseParent(line);
break;
case 2:
_current.Name = line;
_current.Time = ulong.Parse(line);
break;
case 3:
_current.Name = line;
break;
case 4:
_current.Message = line;
break;
}
_nextLineIdx++;
if (_nextLineIdx > 3)
_nextLineIdx = 0;
nextPartIdx++;
if (nextPartIdx > 4)
nextPartIdx = 0;
start = end + 1;
end = rs.StdOut.IndexOf('\n', start);
}
if (start < rs.StdOut.Length)
_current.Message = rs.StdOut.Substring(start);
return outs;
}
private void ParseParent(string data)
{
if (data.Length < 8)
return;
_current.Parents.AddRange(data.Split(separator: ' ', options: StringSplitOptions.RemoveEmptyEntries));
}
private readonly List<Models.Stash> _stashes = new List<Models.Stash>();
private Models.Stash _current = null;
private int _nextLineIdx = 0;
}
}

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
@ -6,12 +7,12 @@ namespace SourceGit.Commands
{
public partial class QuerySubmodules : Command
{
[GeneratedRegex(@"^[\-\+ ][0-9a-f]+\s(.*)\s\(.*\)$")]
private static partial Regex REG_FORMAT1();
[GeneratedRegex(@"^[\-\+ ][0-9a-f]+\s(.*)$")]
private static partial Regex REG_FORMAT2();
[GeneratedRegex(@"^\s?[\w\?]{1,4}\s+(.+)$")]
[GeneratedRegex(@"^([U\-\+ ])([0-9a-f]+)\s(.*?)(\s\(.*\))?$")]
private static partial Regex REG_FORMAT_STATUS();
[GeneratedRegex(@"^\s?[\w\?]{1,4}\s+(.+)$")]
private static partial Regex REG_FORMAT_DIRTY();
[GeneratedRegex(@"^submodule\.(\S*)\.(\w+)=(.*)$")]
private static partial Regex REG_FORMAT_MODULE_INFO();
public QuerySubmodules(string repo)
{
@ -24,55 +25,118 @@ namespace SourceGit.Commands
{
var submodules = new List<Models.Submodule>();
var rs = ReadToEnd();
if (!rs.IsSuccess)
return submodules;
var builder = new StringBuilder();
var lines = rs.StdOut.Split('\n', System.StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_FORMAT1().Match(line);
if (match.Success)
{
var path = match.Groups[1].Value;
builder.Append($"\"{path}\" ");
submodules.Add(new Models.Submodule() { Path = path });
continue;
}
match = REG_FORMAT2().Match(line);
if (match.Success)
{
var path = match.Groups[1].Value;
builder.Append($"\"{path}\" ");
submodules.Add(new Models.Submodule() { Path = path });
}
}
if (submodules.Count > 0)
{
Args = $"status -uno --porcelain -- {builder}";
rs = ReadToEnd();
if (!rs.IsSuccess)
return submodules;
var dirty = new HashSet<string>();
lines = rs.StdOut.Split('\n', System.StringSplitOptions.RemoveEmptyEntries);
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
var map = new Dictionary<string, Models.Submodule>();
var needCheckLocalChanges = false;
foreach (var line in lines)
{
var match = REG_FORMAT_STATUS().Match(line);
if (match.Success)
{
var path = match.Groups[1].Value;
dirty.Add(path);
var stat = match.Groups[1].Value;
var sha = match.Groups[2].Value;
var path = match.Groups[3].Value;
var module = new Models.Submodule() { Path = path, SHA = sha };
switch (stat[0])
{
case '-':
module.Status = Models.SubmoduleStatus.NotInited;
break;
case '+':
module.Status = Models.SubmoduleStatus.RevisionChanged;
break;
case 'U':
module.Status = Models.SubmoduleStatus.Unmerged;
break;
default:
module.Status = Models.SubmoduleStatus.Normal;
needCheckLocalChanges = true;
break;
}
map.Add(path, module);
submodules.Add(module);
}
}
foreach (var submodule in submodules)
submodule.IsDirty = dirty.Contains(submodule.Path);
if (submodules.Count > 0)
{
Args = "config --file .gitmodules --list";
rs = ReadToEnd();
if (rs.IsSuccess)
{
var modules = new Dictionary<string, ModuleInfo>();
lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_FORMAT_MODULE_INFO().Match(line);
if (match.Success)
{
var name = match.Groups[1].Value;
var key = match.Groups[2].Value;
var val = match.Groups[3].Value;
if (!modules.TryGetValue(name, out var m))
{
m = new ModuleInfo();
modules.Add(name, m);
}
if (key.Equals("path", StringComparison.Ordinal))
m.Path = val;
else if (key.Equals("url", StringComparison.Ordinal))
m.URL = val;
}
}
foreach (var kv in modules)
{
if (map.TryGetValue(kv.Value.Path, out var m))
m.URL = kv.Value.URL;
}
}
}
if (needCheckLocalChanges)
{
var builder = new StringBuilder();
foreach (var kv in map)
{
if (kv.Value.Status == Models.SubmoduleStatus.Normal)
{
builder.Append('"');
builder.Append(kv.Key);
builder.Append("\" ");
}
}
Args = $"--no-optional-locks status --porcelain -- {builder}";
rs = ReadToEnd();
if (!rs.IsSuccess)
return submodules;
lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_FORMAT_DIRTY().Match(line);
if (match.Success)
{
var path = match.Groups[1].Value;
if (map.TryGetValue(path, out var m))
m.Status = Models.SubmoduleStatus.Modified;
}
}
}
return submodules;
}
private class ModuleInfo
{
public string Path { get; set; } = string.Empty;
public string URL { get; set; } = string.Empty;
}
}
}

View file

@ -11,7 +11,7 @@ namespace SourceGit.Commands
Context = repo;
WorkingDirectory = repo;
Args = $"tag -l --sort=-creatordate --format=\"{_boundary}%(refname)%00%(objectname)%00%(*objectname)%00%(contents:subject)%0a%0a%(contents:body)\"";
Args = $"tag -l --format=\"{_boundary}%(refname)%00%(objecttype)%00%(objectname)%00%(*objectname)%00%(creatordate:unix)%00%(contents:subject)%0a%0a%(contents:body)\"";
}
public List<Models.Tag> Result()
@ -25,15 +25,21 @@ namespace SourceGit.Commands
foreach (var record in records)
{
var subs = record.Split('\0', StringSplitOptions.None);
if (subs.Length != 4)
if (subs.Length != 6)
continue;
var message = subs[3].Trim();
var name = subs[0].Substring(10);
var message = subs[5].Trim();
if (!string.IsNullOrEmpty(message) && message.Equals(name, StringComparison.Ordinal))
message = null;
tags.Add(new Models.Tag()
{
Name = subs[0].Substring(10),
SHA = string.IsNullOrEmpty(subs[2]) ? subs[1] : subs[2],
Message = string.IsNullOrEmpty(message) ? null : message,
Name = name,
IsAnnotated = subs[1].Equals("tag", StringComparison.Ordinal),
SHA = string.IsNullOrEmpty(subs[3]) ? subs[2] : subs[3],
CreatorDate = ulong.Parse(subs[4]),
Message = message,
});
}

View file

@ -19,7 +19,7 @@ namespace SourceGit.Commands
if (!rs.IsSuccess)
return status;
var lines = rs.StdOut.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line[0] == '>')

View file

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace SourceGit.Commands
{
public partial class QueryUpdatableSubmodules : Command
{
[GeneratedRegex(@"^([U\-\+ ])([0-9a-f]+)\s(.*?)(\s\(.*\))?$")]
private static partial Regex REG_FORMAT_STATUS();
public QueryUpdatableSubmodules(string repo)
{
WorkingDirectory = repo;
Context = repo;
Args = "submodule status";
}
public List<string> Result()
{
var submodules = new List<string>();
var rs = ReadToEnd();
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
var match = REG_FORMAT_STATUS().Match(line);
if (match.Success)
{
var stat = match.Groups[1].Value;
var path = match.Groups[3].Value;
if (!stat.StartsWith(' '))
submodules.Add(path);
}
}
return submodules;
}
}
}

View file

@ -45,5 +45,14 @@
Args = "remote set-url" + (isPush ? " --push " : " ") + $"{name} {url}";
return Exec();
}
public bool HasBranch(string remote, string branch)
{
SSHKey = new Config(WorkingDirectory).Get($"remote.{remote}.sshkey");
Args = $"ls-remote {remote} {branch}";
var rs = ReadToEnd();
return rs.IsSuccess && rs.StdOut.Trim().Length > 0;
}
}
}

View file

@ -1,33 +1,7 @@
using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
namespace SourceGit.Commands
{
public class Reset : Command
{
public Reset(string repo)
{
WorkingDirectory = repo;
Context = repo;
Args = "reset";
}
public Reset(string repo, List<Models.Change> changes)
{
WorkingDirectory = repo;
Context = repo;
var builder = new StringBuilder();
builder.Append("reset --");
foreach (var c in changes)
{
builder.Append(" \"");
builder.Append(c.Path);
builder.Append("\"");
}
Args = builder.ToString();
}
public Reset(string repo, string revision, string mode)
{
WorkingDirectory = repo;

View file

@ -1,29 +1,52 @@
using System.Collections.Generic;
using System.Text;
using System.Text;
namespace SourceGit.Commands
{
public class Restore : Command
{
public Restore(string repo)
/// <summary>
/// Only used for single staged change.
/// </summary>
/// <param name="repo"></param>
/// <param name="stagedChange"></param>
public Restore(string repo, Models.Change stagedChange)
{
WorkingDirectory = repo;
Context = repo;
Args = "restore . --source=HEAD --staged --worktree --recurse-submodules";
var builder = new StringBuilder();
builder.Append("restore --staged -- \"");
builder.Append(stagedChange.Path);
builder.Append('"');
if (stagedChange.Index == Models.ChangeState.Renamed)
{
builder.Append(" \"");
builder.Append(stagedChange.OriginalPath);
builder.Append('"');
}
public Restore(string repo, List<string> files, string extra)
Args = builder.ToString();
}
/// <summary>
/// Restore changes given in a path-spec file.
/// </summary>
/// <param name="repo"></param>
/// <param name="pathspecFile"></param>
/// <param name="isStaged"></param>
public Restore(string repo, string pathspecFile, bool isStaged)
{
WorkingDirectory = repo;
Context = repo;
StringBuilder builder = new StringBuilder();
var builder = new StringBuilder();
builder.Append("restore ");
if (!string.IsNullOrEmpty(extra))
builder.Append(extra).Append(" ");
builder.Append("--");
foreach (var f in files)
builder.Append(' ').Append('"').Append(f).Append('"');
builder.Append(isStaged ? "--staged " : "--worktree --recurse-submodules ");
builder.Append("--pathspec-from-file=\"");
builder.Append(pathspecFile);
builder.Append('"');
Args = builder.ToString();
}
}

View file

@ -9,7 +9,7 @@ namespace SourceGit.Commands
{
public static class SaveChangesAsPatch
{
public static bool Exec(string repo, List<Models.Change> changes, bool isUnstaged, string saveTo)
public static bool ProcessLocalChanges(string repo, List<Models.Change> changes, bool isUnstaged, string saveTo)
{
using (var sw = File.Create(saveTo))
{
@ -23,6 +23,33 @@ namespace SourceGit.Commands
return true;
}
public static bool ProcessRevisionCompareChanges(string repo, List<Models.Change> changes, string baseRevision, string targetRevision, string saveTo)
{
using (var sw = File.Create(saveTo))
{
foreach (var change in changes)
{
if (!ProcessSingleChange(repo, new Models.DiffOption(baseRevision, targetRevision, change), sw))
return false;
}
}
return true;
}
public static bool ProcessStashChanges(string repo, List<Models.DiffOption> opts, string saveTo)
{
using (var sw = File.Create(saveTo))
{
foreach (var opt in opts)
{
if (!ProcessSingleChange(repo, opt, sw))
return false;
}
}
return true;
}
private static bool ProcessSingleChange(string repo, Models.DiffOption opt, FileStream writer)
{
var starter = new ProcessStartInfo();

View file

@ -13,12 +13,8 @@ namespace SourceGit.Commands
var isLFSFiltered = new IsLFSFiltered(repo, revision, file).Result();
if (isLFSFiltered)
{
var tmpFile = saveTo + ".tmp";
if (ExecCmd(repo, $"show {revision}:\"{file}\"", tmpFile))
{
ExecCmd(repo, $"lfs smudge", saveTo, tmpFile);
}
File.Delete(tmpFile);
var pointerStream = QueryFileContent.Run(repo, revision, file);
ExecCmd(repo, $"lfs smudge", saveTo, pointerStream);
}
else
{
@ -26,7 +22,7 @@ namespace SourceGit.Commands
}
}
private static bool ExecCmd(string repo, string args, string outputFile, string inputFile = null)
private static bool ExecCmd(string repo, string args, string outputFile, Stream input = null)
{
var starter = new ProcessStartInfo();
starter.WorkingDirectory = repo;
@ -45,21 +41,8 @@ namespace SourceGit.Commands
{
var proc = new Process() { StartInfo = starter };
proc.Start();
if (inputFile != null)
{
using (StreamReader sr = new StreamReader(inputFile))
{
while (true)
{
var line = sr.ReadLine();
if (line == null)
break;
proc.StandardInput.WriteLine(line);
}
}
}
if (input != null)
proc.StandardInput.Write(new StreamReader(input).ReadToEnd());
proc.StandardOutput.BaseStream.CopyTo(sw);
proc.WaitForExit();
var rs = proc.ExitCode == 0;

View file

@ -11,69 +11,84 @@ namespace SourceGit.Commands
Context = repo;
}
public bool Push(string message)
public bool Push(string message, bool includeUntracked = true, bool keepIndex = false)
{
Args = $"stash push -m \"{message}\"";
var builder = new StringBuilder();
builder.Append("stash push ");
if (includeUntracked)
builder.Append("--include-untracked ");
if (keepIndex)
builder.Append("--keep-index ");
builder.Append("-m \"");
builder.Append(message);
builder.Append("\"");
Args = builder.ToString();
return Exec();
}
public bool Push(List<Models.Change> changes, string message, bool onlyStaged)
public bool Push(string message, List<Models.Change> changes, bool keepIndex)
{
var pathsBuilder = new StringBuilder();
var builder = new StringBuilder();
builder.Append("stash push --include-untracked ");
if (keepIndex)
builder.Append("--keep-index ");
builder.Append("-m \"");
builder.Append(message);
builder.Append("\" -- ");
if (onlyStaged)
{
foreach (var c in changes)
pathsBuilder.Append($"\"{c.Path}\" ");
var paths = pathsBuilder.ToString();
Args = $"stash push --staged -m \"{message}\" -- {paths}";
}
else
{
var needAdd = new List<Models.Change>();
foreach (var c in changes)
{
pathsBuilder.Append($"\"{c.Path}\" ");
if (c.WorkTree == Models.ChangeState.Added || c.WorkTree == Models.ChangeState.Untracked)
{
needAdd.Add(c);
if (needAdd.Count > 10)
{
new Add(WorkingDirectory, needAdd).Exec();
needAdd.Clear();
}
}
}
if (needAdd.Count > 0)
{
new Add(WorkingDirectory, needAdd).Exec();
needAdd.Clear();
}
var paths = pathsBuilder.ToString();
Args = $"stash push -m \"{message}\" -- {paths}";
}
builder.Append($"\"{c.Path}\" ");
Args = builder.ToString();
return Exec();
}
public bool Apply(string name)
public bool Push(string message, string pathspecFromFile, bool keepIndex)
{
Args = $"stash apply -q {name}";
var builder = new StringBuilder();
builder.Append("stash push --include-untracked --pathspec-from-file=\"");
builder.Append(pathspecFromFile);
builder.Append("\" ");
if (keepIndex)
builder.Append("--keep-index ");
builder.Append("-m \"");
builder.Append(message);
builder.Append("\"");
Args = builder.ToString();
return Exec();
}
public bool PushOnlyStaged(string message, bool keepIndex)
{
var builder = new StringBuilder();
builder.Append("stash push --staged ");
if (keepIndex)
builder.Append("--keep-index ");
builder.Append("-m \"");
builder.Append(message);
builder.Append("\"");
Args = builder.ToString();
return Exec();
}
public bool Apply(string name, bool restoreIndex)
{
var opts = restoreIndex ? "--index" : string.Empty;
Args = $"stash apply -q {opts} \"{name}\"";
return Exec();
}
public bool Pop(string name)
{
Args = $"stash pop -q {name}";
Args = $"stash pop -q --index \"{name}\"";
return Exec();
}
public bool Drop(string name)
{
Args = $"stash drop -q {name}";
Args = $"stash drop -q \"{name}\"";
return Exec();
}

View file

@ -1,14 +1,14 @@
using System;
using System;
namespace SourceGit.Commands
{
public class Statistics : Command
{
public Statistics(string repo)
public Statistics(string repo, int max)
{
WorkingDirectory = repo;
Context = repo;
Args = $"log --date-order --branches --remotes -40000 --pretty=format:\"%ct$%aN\"";
Args = $"log --date-order --branches --remotes -{max} --format=%ct$%aN±%aE";
}
public Models.Statistics Result()
@ -40,7 +40,7 @@ namespace SourceGit.Commands
if (dateEndIdx == -1)
return;
var dateStr = line.Substring(0, dateEndIdx);
var dateStr = line.AsSpan(0, dateEndIdx);
if (double.TryParse(dateStr, out var date))
statistics.AddCommit(line.Substring(dateEndIdx + 1), date);
}

View file

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SourceGit.Commands
{
@ -10,10 +11,9 @@ namespace SourceGit.Commands
Context = repo;
}
public bool Add(string url, string relativePath, bool recursive, Action<string> outputHandler)
public bool Add(string url, string relativePath, bool recursive)
{
_outputHandler = outputHandler;
Args = $"submodule add {url} \"{relativePath}\"";
Args = $"-c protocol.file.allow=always submodule add \"{url}\" \"{relativePath}\"";
if (!Exec())
return false;
@ -29,38 +29,38 @@ namespace SourceGit.Commands
}
}
public bool Update(string module, bool init, bool recursive, bool useRemote, Action<string> outputHandler)
public bool Update(List<string> modules, bool init, bool recursive, bool useRemote = false)
{
Args = "submodule update";
var builder = new StringBuilder();
builder.Append("submodule update");
if (init)
Args += " --init";
builder.Append(" --init");
if (recursive)
Args += " --recursive";
builder.Append(" --recursive");
if (useRemote)
Args += " --remote";
if (!string.IsNullOrEmpty(module))
Args += $" -- \"{module}\"";
builder.Append(" --remote");
if (modules.Count > 0)
{
builder.Append(" --");
foreach (var module in modules)
builder.Append($" \"{module}\"");
}
_outputHandler = outputHandler;
Args = builder.ToString();
return Exec();
}
public bool Delete(string relativePath)
public bool Deinit(string module, bool force)
{
Args = $"submodule deinit -f \"{relativePath}\"";
if (!Exec())
return false;
Args = $"rm -rf \"{relativePath}\"";
Args = force ? $"submodule deinit -f -- \"{module}\"" : $"submodule deinit -- \"{module}\"";
return Exec();
}
protected override void OnReadline(string line)
public bool Delete(string module)
{
_outputHandler?.Invoke(line);
Args = $"rm -rf \"{module}\"";
return Exec();
}
private Action<string> _outputHandler;
}
}

View file

@ -1,59 +1,51 @@
using System.Collections.Generic;
using System.IO;
using System.IO;
namespace SourceGit.Commands
{
public static class Tag
{
public static bool Add(string repo, string name, string basedOn)
public static bool Add(string repo, string name, string basedOn, Models.ICommandLog log)
{
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Args = $"tag {name} {basedOn}";
cmd.Args = $"tag --no-sign {name} {basedOn}";
cmd.Log = log;
return cmd.Exec();
}
public static bool Add(string repo, string name, string basedOn, string message, bool sign)
public static bool Add(string repo, string name, string basedOn, string message, bool sign, Models.ICommandLog log)
{
var param = sign ? "--sign -a" : "--no-sign -a";
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Args = $"tag {param} {name} {basedOn} ";
cmd.Log = log;
if (!string.IsNullOrEmpty(message))
{
string tmp = Path.GetTempFileName();
File.WriteAllText(tmp, message);
cmd.Args += $"-F \"{tmp}\"";
}
else
{
cmd.Args += $"-m {name}";
var succ = cmd.Exec();
File.Delete(tmp);
return succ;
}
cmd.Args += $"-m {name}";
return cmd.Exec();
}
public static bool Delete(string repo, string name, List<Models.Remote> remotes)
public static bool Delete(string repo, string name, Models.ICommandLog log)
{
var cmd = new Command();
cmd.WorkingDirectory = repo;
cmd.Context = repo;
cmd.Args = $"tag --delete {name}";
if (!cmd.Exec())
return false;
if (remotes != null)
{
foreach (var r in remotes)
{
new Push(repo, r.Name, name, true).Exec();
}
}
return true;
cmd.Log = log;
return cmd.Exec();
}
}
}

View file

@ -23,13 +23,11 @@ namespace SourceGit.Commands
_patchBuilder.Append(c.DataForAmend.ObjectHash);
_patchBuilder.Append("\t");
_patchBuilder.Append(c.OriginalPath);
_patchBuilder.Append("\n");
}
else if (c.Index == Models.ChangeState.Added)
{
_patchBuilder.Append("0 0000000000000000000000000000000000000000\t");
_patchBuilder.Append(c.Path);
_patchBuilder.Append("\n");
}
else if (c.Index == Models.ChangeState.Deleted)
{
@ -37,7 +35,6 @@ namespace SourceGit.Commands
_patchBuilder.Append(c.DataForAmend.ObjectHash);
_patchBuilder.Append("\t");
_patchBuilder.Append(c.Path);
_patchBuilder.Append("\n");
}
else
{
@ -46,8 +43,9 @@ namespace SourceGit.Commands
_patchBuilder.Append(c.DataForAmend.ObjectHash);
_patchBuilder.Append("\t");
_patchBuilder.Append(c.Path);
_patchBuilder.Append("\n");
}
_patchBuilder.Append("\n");
}
}

View file

@ -1,19 +0,0 @@
namespace SourceGit.Commands
{
public class Version : Command
{
public Version()
{
Args = "--version";
RaiseError = false;
}
public string Query()
{
var rs = ReadToEnd();
if (!rs.IsSuccess || string.IsNullOrWhiteSpace(rs.StdOut))
return string.Empty;
return rs.StdOut.Trim().Substring("git version ".Length);
}
}
}

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace SourceGit.Commands
{
@ -20,12 +21,13 @@ namespace SourceGit.Commands
var last = null as Models.Worktree;
if (rs.IsSuccess)
{
var lines = rs.StdOut.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
var lines = rs.StdOut.Split(['\r', '\n'], StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line.StartsWith("worktree ", StringComparison.Ordinal))
{
last = new Models.Worktree() { FullPath = line.Substring(9).Trim() };
last.RelativePath = Path.GetRelativePath(WorkingDirectory, last.FullPath);
worktrees.Add(last);
}
else if (line.StartsWith("bare", StringComparison.Ordinal))
@ -54,7 +56,7 @@ namespace SourceGit.Commands
return worktrees;
}
public bool Add(string fullpath, string name, bool createNew, string tracking, Action<string> outputHandler)
public bool Add(string fullpath, string name, bool createNew, string tracking)
{
Args = "worktree add ";
@ -73,15 +75,15 @@ namespace SourceGit.Commands
if (!string.IsNullOrEmpty(tracking))
Args += tracking;
else if (!string.IsNullOrEmpty(name) && !createNew)
Args += name;
_outputHandler = outputHandler;
return Exec();
}
public bool Prune(Action<string> outputHandler)
public bool Prune()
{
Args = "worktree prune -v";
_outputHandler = outputHandler;
return Exec();
}
@ -97,22 +99,14 @@ namespace SourceGit.Commands
return Exec();
}
public bool Remove(string fullpath, bool force, Action<string> outputHandler)
public bool Remove(string fullpath, bool force)
{
if (force)
Args = $"worktree remove -f \"{fullpath}\"";
else
Args = $"worktree remove \"{fullpath}\"";
_outputHandler = outputHandler;
return Exec();
}
protected override void OnReadline(string line)
{
_outputHandler?.Invoke(line);
}
private Action<string> _outputHandler = null;
}
}

View file

@ -1,4 +1,5 @@
using Avalonia.Data.Converters;
using Avalonia.Media;
namespace SourceGit.Converters
{
@ -6,5 +7,8 @@ namespace SourceGit.Converters
{
public static readonly FuncValueConverter<bool, double> ToPageTabWidth =
new FuncValueConverter<bool, double>(x => x ? 200 : double.NaN);
public static readonly FuncValueConverter<bool, FontWeight> IsBoldToFontWeight =
new FuncValueConverter<bool, FontWeight>(x => x ? FontWeight.Bold : FontWeight.Normal);
}
}

Some files were not shown because too many files have changed in this diff Show more