gitforge/modules/git
Mathieu Fenniak 958cface13 fix: terminate git (& other) subcommands gracefully on context timeout/cancellation (#13263)
By default, when you create an `exec.CommandContext` in Go, when the context is cancelled or timed out, Go will SIGKILL the subprocess which does not allow the subprocess to perform any cleanup work.  As some git operations in Forgejo will be linked to the current HTTP context, and the current HTTP context will be closed when the HTTP client disconnects, this can theoretically cause SIGKILLs when locks are being held.

This PR contains two fixes:
- Change the behaviour of all subprocesses that Forgejo creates to use a graceful termination, SIGTERM'ing the process, and then SIGKILL'ing it after a timeout.
- Fixes a bug where previously all subprocesses are setup in a process group (by 1d04e8641d), but they were never *killed* in a process group, preventing child processes from receiving these termination signals.  Both SIGTERM and SIGKILL are sent to the process group.

Introduces new configuration setting which controls subcommand graceful timeouts.  If a subprocess does not shutdown from SIGTERM within `[server].SUBPROCESS_TERMINATE_GRACE` (default 5 seconds), then an error will be logged, and the process will be SIGKILL'd.  The error is:
```
2026/07/01 08:31:20 modules/log/init.go:38:func2() [E] Subprocess pid=3790963 (/nix/store/c0277k5giric1mn9dklllavbzvxl6hzb-git-2.53.0/bin/git blame --porcelain 8ee7e7c32b -- options/locale/locale_en-US.ini) failed to terminate from SIGTERM after grace period 0s, and was sent SIGKILL. The subprocess termination may leave incomplete state on the server, such as lock files. `[server].SUBPROCESS_TERMINATE_GRACE` can be changed to give subprocesses more time to cleanly exit.
```

(This was produced on a live server by setting SUBPROCESS_TERMINATE_GRACE to zero seconds, loading a page that does a `git blame`, and hitting escape in the browser quickly.)

### Tests for Go changes

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
  - [x] `make pr-go` before pushing

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
    - Will create a documentation PR with new config settings.
- [ ] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [x] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [ ] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13263
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
2026-07-01 20:26:02 +02:00
..
foreachref chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
internal
pipeline
pushoptions chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
tests/repos fix: always include files set to be detectable for language stats (#11685) 2026-04-18 00:56:08 +02:00
url Update dependency go to v1.25 (forgejo) (#8908) 2025-10-08 15:57:37 +02:00
batch.go
batch_reader.go chore: handle error types consistently (#9873) 2026-03-06 00:48:06 +01:00
blame.go chore: make use of go1.26 features (#12369) 2026-05-01 22:51:48 +02:00
blame_sha256_test.go
blame_test.go
blob.go chore: use io.ReadFull instead of io.ReadAll for DataAsync (#12795) 2026-05-28 23:51:15 +02:00
blob_test.go chore: use io.ReadFull instead of io.ReadAll for DataAsync (#12795) 2026-05-28 23:51:15 +02:00
command.go fix: terminate git (& other) subcommands gracefully on context timeout/cancellation (#13263) 2026-07-01 20:26:02 +02:00
command_race_test.go
command_test.go
commit.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
commit_info.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
commit_info_test.go
commit_reader.go feat: include non-conventional headers in payload for git signatures (#9558) 2025-10-14 02:18:01 +02:00
commit_sha256_test.go
commit_test.go chore: two small refactors in git module (#10109) 2025-11-15 13:24:00 +01:00
diff.go fix: multiline comment invalidation (#12950) 2026-06-09 03:07:56 +02:00
diff_compare.go feat: improve checking if diffs differ (#8451) 2025-07-16 18:19:27 +02:00
diff_compare_test.go chore: fix typos throughout the codebase (#10753) 2026-01-26 22:57:33 +01:00
diff_test.go fix: multiline comment invalidation (#12950) 2026-06-09 03:07:56 +02:00
error.go
fetch.go chore: unify the usage of CryptoRandomString (#10110) 2025-11-15 13:24:53 +01:00
fetch_test.go fix: always include files set to be detectable for language stats (#11685) 2026-04-18 00:56:08 +02:00
git.go chore: remove some git configuration options (#12681) 2026-05-24 12:34:59 +02:00
git_test.go
grep.go feat: add support to opt-in for fuzzy search (#10378) 2025-12-17 13:51:48 +01:00
grep_test.go fix: always include files set to be detectable for language stats (#11685) 2026-04-18 00:56:08 +02:00
hook.go fix(git): treat missing hooks folder the same as missing hook file (#12833) 2026-05-31 14:41:28 +02:00
hook_generate.go feat: replace repo based server-side hooks with centralised hooks (#10397) 2026-04-27 22:34:46 +02:00
last_commit_cache.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
log_name_status.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
notes.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
notes_test.go chore: simplify GetNote (#9985) 2025-11-06 13:23:35 +01:00
object_format.go
object_id.go
object_id_test.go
object_signature.go
parse.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
parse_test.go fix: do better parsing of file modes (#9161) 2025-09-04 21:58:12 +02:00
README.md
ref.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
ref_test.go
remote.go
repo.go fix: compliance with [migrations].ALLOWED_DOMAINS, ...BLOCKED_DOMAINS, and ....ALLOW_LOCALNETWORKS for git & LFS ops (#13129) 2026-06-23 23:40:25 +02:00
repo_archive.go
repo_attribute.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
repo_attribute_test.go
repo_base.go
repo_base_test.go
repo_blame.go fix: relocate PR review comments using git blame --reverse, improving comment placement (#12015) 2026-04-11 21:45:39 +02:00
repo_blame_test.go fix: relocate PR review comments using git blame --reverse, improving comment placement (#12015) 2026-04-11 21:45:39 +02:00
repo_blob_test.go
repo_branch.go
repo_branch_test.go
repo_commit.go fix: check valid commit ids for existence (#12963) 2026-06-29 17:21:55 +02:00
repo_commit_test.go fix: check valid commit ids for existence (#12963) 2026-06-29 17:21:55 +02:00
repo_commitgraph.go
repo_compare.go fix: detect renames when using diff-tree (#11038) 2026-01-25 15:51:18 +01:00
repo_compare_test.go fix: detect renames when using diff-tree (#11038) 2026-01-25 15:51:18 +01:00
repo_gpg.go
repo_hook.go
repo_index.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
repo_language_stats.go fix: always include files set to be detectable for language stats (#11685) 2026-04-18 00:56:08 +02:00
repo_language_stats_test.go fix: always include files set to be detectable for language stats (#11685) 2026-04-18 00:56:08 +02:00
repo_object.go
repo_ref.go
repo_ref_test.go
repo_stats.go ci: detect and prevent empty case statements in Go code (#11593) 2026-03-10 02:50:28 +01:00
repo_stats_test.go
repo_tag.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
repo_tag_test.go chore: require.ErrorContains() is intended, but require.Errorf() is used (#11035) 2026-01-25 19:48:15 +01:00
repo_test.go Skip sha256 repo tests if sha256 not supported (#13018) 2026-06-09 16:07:47 +02:00
repo_tree.go
signature.go
signature_test.go
submodule.go fix: internal server error on a large .gitmodules (#10744) 2026-01-10 10:44:59 +01:00
submodule_test.go git/commit: re-implement submodules file reader (#8438) 2025-07-15 00:20:00 +02:00
tag.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
tag_test.go
tree.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
tree_blob.go git/commit: re-implement submodules file reader (#8438) 2025-07-15 00:20:00 +02:00
tree_entry.go fix: "Follow symlink" to work with arbitrary links (#12246) 2026-04-27 23:54:21 +02:00
tree_entry_mode.go
tree_entry_test.go fix: "Follow symlink" to work with arbitrary links (#12246) 2026-04-27 23:54:21 +02:00
tree_test.go chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
utils.go fix(git): treat missing hooks folder the same as missing hook file (#12833) 2026-05-31 14:41:28 +02:00
utils_test.go

Git Module

This module is merged from https://github.com/go-gitea/git which is a Go module to access Git through shell commands. Now it's a part of gitea's main repository for easier pull request.