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
|
### How Forgejo checks mergeability
|
||||||
|
|
||||||
Forgejo (with git ≥ 2.38) uses `git merge-tree --write-tree` to perform a
|
Forgejo checks PR mergeability by calling `git merge-file current base other`
|
||||||
trial merge in the bare repository. This command **does** invoke configured
|
directly for each conflicting file. This command bypasses gitattributes merge
|
||||||
merge drivers — confirmed by testing. With ifcmerge set up correctly,
|
drivers entirely — `/etc/gitconfig` and `core.attributesFile` have no effect
|
||||||
the "can be automatically merged" indicator on a PR reflects ifcmerge's
|
on this code path.
|
||||||
actual result, not a naive text-conflict check.
|
|
||||||
|
|
||||||
**Important:** bare repositories do not read committed `.gitattributes` files
|
The solution is a **git wrapper** at `/usr/bin/git` (with the original binary
|
||||||
from the tree. The merge driver must be declared via a system-wide
|
moved to `/usr/bin/git.real`) that intercepts `merge-file` calls, detects IFC
|
||||||
`core.attributesFile` setting in `/etc/gitconfig`.
|
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
|
### Prerequisites
|
||||||
|
|
||||||
`ifcmerge` is a single Perl script from
|
`ifcmerge` is a Perl script — install Perl's DateTime module first:
|
||||||
[github.com/brunopostle/ifcmerge](https://github.com/brunopostle/ifcmerge).
|
|
||||||
Download and install it on the Forgejo server:
|
```bash
|
||||||
|
apt install -y libdatetime-perl
|
||||||
|
```
|
||||||
|
|
||||||
|
Then download ifcmerge from
|
||||||
|
[github.com/brunopostle/ifcmerge](https://github.com/brunopostle/ifcmerge):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -o /usr/local/bin/ifcmerge \
|
curl -o /usr/local/bin/ifcmerge \
|
||||||
|
|
@ -290,19 +301,24 @@ curl -o /usr/local/bin/ifcmerge \
|
||||||
chmod +x /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
|
```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
|
```bash
|
||||||
# System-wide gitattributes (the critical piece for bare repos)
|
# System-wide gitattributes
|
||||||
sudo cp forgejo/server-config/gitattributes /etc/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
|
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