mirror of
https://github.com/brunopostle/ifcurl.git
synced 2026-07-12 02:08:13 +00:00
Document git-wrapper for ifcmerge: Forgejo uses git merge-file not merge-tree
This commit is contained in:
parent
0e855d8413
commit
b23b210f76
2 changed files with 92 additions and 16 deletions
|
|
@ -268,21 +268,32 @@ automatically merge IFC pull requests instead of marking them as conflicted.
|
|||
|
||||
### How Forgejo checks mergeability
|
||||
|
||||
Forgejo (with git ≥ 2.38) uses `git merge-tree --write-tree` to perform a
|
||||
trial merge in the bare repository. This command **does** invoke configured
|
||||
merge drivers — confirmed by testing. With ifcmerge set up correctly,
|
||||
the "can be automatically merged" indicator on a PR reflects ifcmerge's
|
||||
actual result, not a naive text-conflict check.
|
||||
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.
|
||||
|
||||
**Important:** bare repositories do not read committed `.gitattributes` files
|
||||
from the tree. The merge driver must be declared via a system-wide
|
||||
`core.attributesFile` setting in `/etc/gitconfig`.
|
||||
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.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
`ifcmerge` is a single Perl script from
|
||||
[github.com/brunopostle/ifcmerge](https://github.com/brunopostle/ifcmerge).
|
||||
Download and install it on the Forgejo server:
|
||||
`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):
|
||||
|
||||
```bash
|
||||
curl -o /usr/local/bin/ifcmerge \
|
||||
|
|
@ -290,19 +301,24 @@ curl -o /usr/local/bin/ifcmerge \
|
|||
chmod +x /usr/local/bin/ifcmerge
|
||||
```
|
||||
|
||||
Verify it is on `PATH` for the `forgejo` system user:
|
||||
### 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:
|
||||
|
||||
```bash
|
||||
sudo -u forgejo which ifcmerge
|
||||
mv /usr/bin/git /usr/bin/git.real
|
||||
cp forgejo/server-config/git-wrapper /usr/bin/git
|
||||
chmod +x /usr/bin/git
|
||||
```
|
||||
|
||||
### Deploy the config files
|
||||
### Deploy the config files (for client-side merges)
|
||||
|
||||
```bash
|
||||
# System-wide gitattributes (the critical piece for bare repos)
|
||||
# System-wide gitattributes
|
||||
sudo cp forgejo/server-config/gitattributes /etc/gitattributes
|
||||
|
||||
# Append merge driver registration + core.attributesFile to /etc/gitconfig
|
||||
# Merge driver registration in /etc/gitconfig
|
||||
sudo git config --system include.path /path/to/ifcurl/forgejo/server-config/gitconfig-ifcmerge
|
||||
```
|
||||
|
||||
|
|
|
|||
60
forgejo/server-config/git-wrapper
Normal file
60
forgejo/server-config/git-wrapper
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#!/bin/bash
|
||||
# Drop this at /usr/bin/git (move original to /usr/bin/git.real).
|
||||
#
|
||||
# Forgejo checks PR mergeability by calling 'git merge-file current base other'
|
||||
# directly. This bypasses gitattributes merge drivers entirely — there is no
|
||||
# way to configure ifcmerge via /etc/gitconfig for this code path.
|
||||
#
|
||||
# This wrapper intercepts 'git merge-file' calls where the file being merged
|
||||
# is an IFC/STEP file (identified by the ISO-10303 header) and delegates to
|
||||
# ifcmerge instead of git's built-in text merge.
|
||||
#
|
||||
# Installation:
|
||||
# mv /usr/bin/git /usr/bin/git.real
|
||||
# cp git-wrapper /usr/bin/git
|
||||
# chmod +x /usr/bin/git
|
||||
#
|
||||
# The wrapper is transparent for all other git commands.
|
||||
#
|
||||
# NOTE: apt upgrades to the git package will overwrite /usr/bin/git.
|
||||
# After any git package upgrade, reinstall this wrapper.
|
||||
|
||||
is_merge_file=false
|
||||
for arg in "$@"; do
|
||||
[ "$arg" = "merge-file" ] && is_merge_file=true && break
|
||||
done
|
||||
|
||||
if $is_merge_file; then
|
||||
files=()
|
||||
past_subcommand=false
|
||||
skip_next=false
|
||||
for arg in "$@"; do
|
||||
if ! $past_subcommand; then
|
||||
[ "$arg" = "merge-file" ] && past_subcommand=true
|
||||
continue
|
||||
fi
|
||||
if $skip_next; then skip_next=false; continue; fi
|
||||
case "$arg" in
|
||||
-L|--marker-size) skip_next=true ;;
|
||||
-p|-q|--quiet|--ours|--theirs|--union|--diff3|--zdiff3) ;;
|
||||
--) ;;
|
||||
-*) ;;
|
||||
*) files+=("$arg") ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ ${#files[@]} -eq 3 ]; then
|
||||
current="${files[0]}"
|
||||
base="${files[1]}"
|
||||
other="${files[2]}"
|
||||
if [ -f "$current" ] && head -c 20 "$current" 2>/dev/null | grep -q "ISO-10303"; then
|
||||
dir=$(dirname "$current")
|
||||
[[ "$base" != /* ]] && base="$dir/$base"
|
||||
[[ "$other" != /* ]] && other="$dir/$other"
|
||||
ifcmerge --prioritise-local "$base" "$current" "$other" "$current"
|
||||
exit $?
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
exec /usr/bin/git.real "$@"
|
||||
Loading…
Add table
Reference in a new issue