main at e9f8377 is the candidate for 1.1.1. Nothing is tagged. This issue holds what has to be decided and done before the tag, and the draft of the release notes. The checklist of the standards' release template is still to be worked through here (docs/RELEASING.md, step 1).
Where it stands
Everything planned for 1.1.1 is merged; Directory.Build.props says 1.1.1.
Gates on the tree of e9f8377, started from PowerShell: build with warnings as errors 0, engine 1,166, CLI 212, line coverage 100% on the three gated assemblies, format clean, UI suite 13 of 13, PSScriptAnalyzer clean.
Four independent reviews of the candidate (code, security, design, architecture), their findings fixed (#182, #183, #184) and checked again by the same reviewers. No blocker in code or security: no way found to lose data, disclose a token, or write outside a clone. Scores after the fixes: code 9, security 8, design 8, architecture 8 (target: 9 on each).
What holds the three at 8, in the reviewers' words: the updater checks nothing the release server cannot change (#189, accepted for 1.1.1 as T1); the decisions below; polish that was filed, not fixed (#192).
How 1.1.1 is published. A tag on git.kof22.com builds nothing today; the workflow that builds and signs runs on GitHub (#197). Either tag on GitHub and copy the signed assets to a release here (docs/RELEASING.md, steps 5 to 7), or wait for a pipeline here, or build and sign by hand.
Is git.kof22.com reachable from outside the local network, without signing in? From 1.1.1 on, the updater, the Scoop manifest, the Help links and the Share invitation point there. Three reviewers would not tag without the answer. docs/RELEASING.md step 2 is this check.
Where people without an account here report problems and vulnerabilities. Registration is closed; SECURITY.md names GitHub's private reporting; Help > Submit an issue leads to a sign-in page.
The gclo.Engine package.IGitClient.FetchAndPullAsync gained a parameter, which breaks implementers and callers, under a patch number. Publish to NuGet as 1.1.1 with the break stated, leave NUGET_PUBLISH off for this release, or number the release for the package.
Before the stable tag
The check of decision 2.
A rehearsal with two prereleases (docs/RELEASING.md step 3): both copied to git.kof22.com, the first installed, and its update to the second read from that server from a machine outside the network. 1.1.1 is the version that moves the updater; an install that has taken it looks nowhere else.
#56 (self-update on a dev-channel install) is the same test and can be closed by it.
Draft release notes
1.1.1 is a fixes release from a full review of the code, plus three things asked
for while trying it: a Sync all pass you can see, a table that follows the sync,
and a way to share the app.
If you have 1.1.0 installed
The project's home moved to git.kof22.com. Help, About, and the documentation
link there.
Updates come from git.kof22.com from this version on. 1.1.0
looks for updates on GitHub; if it does not offer you 1.1.1, install 1.1.1 once
from the releases page. After that the app updates itself.
CLI exit codes changed for some failures (see "Command line" below). Scripts
that test for exit code 70 should be checked.
New
Help > Share gclo by email opens a new message in your email program with an
invitation already written (what gclo is, where to download it, how to install
it). You add the address and send; gclo sends nothing. With no email program set
up, the text is shown and copied to the clipboard.
Sync all shows where it stands. A status row above the workspace says which
account is syncing, which of how many, and how far along it is, whichever
workspace you are looking at; it takes you to that account, and holds the result
when the pass is over. It replaces the dialog at the end.
The table follows the sync. By default, repositories in progress are on top,
then failed ones, then finished ones (latest first), then those waiting. When
the sync is over: failed first, then by name. A column you sort by yourself
still wins; a third click on its header returns to this order.
The activity log says when the window stopped responding, for how long, and
what was running.
Fixed
The window
The window no longer freezes while a large account syncs. Progress now reaches
it a few times a second instead of once per report: cloning 281 repositories
with the account on screen went from 23 freezes (11.6 s in total) to none with
the rows at rest.
Showing an account with hundreds of repositories is faster (fewer rows are built
ahead of what is visible).
The result bar after a sync is one row, with the one action that matters (Retry
failed, or Open folder). Open folder is also a toolbar button.
The account wizard asks for a token when the box is empty, instead of showing an
internal error.
A token saved, replaced, or removed while the app is open takes effect at the
next sync, without a restart.
An account's token is changed with Edit account…, which is now on the
account's page as well. The token box on that page takes no input any more: a
token typed there looked accepted and was not used. The page says why it cannot
load when the account has no token.
Sync all no longer shows a pass as finished and green when an account could
not be synced (no token, repositories that could not be loaded): the account is
marked in the pane and counted as needing attention. An account whose own sync
you canceled is not counted as synced, and a canceled pass says how many accounts
were not started.
Retry failed leaves your selection alone. Before, it selected the failed
rows, and the next sync covered only those.
Syncing and recovery
A pull is made only into a folder that is a clone of the listed repository, and
only over the listed URL.
Path recovery (for repositories with names Windows cannot create) never discards
local work, writes and deletes only inside the working tree, and delivers the
commits it reports.
A clone that was empty, cut off, or still ending is handled safely by the next
sync. An unfinished checkout is completed instead of being reported as up to
date. Nothing of yours in the folder is replaced or removed: where a file, a
link, or something you added with git add is in the way, the row fails and
names it. Two operations never work in one folder at once.
An empty clone follows the origin's default branch once the origin has
commits, unless you have put something into its folder or started a branch
there yourself.
Clone in WSL clones under a temporary name and moves the folder into place when
it is complete, so a clone that was cut off never looks like a finished one.
Failures are named for what they are: access refused, rate limited, the server
or the network unavailable.
Text from repositories and servers is shown with control characters made
visible, in the log and in everything the CLI prints.
A folder's own git configuration does not decide where a fetch goes: a URL
rewrite, an SSH program, a proxy, or a redirect setting in a folder's .git/config is refused with a message that names it. If you had set a proxy
for one clone that way, its row now fails until the setting is moved to your
global git configuration, which still applies.
Accounts and settings
accounts.json is safe when several gclo windows or CLI runs change it at once,
and a file that cannot be read for a moment is no longer treated as corrupt. A
backup (accounts.json.bak) is kept.
Command line
Exit codes: access, network and server failures now exit with 3 or 4 instead
of 70. gclo accounts exits with 2 for a storage failure (4 when the file is
busy). A canceled --dry-run exits with 1.
A relative --target is stored as an absolute path.
Ctrl+C lets a change to the accounts finish instead of leaving it half done.
The CLI's log follows GCLO_DATA_DIR. Log lines carry a UTC offset, and logs are
kept for 30 days.
For users of the gclo.Engine library
IGitClient.FetchAndPullAsync takes the expected URL as its first parameter
(url, path, token, cancellationToken). This is the fix for a pull that used
whatever origin a folder had; it changes the interface, so code that
implements or calls it must be changed.
The listers throw GitHubAccessException with the new kind Unavailable for
network and server failures, where those used to pass through as they were. ApplyRecoveryAsync refuses a clone that was checked out normally. A
repository named as git's own folder (.git) fails its row in SyncAsync on
every platform.
(To decide before publishing: whether the package goes to NuGet under 1.1.1.)
Known limits
Sync all syncs the repositories each account's page already lists. Use Refresh on the page to pick up repositories created since it was loaded.
After paths of a repository were resolved: if the origin later adds another
invalid path under a folder that was renamed, it cannot be resolved; delete the
folder and sync again (#186).
Rows that move in the table while a sync runs can cause short hitches (up to
about a third of a second in the worst case measured) because building a table
row is slow.
Repositories with very long branch names can fail with "path too long" inside .git.
After a checkout that was cut off: if you then ran git in that folder yourself,
a file that was only half written can be left as it is (git shows it as
changed); and if the origin rewrote its history meanwhile, files of the old
history stay in the folder as untracked files.
Filing an issue on git.kof22.com needs an account there.
Verifying a release
As before: every asset is listed in SHA256SUMS, and the installer and the
executables are Authenticode-signed.
`main` at e9f8377 is the candidate for 1.1.1. Nothing is tagged. This issue holds what has to be decided and done before the tag, and the draft of the release notes. The checklist of the standards' release template is still to be worked through here (`docs/RELEASING.md`, step 1).
## Where it stands
- Everything planned for 1.1.1 is merged; `Directory.Build.props` says 1.1.1.
- Gates on the tree of e9f8377, started from PowerShell: build with warnings as errors 0, engine 1,166, CLI 212, line coverage 100% on the three gated assemblies, format clean, UI suite 13 of 13, PSScriptAnalyzer clean.
- Four independent reviews of the candidate (code, security, design, architecture), their findings fixed (#182, #183, #184) and checked again by the same reviewers. No blocker in code or security: no way found to lose data, disclose a token, or write outside a clone. Scores after the fixes: code 9, security 8, design 8, architecture 8 (target: 9 on each).
- What holds the three at 8, in the reviewers' words: the updater checks nothing the release server cannot change (#189, accepted for 1.1.1 as T1); the decisions below; polish that was filed, not fixed (#192).
- Left for 1.2.0, on the tracker: #178 to #181 and #186 to #197.
## To decide (owner)
1. **How 1.1.1 is published.** A tag on git.kof22.com builds nothing today; the workflow that builds and signs runs on GitHub (#197). Either tag on GitHub and copy the signed assets to a release here (`docs/RELEASING.md`, steps 5 to 7), or wait for a pipeline here, or build and sign by hand.
2. **Is git.kof22.com reachable from outside the local network, without signing in?** From 1.1.1 on, the updater, the Scoop manifest, the Help links and the Share invitation point there. Three reviewers would not tag without the answer. `docs/RELEASING.md` step 2 is this check.
3. **Where people without an account here report problems and vulnerabilities.** Registration is closed; `SECURITY.md` names GitHub's private reporting; Help > Submit an issue leads to a sign-in page.
4. **The `gclo.Engine` package.** `IGitClient.FetchAndPullAsync` gained a parameter, which breaks implementers and callers, under a patch number. Publish to NuGet as 1.1.1 with the break stated, leave `NUGET_PUBLISH` off for this release, or number the release for the package.
## Before the stable tag
- The check of decision 2.
- A rehearsal with two prereleases (`docs/RELEASING.md` step 3): both copied to git.kof22.com, the first installed, and its update to the second read from that server from a machine outside the network. 1.1.1 is the version that moves the updater; an install that has taken it looks nowhere else.
- #56 (self-update on a dev-channel install) is the same test and can be closed by it.
## Draft release notes
1.1.1 is a fixes release from a full review of the code, plus three things asked
for while trying it: a Sync all pass you can see, a table that follows the sync,
and a way to share the app.
## If you have 1.1.0 installed
- **The project's home moved to git.kof22.com.** Help, About, and the documentation
link there.
- **Updates come from git.kof22.com from this version on.** 1.1.0
looks for updates on GitHub; if it does not offer you 1.1.1, install 1.1.1 once
from the releases page. After that the app updates itself.
- **CLI exit codes changed** for some failures (see "Command line" below). Scripts
that test for exit code 70 should be checked.
## New
- **Help > Share gclo by email** opens a new message in your email program with an
invitation already written (what gclo is, where to download it, how to install
it). You add the address and send; gclo sends nothing. With no email program set
up, the text is shown and copied to the clipboard.
- **Sync all shows where it stands.** A status row above the workspace says which
account is syncing, which of how many, and how far along it is, whichever
workspace you are looking at; it takes you to that account, and holds the result
when the pass is over. It replaces the dialog at the end.
- **The table follows the sync.** By default, repositories in progress are on top,
then failed ones, then finished ones (latest first), then those waiting. When
the sync is over: failed first, then by name. A column you sort by yourself
still wins; a third click on its header returns to this order.
- **The activity log says when the window stopped responding**, for how long, and
what was running.
## Fixed
### The window
- The window no longer freezes while a large account syncs. Progress now reaches
it a few times a second instead of once per report: cloning 281 repositories
with the account on screen went from 23 freezes (11.6 s in total) to none with
the rows at rest.
- Showing an account with hundreds of repositories is faster (fewer rows are built
ahead of what is visible).
- The result bar after a sync is one row, with the one action that matters (Retry
failed, or Open folder). Open folder is also a toolbar button.
- The account wizard asks for a token when the box is empty, instead of showing an
internal error.
- A token saved, replaced, or removed while the app is open takes effect at the
next sync, without a restart.
- An account's token is changed with **Edit account…**, which is now on the
account's page as well. The token box on that page takes no input any more: a
token typed there looked accepted and was not used. The page says why it cannot
load when the account has no token.
- **Sync all** no longer shows a pass as finished and green when an account could
not be synced (no token, repositories that could not be loaded): the account is
marked in the pane and counted as needing attention. An account whose own sync
you canceled is not counted as synced, and a canceled pass says how many accounts
were not started.
- **Retry failed** leaves your selection alone. Before, it selected the failed
rows, and the next sync covered only those.
### Syncing and recovery
- A pull is made only into a folder that is a clone of the listed repository, and
only over the listed URL.
- Path recovery (for repositories with names Windows cannot create) never discards
local work, writes and deletes only inside the working tree, and delivers the
commits it reports.
- A clone that was empty, cut off, or still ending is handled safely by the next
sync. An unfinished checkout is completed instead of being reported as up to
date. Nothing of yours in the folder is replaced or removed: where a file, a
link, or something you added with `git add` is in the way, the row fails and
names it. Two operations never work in one folder at once.
- An empty clone follows the origin's default branch once the origin has
commits, unless you have put something into its folder or started a branch
there yourself.
- Clone in WSL clones under a temporary name and moves the folder into place when
it is complete, so a clone that was cut off never looks like a finished one.
- Failures are named for what they are: access refused, rate limited, the server
or the network unavailable.
- Text from repositories and servers is shown with control characters made
visible, in the log and in everything the CLI prints.
- A folder's own git configuration does not decide where a fetch goes: a URL
rewrite, an SSH program, a proxy, or a redirect setting in a folder's
`.git/config` is refused with a message that names it. If you had set a proxy
for one clone that way, its row now fails until the setting is moved to your
global git configuration, which still applies.
### Accounts and settings
- `accounts.json` is safe when several gclo windows or CLI runs change it at once,
and a file that cannot be read for a moment is no longer treated as corrupt. A
backup (`accounts.json.bak`) is kept.
### Command line
- **Exit codes:** access, network and server failures now exit with 3 or 4 instead
of 70. `gclo accounts` exits with 2 for a storage failure (4 when the file is
busy). A canceled `--dry-run` exits with 1.
- A relative `--target` is stored as an absolute path.
- Ctrl+C lets a change to the accounts finish instead of leaving it half done.
- The CLI's log follows `GCLO_DATA_DIR`. Log lines carry a UTC offset, and logs are
kept for 30 days.
## For users of the gclo.Engine library
- **`IGitClient.FetchAndPullAsync` takes the expected URL as its first parameter**
(`url, path, token, cancellationToken`). This is the fix for a pull that used
whatever `origin` a folder had; it changes the interface, so code that
implements or calls it must be changed.
- The listers throw `GitHubAccessException` with the new kind `Unavailable` for
network and server failures, where those used to pass through as they were.
`ApplyRecoveryAsync` refuses a clone that was checked out normally. A
repository named as git's own folder (`.git`) fails its row in `SyncAsync` on
every platform.
- New: `DisplayText`, `PathRecovery.EffectivePathOf`, `FileActivityLog.RetentionDays`.
- (To decide before publishing: whether the package goes to NuGet under 1.1.1.)
## Known limits
- Sync all syncs the repositories each account's page already lists. Use
**Refresh** on the page to pick up repositories created since it was loaded.
- After paths of a repository were resolved: if the origin later adds another
invalid path under a folder that was renamed, it cannot be resolved; delete the
folder and sync again (#186).
- Rows that move in the table while a sync runs can cause short hitches (up to
about a third of a second in the worst case measured) because building a table
row is slow.
- Repositories with very long branch names can fail with "path too long" inside
`.git`.
- After a checkout that was cut off: if you then ran git in that folder yourself,
a file that was only half written can be left as it is (git shows it as
changed); and if the origin rewrote its history meanwhile, files of the old
history stay in the folder as untracked files.
- Filing an issue on git.kof22.com needs an account there.
## Verifying a release
As before: every asset is listed in `SHA256SUMS`, and the installer and the
executables are Authenticode-signed.
git.kof22.com is public. The releases page can be opened from outside the network without signing in.
How it is published: wait for a pipeline on git.kof22.com that builds and signs (#197). No tag on GitHub for this release.
Reports from people without an account: Help stays pointed at git.kof22.com; registration will be opened over time. No change to the app.
One release, numbered 1.2. There is no separate 1.1.1: the fixes on main and the Gitea work go out together as 1.2. That also settles the gclo.Engine package: the changed method ships under a new minor number.
Two windows (#216): one gclo window per data folder; a second start brings the first to the front.
Live test against a Gitea server: approved, read-only, and done (below).
Merging: the six reviewed pull requests of #201 are merged into main now, in order (#203, #205, #207, #210, #214, #215). The rule "nothing merges before 1.1.1 is tagged" has nothing left to wait for.
Live test against git.kof22.com (CLI built from #215, read-only)
gclo orgs --server: the organizations of the token listed.
gclo repos --server --org: an organization with 89 repositories listed (more than one page), and a user account.
gclo sync: a private repository cloned, then updated on a second run. (A first try used a repository that turned out to be public, which proves nothing about the token; repeated with one that cannot be read without it.)
A wrong token: exit 3, "git.kof22.com rejected the token (401). Check that the access token is complete and has not been deleted or expired."
The token was found in neither the activity log nor the clone.
Not covered: the token was a sign-in (OAuth) token, not a hand-made access token; and a token without organization rights was not tried, because making one changes the server.
What this issue becomes
The release issue for 1.2.0. The draft notes above are for the fixes; the Gitea part is added when the six are merged. Nothing is tagged until #197 is done.
## Owner's decisions (2026-11-11)
1. **git.kof22.com is public.** The releases page can be opened from outside the network without signing in.
2. **How it is published:** wait for a pipeline on git.kof22.com that builds and signs (#197). No tag on GitHub for this release.
3. **Reports from people without an account:** Help stays pointed at git.kof22.com; registration will be opened over time. No change to the app.
4. **One release, numbered 1.2.** There is no separate 1.1.1: the fixes on `main` and the Gitea work go out together as 1.2. That also settles the `gclo.Engine` package: the changed method ships under a new minor number.
5. **Two windows (#216):** one gclo window per data folder; a second start brings the first to the front.
6. **Live test against a Gitea server:** approved, read-only, and done (below).
7. **Merging:** the six reviewed pull requests of #201 are merged into `main` now, in order (#203, #205, #207, #210, #214, #215). The rule "nothing merges before 1.1.1 is tagged" has nothing left to wait for.
## Live test against git.kof22.com (CLI built from #215, read-only)
- `gclo orgs --server`: the organizations of the token listed.
- `gclo repos --server --org`: an organization with 89 repositories listed (more than one page), and a user account.
- `gclo sync`: a **private** repository cloned, then updated on a second run. (A first try used a repository that turned out to be public, which proves nothing about the token; repeated with one that cannot be read without it.)
- A wrong token: exit 3, "git.kof22.com rejected the token (401). Check that the access token is complete and has not been deleted or expired."
- The token was found in neither the activity log nor the clone.
Not covered: the token was a sign-in (OAuth) token, not a hand-made access token; and a token without organization rights was not tried, because making one changes the server.
## What this issue becomes
The release issue for **1.2.0**. The draft notes above are for the fixes; the Gitea part is added when the six are merged. Nothing is tagged until #197 is done.
The six pull requests of #201 are merged; main is d5d4f67 and says 1.2.0. Its files are exactly those of the commit that passed the gates (engine and view models 1,476, CLI 249, line coverage 100% on the three gated assemblies, format clean, UI suite 18 of 18).
Draft release notes, added for 1.2.0: Gitea beside GitHub
gclo works with Gitea servers as well as GitHub. Everywhere a place is chosen, the two are offered side by side, named GitHub and Gitea. For Gitea you enter the address of your server (HTTPS only).
Start page (Quick Sync): choose GitHub or Gitea, enter a token, press Find to list the organizations the token can see. Nothing is preselected, and no token is sent anywhere until you press Find or Load repositories.
Accounts: the Add account wizard asks where the repositories are. An account stays on the place it was made for; its token is only ever sent there.
Settings: a default token for GitHub and one for a Gitea server (address and token together). A default token is used only for the place it was saved for.
The app opens where you left it: the workspace that was open, and Quick Sync's last connection (never a token).
Command line:--forge github|gitea and --server <address> on sync, repos, orgs and accounts add. With --server, the token is read from GITEA_TOKEN instead of GITHUB_TOKEN; one is never used for the other.
The button at the top of the navigation pane closes the pane to its icons and opens it again.
Older versions and your accounts: accounts on a Gitea server are kept in a file of their own, so an older gclo that is still installed neither sees nor damages them.
For people who use the gclo.Engine library
IGitClient.FetchAndPullAsync gained a parameter (from the fixes), and there are new types for other forges (ForgeKind, ForgeEndpoint, ForgeAccessException, the Gitea listers). GitHubAccessException still compiles and still catches.
Still open before a tag
#197: a pipeline on git.kof22.com that builds and signs. Nothing is tagged before it exists (owner's decision).
#216: one gclo window per data folder (decided; to be built).
The rehearsal in "Before the stable tag" above, with the version numbers changed to 1.2.0.
Not tried live: a hand-made Gitea access token with fewer rights than the sign-in token used in the live test.
The six pull requests of #201 are merged; `main` is `d5d4f67` and says 1.2.0. Its files are exactly those of the commit that passed the gates (engine and view models 1,476, CLI 249, line coverage 100% on the three gated assemblies, format clean, UI suite 18 of 18).
## Draft release notes, added for 1.2.0: Gitea beside GitHub
- **gclo works with Gitea servers as well as GitHub.** Everywhere a place is chosen, the two are offered side by side, named **GitHub** and **Gitea**. For Gitea you enter the address of your server (HTTPS only).
- **Start page (Quick Sync):** choose GitHub or Gitea, enter a token, press **Find** to list the organizations the token can see. Nothing is preselected, and no token is sent anywhere until you press Find or Load repositories.
- **Accounts:** the Add account wizard asks where the repositories are. An account stays on the place it was made for; its token is only ever sent there.
- **Settings:** a default token for GitHub and one for a Gitea server (address and token together). A default token is used only for the place it was saved for.
- **The app opens where you left it:** the workspace that was open, and Quick Sync's last connection (never a token).
- **Command line:** `--forge github|gitea` and `--server <address>` on `sync`, `repos`, `orgs` and `accounts add`. With `--server`, the token is read from `GITEA_TOKEN` instead of `GITHUB_TOKEN`; one is never used for the other.
- **The button at the top of the navigation pane** closes the pane to its icons and opens it again.
- **Older versions and your accounts:** accounts on a Gitea server are kept in a file of their own, so an older gclo that is still installed neither sees nor damages them.
## For people who use the `gclo.Engine` library
- `IGitClient.FetchAndPullAsync` gained a parameter (from the fixes), and there are new types for other forges (`ForgeKind`, `ForgeEndpoint`, `ForgeAccessException`, the Gitea listers). `GitHubAccessException` still compiles and still catches.
## Still open before a tag
- #197: a pipeline on git.kof22.com that builds and signs. Nothing is tagged before it exists (owner's decision).
- #216: one gclo window per data folder (decided; to be built).
- The rehearsal in "Before the stable tag" above, with the version numbers changed to 1.2.0.
- Not tried live: a hand-made Gitea access token with fewer rights than the sign-in token used in the live test.
james.maes
changed title from Release v1.1.1 to Release v1.2.02026-11-11 22:29:08 +00:00
State at the end of 2026-11-11: main is e2e099e and is the 1.2.0 candidate. Since the six Gitea pull requests: #217 (one gclo window per data folder, closes#216), #219 (the documents name 1.2.0, closes#218) and #220 (the build on the Windows runner here). Gates on the tree of #217: engine and view models 1,483, CLI 249, line coverage 100%, format clean, UI suite 19 of 19.
Asked again today, the owner kept the decision: nothing is tagged until the pipeline here builds and signs (#197, in work).
Add to the draft notes: gclo opens one window. Starting it again brings the open window to the front.
Still owed before the tag: the rehearsal with two prereleases above; docs/RELEASING.md says 1.1.1 in three places (noted on #197); a live run with a hand-made Gitea access token of fewer rights than the sign-in token used.
State at the end of 2026-11-11: main is e2e099e and is the 1.2.0 candidate. Since the six Gitea pull requests: #217 (one gclo window per data folder, closes #216), #219 (the documents name 1.2.0, closes #218) and #220 (the build on the Windows runner here). Gates on the tree of #217: engine and view models 1,483, CLI 249, line coverage 100%, format clean, UI suite 19 of 19.
Asked again today, the owner kept the decision: nothing is tagged until the pipeline here builds and signs (#197, in work).
Add to the draft notes: **gclo opens one window.** Starting it again brings the open window to the front.
Still owed before the tag: the rehearsal with two prereleases above; docs/RELEASING.md says 1.1.1 in three places (noted on #197); a live run with a hand-made Gitea access token of fewer rights than the sign-in token used.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
mainate9f8377is the candidate for 1.1.1. Nothing is tagged. This issue holds what has to be decided and done before the tag, and the draft of the release notes. The checklist of the standards' release template is still to be worked through here (docs/RELEASING.md, step 1).Where it stands
Directory.Build.propssays 1.1.1.e9f8377, started from PowerShell: build with warnings as errors 0, engine 1,166, CLI 212, line coverage 100% on the three gated assemblies, format clean, UI suite 13 of 13, PSScriptAnalyzer clean.To decide (owner)
docs/RELEASING.md, steps 5 to 7), or wait for a pipeline here, or build and sign by hand.docs/RELEASING.mdstep 2 is this check.SECURITY.mdnames GitHub's private reporting; Help > Submit an issue leads to a sign-in page.gclo.Enginepackage.IGitClient.FetchAndPullAsyncgained a parameter, which breaks implementers and callers, under a patch number. Publish to NuGet as 1.1.1 with the break stated, leaveNUGET_PUBLISHoff for this release, or number the release for the package.Before the stable tag
docs/RELEASING.mdstep 3): both copied to git.kof22.com, the first installed, and its update to the second read from that server from a machine outside the network. 1.1.1 is the version that moves the updater; an install that has taken it looks nowhere else.Draft release notes
1.1.1 is a fixes release from a full review of the code, plus three things asked
for while trying it: a Sync all pass you can see, a table that follows the sync,
and a way to share the app.
If you have 1.1.0 installed
link there.
looks for updates on GitHub; if it does not offer you 1.1.1, install 1.1.1 once
from the releases page. After that the app updates itself.
that test for exit code 70 should be checked.
New
invitation already written (what gclo is, where to download it, how to install
it). You add the address and send; gclo sends nothing. With no email program set
up, the text is shown and copied to the clipboard.
account is syncing, which of how many, and how far along it is, whichever
workspace you are looking at; it takes you to that account, and holds the result
when the pass is over. It replaces the dialog at the end.
then failed ones, then finished ones (latest first), then those waiting. When
the sync is over: failed first, then by name. A column you sort by yourself
still wins; a third click on its header returns to this order.
what was running.
Fixed
The window
it a few times a second instead of once per report: cloning 281 repositories
with the account on screen went from 23 freezes (11.6 s in total) to none with
the rows at rest.
ahead of what is visible).
failed, or Open folder). Open folder is also a toolbar button.
internal error.
next sync, without a restart.
account's page as well. The token box on that page takes no input any more: a
token typed there looked accepted and was not used. The page says why it cannot
load when the account has no token.
not be synced (no token, repositories that could not be loaded): the account is
marked in the pane and counted as needing attention. An account whose own sync
you canceled is not counted as synced, and a canceled pass says how many accounts
were not started.
rows, and the next sync covered only those.
Syncing and recovery
only over the listed URL.
local work, writes and deletes only inside the working tree, and delivers the
commits it reports.
sync. An unfinished checkout is completed instead of being reported as up to
date. Nothing of yours in the folder is replaced or removed: where a file, a
link, or something you added with
git addis in the way, the row fails andnames it. Two operations never work in one folder at once.
commits, unless you have put something into its folder or started a branch
there yourself.
it is complete, so a clone that was cut off never looks like a finished one.
or the network unavailable.
visible, in the log and in everything the CLI prints.
rewrite, an SSH program, a proxy, or a redirect setting in a folder's
.git/configis refused with a message that names it. If you had set a proxyfor one clone that way, its row now fails until the setting is moved to your
global git configuration, which still applies.
Accounts and settings
accounts.jsonis safe when several gclo windows or CLI runs change it at once,and a file that cannot be read for a moment is no longer treated as corrupt. A
backup (
accounts.json.bak) is kept.Command line
of 70.
gclo accountsexits with 2 for a storage failure (4 when the file isbusy). A canceled
--dry-runexits with 1.--targetis stored as an absolute path.GCLO_DATA_DIR. Log lines carry a UTC offset, and logs arekept for 30 days.
For users of the gclo.Engine library
IGitClient.FetchAndPullAsynctakes the expected URL as its first parameter(
url, path, token, cancellationToken). This is the fix for a pull that usedwhatever
origina folder had; it changes the interface, so code thatimplements or calls it must be changed.
GitHubAccessExceptionwith the new kindUnavailablefornetwork and server failures, where those used to pass through as they were.
ApplyRecoveryAsyncrefuses a clone that was checked out normally. Arepository named as git's own folder (
.git) fails its row inSyncAsynconevery platform.
DisplayText,PathRecovery.EffectivePathOf,FileActivityLog.RetentionDays.Known limits
Refresh on the page to pick up repositories created since it was loaded.
invalid path under a folder that was renamed, it cannot be resolved; delete the
folder and sync again (#186).
about a third of a second in the worst case measured) because building a table
row is slow.
.git.a file that was only half written can be left as it is (git shows it as
changed); and if the origin rewrote its history meanwhile, files of the old
history stay in the folder as untracked files.
Verifying a release
As before: every asset is listed in
SHA256SUMS, and the installer and theexecutables are Authenticode-signed.
Owner's decisions (2026-11-11)
mainand the Gitea work go out together as 1.2. That also settles thegclo.Enginepackage: the changed method ships under a new minor number.mainnow, in order (#203, #205, #207, #210, #214, #215). The rule "nothing merges before 1.1.1 is tagged" has nothing left to wait for.Live test against git.kof22.com (CLI built from #215, read-only)
gclo orgs --server: the organizations of the token listed.gclo repos --server --org: an organization with 89 repositories listed (more than one page), and a user account.gclo sync: a private repository cloned, then updated on a second run. (A first try used a repository that turned out to be public, which proves nothing about the token; repeated with one that cannot be read without it.)Not covered: the token was a sign-in (OAuth) token, not a hand-made access token; and a token without organization rights was not tried, because making one changes the server.
What this issue becomes
The release issue for 1.2.0. The draft notes above are for the fixes; the Gitea part is added when the six are merged. Nothing is tagged until #197 is done.
The six pull requests of #201 are merged;
mainisd5d4f67and says 1.2.0. Its files are exactly those of the commit that passed the gates (engine and view models 1,476, CLI 249, line coverage 100% on the three gated assemblies, format clean, UI suite 18 of 18).Draft release notes, added for 1.2.0: Gitea beside GitHub
--forge github|giteaand--server <address>onsync,repos,orgsandaccounts add. With--server, the token is read fromGITEA_TOKENinstead ofGITHUB_TOKEN; one is never used for the other.For people who use the
gclo.EnginelibraryIGitClient.FetchAndPullAsyncgained a parameter (from the fixes), and there are new types for other forges (ForgeKind,ForgeEndpoint,ForgeAccessException, the Gitea listers).GitHubAccessExceptionstill compiles and still catches.Still open before a tag
Release v1.1.1to Release v1.2.0State at the end of 2026-11-11: main is
e2e099eand is the 1.2.0 candidate. Since the six Gitea pull requests: #217 (one gclo window per data folder, closes #216), #219 (the documents name 1.2.0, closes #218) and #220 (the build on the Windows runner here). Gates on the tree of #217: engine and view models 1,483, CLI 249, line coverage 100%, format clean, UI suite 19 of 19.Asked again today, the owner kept the decision: nothing is tagged until the pipeline here builds and signs (#197, in work).
Add to the draft notes: gclo opens one window. Starting it again brings the open window to the front.
Still owed before the tag: the rehearsal with two prereleases above; docs/RELEASING.md says 1.1.1 in three places (noted on #197); a live run with a hand-made Gitea access token of fewer rights than the sign-in token used.