2026-04-24 07:57:33 +01:00
|
|
|
# Forgejo integration
|
|
|
|
|
|
2026-04-25 07:26:00 +01:00
|
|
|
This directory contains assets for the ifcurl preview extension. The features
|
|
|
|
|
split into two tiers by what infrastructure they require.
|
2026-04-24 07:57:33 +01:00
|
|
|
|
2026-04-25 07:26:00 +01:00
|
|
|
## Feature overview
|
|
|
|
|
|
|
|
|
|
| Feature | What it needs | Forgejo rebuild? |
|
|
|
|
|
|---|---|---|
|
2026-04-27 08:25:34 +01:00
|
|
|
| "View in 3D" button on file/history pages | `ifcurl.js` + ifcurl service | No |
|
2026-04-25 07:26:00 +01:00
|
|
|
| Browser IFC viewer | `viewer.html` static asset | No |
|
2026-04-27 08:25:34 +01:00
|
|
|
| PR diff 3D render | `ifcurl.js` + ifcurl service + **Nginx proxy** | No |
|
|
|
|
|
| `[title](ifc://...)` links in markdown → inline preview | `ifcurl.js` + ifcurl service + **Nginx proxy** | No |
|
2026-05-17 11:28:38 +01:00
|
|
|
| Bare `ifc://...` text in markdown → inline preview | `ifcurl.js` (JS text-node linkification) | No |
|
2026-04-25 07:26:00 +01:00
|
|
|
|
2026-05-17 11:28:38 +01:00
|
|
|
All features work with static asset deployment only — no Forgejo rebuild required.
|
|
|
|
|
`ifcurl.js` handles both `<a href="ifc://...">` links produced by Goldmark's
|
|
|
|
|
standard link parser and bare `ifc://...` text nodes, replacing both with preview
|
|
|
|
|
figures at page load.
|
2026-04-25 07:26:00 +01:00
|
|
|
|
2026-05-17 11:28:38 +01:00
|
|
|
**Bare URL caveat:** bare `ifc://` URLs where the path or query parameters
|
|
|
|
|
contain matched underscores (e.g. `_model_v2.ifc`) may be split by Goldmark's
|
|
|
|
|
emphasis parser before `ifcurl.js` can linkify them. Use the explicit
|
|
|
|
|
`[label](ifc://...)` form in those cases — the viewer's **Issue** button always
|
|
|
|
|
generates this safe form.
|
2026-04-25 07:26:00 +01:00
|
|
|
|
|
|
|
|
The PR diff feature requires a **reverse proxy** (e.g. Nginx) to expose the
|
|
|
|
|
ifcurl service at the same origin as Forgejo. This is because the diff image is
|
|
|
|
|
fetched by the browser (not by Forgejo's server), and browsers block cross-origin
|
|
|
|
|
image requests to plain `http://localhost` URLs. Most production Forgejo
|
|
|
|
|
deployments already sit behind Nginx for TLS termination; adding two
|
|
|
|
|
`proxy_pass` lines is the only extra step.
|
2026-04-24 07:57:33 +01:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Directory layout
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
forgejo/
|
|
|
|
|
custom/public/assets/
|
|
|
|
|
viewer.html ← browser IFC viewer (no rebuild needed)
|
2026-04-27 20:24:58 +01:00
|
|
|
viewer-url.js ← ifc:// URL parse/build/resolve logic (ES module)
|
|
|
|
|
viewer-util.js ← shared pure utilities: parseCommitHref, isSimpleTypeSelector, etc.
|
|
|
|
|
ifcurl.js ← "View in 3D" + PR diff injection (ES module, no rebuild needed)
|
2026-04-24 07:57:33 +01:00
|
|
|
templates/custom/
|
2026-04-27 07:36:57 +01:00
|
|
|
footer.tmpl ← loads ifcurl.js (no rebuild needed)
|
2026-04-24 09:17:32 +01:00
|
|
|
server-config/
|
2026-04-25 10:00:33 +01:00
|
|
|
ifcurl-api.service ← systemd unit for the API service (git + caching)
|
|
|
|
|
ifcurl-render.service ← systemd unit for the render isolation service
|
2026-04-24 09:27:56 +01:00
|
|
|
gitconfig-ifcmerge ← git merge driver registration for /etc/gitconfig
|
|
|
|
|
gitattributes ← system-wide gitattributes for bare repos
|
2026-04-24 07:57:33 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-27 12:26:58 -05:00
|
|
|
## Local setup (Windows + Docker)
|
|
|
|
|
|
|
|
|
|
For a self-contained local deployment of Forgejo + ifcurl on Windows using Docker, see [SETUP_LOCAL.md](SETUP_LOCAL.md).
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-24 07:57:33 +01:00
|
|
|
## Prerequisites
|
|
|
|
|
|
2026-04-25 10:00:33 +01:00
|
|
|
- ifcurl API service + render service running (see [Running the preview service](#running-the-preview-service))
|
2026-04-25 07:26:00 +01:00
|
|
|
- Nginx (or equivalent) in front of Forgejo if PR diff images are wanted
|
2026-04-24 07:57:33 +01:00
|
|
|
|
2026-05-17 11:28:38 +01:00
|
|
|
No Forgejo source tree or Go toolchain is required — all features work with
|
|
|
|
|
static asset deployment.
|
2026-04-24 07:57:33 +01:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-25 18:24:50 +01:00
|
|
|
## Building the viewer JavaScript bundle
|
|
|
|
|
|
|
|
|
|
The viewer loads Three.js, ThatOpen components, and JSZip from locally-bundled
|
|
|
|
|
files rather than CDNs. The bundle files are committed to the repository, so
|
|
|
|
|
you only need to re-run the build when upgrading a dependency version.
|
|
|
|
|
|
|
|
|
|
### Prerequisites
|
|
|
|
|
|
|
|
|
|
Node.js 18+ and npm (used only at build time; not required on the server).
|
|
|
|
|
|
|
|
|
|
### Run the build
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
cd forgejo/
|
|
|
|
|
npm install # installs pinned versions from package-lock.json
|
|
|
|
|
npm run build # produces the four files below
|
2026-04-27 20:24:58 +01:00
|
|
|
npm test # run JavaScript unit tests (viewer-url.js, viewer-util.js)
|
2026-04-25 18:24:50 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Output files (committed to the repository):
|
|
|
|
|
|
|
|
|
|
| File | Source | Purpose |
|
|
|
|
|
|---|---|---|
|
2026-04-28 00:01:19 +01:00
|
|
|
| `custom/public/assets/viewer-deps.js` | three + @thatopen/components + @thatopen/components-front + jszip | Main viewer dependencies |
|
2026-04-25 18:24:50 +01:00
|
|
|
| `custom/public/assets/fragments-worker.js` | @thatopen/fragments worker | IFC parsing web worker |
|
|
|
|
|
| `custom/public/assets/web-ifc.wasm` | web-ifc | IFC geometry kernel (single-threaded) |
|
|
|
|
|
| `custom/public/assets/web-ifc-mt.wasm` | web-ifc | IFC geometry kernel (multi-threaded) |
|
|
|
|
|
|
|
|
|
|
The `node_modules/` directory is gitignored and is never deployed.
|
|
|
|
|
|
|
|
|
|
### Upgrading a dependency
|
|
|
|
|
|
|
|
|
|
Edit the version number in `package.json`, then:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
cd forgejo/
|
|
|
|
|
npm install # updates package-lock.json
|
|
|
|
|
npm run build # regenerates the bundle from the new version
|
|
|
|
|
git add package.json package-lock.json custom/public/assets/
|
|
|
|
|
git commit -m "viewer: upgrade <package> to vX.Y.Z"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-24 07:57:33 +01:00
|
|
|
## Deploying custom assets (no rebuild required)
|
|
|
|
|
|
|
|
|
|
These files can be updated at any time without recompiling Forgejo.
|
|
|
|
|
|
|
|
|
|
### Viewer and URL logic
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-04-25 23:12:15 +01:00
|
|
|
sudo mkdir -p /var/lib/forgejo/custom/public/assets/
|
|
|
|
|
sudo cp forgejo/custom/public/assets/viewer.html /var/lib/forgejo/custom/public/assets/
|
|
|
|
|
sudo cp forgejo/custom/public/assets/viewer-url.js /var/lib/forgejo/custom/public/assets/
|
2026-04-27 20:24:58 +01:00
|
|
|
sudo cp forgejo/custom/public/assets/viewer-util.js /var/lib/forgejo/custom/public/assets/
|
2026-04-25 23:12:15 +01:00
|
|
|
sudo cp forgejo/custom/public/assets/viewer-deps.js /var/lib/forgejo/custom/public/assets/
|
|
|
|
|
sudo cp forgejo/custom/public/assets/fragments-worker.js /var/lib/forgejo/custom/public/assets/
|
|
|
|
|
sudo cp forgejo/custom/public/assets/web-ifc.wasm /var/lib/forgejo/custom/public/assets/
|
|
|
|
|
sudo cp forgejo/custom/public/assets/web-ifc-mt.wasm /var/lib/forgejo/custom/public/assets/
|
2026-04-27 07:36:57 +01:00
|
|
|
sudo cp forgejo/custom/public/assets/ifcurl.js /var/lib/forgejo/custom/public/assets/
|
2026-04-24 07:57:33 +01:00
|
|
|
```
|
|
|
|
|
|
2026-04-27 20:24:58 +01:00
|
|
|
`ifcurl.js` is an ES module and imports from `viewer-util.js` at the same path, so both files must be deployed together.
|
|
|
|
|
|
2026-04-25 18:24:50 +01:00
|
|
|
Served at `/assets/viewer.html`, `/assets/viewer-deps.js`, etc.
|
2026-04-24 07:57:33 +01:00
|
|
|
|
2026-04-25 23:12:15 +01:00
|
|
|
Note: the correct CustomPath is `/var/lib/forgejo/custom` (Forgejo's default when `FORGEJO_CUSTOM` is
|
|
|
|
|
not set). Do not use `/etc/forgejo/public/assets/` — Forgejo does not serve from there.
|
|
|
|
|
|
2026-04-24 07:57:33 +01:00
|
|
|
### "View in 3D" footer template
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
sudo mkdir -p /var/lib/forgejo/custom/templates/custom/
|
|
|
|
|
sudo cp forgejo/templates/custom/footer.tmpl /var/lib/forgejo/custom/templates/custom/
|
|
|
|
|
sudo systemctl restart forgejo
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-24 09:17:32 +01:00
|
|
|
## Running the preview service
|
2026-04-24 08:26:37 +01:00
|
|
|
|
2026-04-25 10:00:33 +01:00
|
|
|
The service is split into two systemd units for security isolation:
|
2026-04-24 09:17:32 +01:00
|
|
|
|
2026-04-25 10:00:33 +01:00
|
|
|
- **ifcurl-api** — handles HTTP requests, git fetching, and caching. Has network
|
|
|
|
|
access and can call git CLI tools. Holds credentials (`/etc/ifcurl/env`).
|
|
|
|
|
Delegates all IFC rendering to ifcurl-render over a Unix socket.
|
|
|
|
|
|
|
|
|
|
- **ifcurl-render** — handles IFC parsing and rendering via ifcopenshell and pyvista.
|
|
|
|
|
Has no network access, no credentials, and `execve`/`execveat` are blocked by
|
|
|
|
|
systemd. Communicates only over the Unix socket.
|
|
|
|
|
|
|
|
|
|
This split limits the blast radius if a crafted IFC file achieves code execution
|
|
|
|
|
in the render process: it cannot reach git hosts or read credentials.
|
|
|
|
|
|
|
|
|
|
### As systemd services (recommended)
|
2026-04-24 09:17:32 +01:00
|
|
|
|
|
|
|
|
```bash
|
2026-04-25 10:00:33 +01:00
|
|
|
# Create the two service users
|
2026-04-24 09:17:32 +01:00
|
|
|
sudo useradd --system --no-create-home --shell /usr/sbin/nologin ifcurl
|
2026-04-25 10:00:33 +01:00
|
|
|
sudo useradd --system --no-create-home --shell /usr/sbin/nologin ifcurl-render
|
2026-04-24 09:17:32 +01:00
|
|
|
|
2026-04-25 10:00:33 +01:00
|
|
|
# Add ifcurl user to ifcurl-render group so it can read the socket
|
|
|
|
|
sudo usermod -aG ifcurl-render ifcurl
|
|
|
|
|
|
|
|
|
|
# Install the units (edit AllowedHosts and port in ifcurl-api.service first)
|
|
|
|
|
sudo cp forgejo/server-config/ifcurl-api.service /etc/systemd/system/
|
|
|
|
|
sudo cp forgejo/server-config/ifcurl-render.service /etc/systemd/system/
|
2026-04-24 09:17:32 +01:00
|
|
|
sudo systemctl daemon-reload
|
2026-04-25 10:00:33 +01:00
|
|
|
sudo systemctl enable --now ifcurl-render
|
|
|
|
|
sudo systemctl enable --now ifcurl-api
|
2026-04-24 09:17:32 +01:00
|
|
|
```
|
|
|
|
|
|
2026-04-25 10:00:33 +01:00
|
|
|
Edit the `ExecStart` line in `ifcurl-api.service` to set your Forgejo hostname:
|
2026-04-24 09:17:32 +01:00
|
|
|
|
|
|
|
|
```ini
|
|
|
|
|
ExecStart=/usr/local/bin/ifcurl serve \
|
|
|
|
|
--host 127.0.0.1 \
|
|
|
|
|
--port 8000 \
|
|
|
|
|
--allowed-hosts git.example.com
|
|
|
|
|
```
|
|
|
|
|
|
2026-04-25 10:00:33 +01:00
|
|
|
Cache limits and other environment variables for the API service go in
|
2026-04-24 09:17:32 +01:00
|
|
|
`/etc/ifcurl/env` (one `KEY=value` per line):
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
IFCURL_CACHE_MAX_GB=10
|
|
|
|
|
IFCURL_T2_MAX=16
|
|
|
|
|
```
|
|
|
|
|
|
2026-04-25 10:00:33 +01:00
|
|
|
Render-side environment variables (timeouts, memory limits) go in
|
|
|
|
|
`/etc/ifcurl/render-env`:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
IFCURL_SANDBOX_TIMEOUT=180
|
|
|
|
|
IFCURL_SANDBOX_MEMORY_MB=2048
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Single-service mode (testing / simple deployments)
|
|
|
|
|
|
|
|
|
|
Without `IFCURL_RENDER_SOCKET` set, the API service handles rendering directly
|
|
|
|
|
in its own subprocess sandbox. This is simpler to set up but offers less
|
|
|
|
|
isolation.
|
2026-04-24 08:26:37 +01:00
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
ifcurl serve --allowed-hosts git.example.com
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
For a Forgejo instance on a non-standard port (e.g. 3000 for local dev):
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
ifcurl serve --allowed-hosts localhost:3000
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`--allowed-hosts` accepts a comma-separated list. Omitting it allows all
|
|
|
|
|
non-private remote hosts, which is unsafe if the service is reachable from
|
|
|
|
|
untrusted clients.
|
|
|
|
|
|
2026-04-25 07:17:17 +01:00
|
|
|
## Nginx reverse-proxy for PR diff images
|
|
|
|
|
|
|
|
|
|
The PR diff viewer (Case 3 in `footer.tmpl`) injects `<img src="/render_diff?…">`
|
|
|
|
|
tags that the **browser** must fetch. The browser resolves `/render_diff` against
|
|
|
|
|
the Forgejo origin, so the ifcurl service must be reachable at the public URL.
|
|
|
|
|
|
|
|
|
|
Add these proxy locations to the Nginx virtual host that fronts Forgejo:
|
|
|
|
|
|
|
|
|
|
```nginx
|
|
|
|
|
# ifcurl preview service — served under the same origin as Forgejo
|
|
|
|
|
location /preview {
|
|
|
|
|
proxy_pass http://127.0.0.1:8000;
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
proxy_read_timeout 120s;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
location /render_diff {
|
|
|
|
|
proxy_pass http://127.0.0.1:8000;
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
proxy_read_timeout 120s;
|
|
|
|
|
}
|
2026-04-25 12:54:20 +01:00
|
|
|
|
|
|
|
|
location /bcf {
|
|
|
|
|
proxy_pass http://127.0.0.1:8000;
|
|
|
|
|
proxy_set_header Host $host;
|
|
|
|
|
proxy_read_timeout 120s;
|
|
|
|
|
}
|
2026-04-25 07:17:17 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Without this proxy the "View in 3D" button (Case 1/2) still works — it opens
|
|
|
|
|
the viewer HTML which fetches the IFC file directly. The PR diff images
|
|
|
|
|
(Case 3) will silently fail to load until the proxy is in place.
|
2026-04-24 07:57:33 +01:00
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-04-24 09:17:32 +01:00
|
|
|
## IFC merge driver (ifcmerge)
|
|
|
|
|
|
|
|
|
|
Configuring `ifcmerge` as the git merge driver for `.ifc` files lets Forgejo
|
|
|
|
|
automatically merge IFC pull requests instead of marking them as conflicted.
|
|
|
|
|
|
2026-04-24 09:27:56 +01:00
|
|
|
### How Forgejo checks mergeability
|
|
|
|
|
|
2026-05-17 23:37:14 +01:00
|
|
|
Forgejo checks PR mergeability by calling `git merge-file current base other`
|
|
|
|
|
directly for each conflicting file. This command bypasses gitattributes merge
|
|
|
|
|
drivers entirely — `/etc/gitconfig` and `core.attributesFile` have no effect
|
|
|
|
|
on this code path.
|
2026-04-24 09:27:56 +01:00
|
|
|
|
2026-05-17 23:37:14 +01:00
|
|
|
The solution is a **git wrapper** at `/usr/bin/git` (with the original binary
|
|
|
|
|
moved to `/usr/bin/git.real`) that intercepts `merge-file` calls, detects IFC
|
|
|
|
|
files by their ISO-10303 STEP header, and delegates to `ifcmerge` instead.
|
|
|
|
|
|
|
|
|
|
The `/etc/gitconfig` merge driver registration and `/etc/gitattributes` are
|
|
|
|
|
still useful for client-side `git merge` operations on developer machines, but
|
|
|
|
|
they do not affect Forgejo's server-side conflict check.
|
|
|
|
|
|
|
|
|
|
**Important:** the git package in apt will overwrite `/usr/bin/git` on upgrade.
|
|
|
|
|
Reinstall the wrapper (`server-config/git-wrapper`) after any git package upgrade.
|
2026-04-24 09:27:56 +01:00
|
|
|
|
2026-04-24 09:17:32 +01:00
|
|
|
### Prerequisites
|
|
|
|
|
|
2026-05-17 23:37:14 +01:00
|
|
|
`ifcmerge` is a Perl script — install Perl's DateTime module first:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
apt install -y libdatetime-perl
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Then download ifcmerge from
|
|
|
|
|
[github.com/brunopostle/ifcmerge](https://github.com/brunopostle/ifcmerge):
|
2026-04-24 09:17:32 +01:00
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
curl -o /usr/local/bin/ifcmerge \
|
|
|
|
|
https://raw.githubusercontent.com/brunopostle/ifcmerge/main/ifcmerge
|
|
|
|
|
chmod +x /usr/local/bin/ifcmerge
|
|
|
|
|
```
|
|
|
|
|
|
2026-05-17 23:37:14 +01:00
|
|
|
### Install the git wrapper
|
|
|
|
|
|
|
|
|
|
The git wrapper intercepts `git merge-file` for IFC files and routes them to
|
|
|
|
|
ifcmerge. Install it by replacing the git binary:
|
2026-04-24 09:17:32 +01:00
|
|
|
|
|
|
|
|
```bash
|
2026-05-17 23:37:14 +01:00
|
|
|
mv /usr/bin/git /usr/bin/git.real
|
|
|
|
|
cp forgejo/server-config/git-wrapper /usr/bin/git
|
|
|
|
|
chmod +x /usr/bin/git
|
2026-04-24 09:17:32 +01:00
|
|
|
```
|
|
|
|
|
|
2026-05-17 23:37:14 +01:00
|
|
|
### Deploy the config files (for client-side merges)
|
2026-04-24 09:17:32 +01:00
|
|
|
|
|
|
|
|
```bash
|
2026-05-17 23:37:14 +01:00
|
|
|
# System-wide gitattributes
|
2026-04-24 09:27:56 +01:00
|
|
|
sudo cp forgejo/server-config/gitattributes /etc/gitattributes
|
2026-04-24 09:17:32 +01:00
|
|
|
|
2026-05-17 23:37:14 +01:00
|
|
|
# Merge driver registration in /etc/gitconfig
|
2026-04-24 09:27:56 +01:00
|
|
|
sudo git config --system include.path /path/to/ifcurl/forgejo/server-config/gitconfig-ifcmerge
|
2026-04-24 09:17:32 +01:00
|
|
|
```
|
|
|
|
|
|
2026-04-24 09:27:56 +01:00
|
|
|
Or apply the blocks from `server-config/gitconfig-ifcmerge` directly into
|
|
|
|
|
`/etc/gitconfig` by hand.
|
2026-04-24 09:17:32 +01:00
|
|
|
|
|
|
|
|
### Merge direction
|
|
|
|
|
|
2026-04-25 07:41:49 +01:00
|
|
|
The invariant is that step-IDs in `main`/`master` must never be renumbered,
|
|
|
|
|
because existing cross-references depend on them. The correct driver depends
|
|
|
|
|
on which branch is the "local" (`%A`) side:
|
2026-04-24 09:17:32 +01:00
|
|
|
|
2026-04-25 07:41:49 +01:00
|
|
|
| Situation | `%A` (local) | `%B` (remote) | Driver to use |
|
|
|
|
|
|---|---|---|---|
|
|
|
|
|
| Forgejo "Merge commit" button | `main` | PR branch | `ifcmerge_ours` (`--prioritise-local`) |
|
|
|
|
|
| Developer rebasing PR from `main` | PR branch | `main` | `ifcmerge` (default) |
|
2026-04-24 09:17:32 +01:00
|
|
|
|
2026-04-25 07:41:49 +01:00
|
|
|
For Forgejo server-side merges, use the **"Merge commit"** strategy (not
|
|
|
|
|
rebase or squash) and configure `.gitattributes` to use `ifcmerge_ours`:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
*.ifc merge=ifcmerge_ours
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
`ifcmerge` (no flag) is for client-side use by developers updating their
|
|
|
|
|
working branch from `main`, where `main` arrives as the remote (`%B`) side
|
|
|
|
|
and its IDs are preserved by default.
|
2026-04-24 09:17:32 +01:00
|
|
|
|
2026-04-24 09:27:56 +01:00
|
|
|
### Client-side `.gitattributes`
|
|
|
|
|
|
|
|
|
|
For client-side merges (`git merge` on a developer's machine) committed
|
|
|
|
|
`.gitattributes` files in the repository work fine. It is still worth
|
|
|
|
|
adding one:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
*.ifc merge=ifcmerge
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This ensures developers with ifcmerge installed get automatic IFC merges
|
|
|
|
|
locally, and tools that read gitattributes (e.g. diff viewers) can
|
|
|
|
|
identify `.ifc` files correctly.
|
|
|
|
|
|
2026-04-24 09:17:32 +01:00
|
|
|
---
|
|
|
|
|
|
2026-04-24 07:57:33 +01:00
|
|
|
## Upgrading Forgejo
|
|
|
|
|
|
2026-05-17 11:28:38 +01:00
|
|
|
Custom assets (`viewer.html`, `ifcurl.js`, etc.) and `footer.tmpl` are
|
|
|
|
|
unaffected by Forgejo upstream upgrades — redeploy them after each asset
|
|
|
|
|
change and restart Forgejo once after updating `footer.tmpl`.
|