Skip to content

Commit 65cc655

Browse files
committed
Add ADR-003: Document Git commits with historical dates for version history
1 parent d85f5e2 commit 65cc655

1 file changed

Lines changed: 220 additions & 0 deletions

File tree

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# ADR-003: Git-commits med historiska datum för versionshistorik
2+
3+
## Status
4+
5+
Accepterad
6+
7+
## Kontext och problembeskrivning
8+
9+
Lagstiftning har en inneboende temporal dimension - lagar stiftas, ändras och upphävs vid specifika datum. För att göra denna historik tillgänglig och navigerbar behövde vi ett sätt att representera hur en lag såg ut vid olika tidpunkter genom historien.
10+
11+
Utmaningarna var:
12+
13+
1. **Historisk representation**: Hur visar vi hur en lag såg ut 2010 vs 2024?
14+
2. **Navigerbarhet**: Användare ska kunna "scrolla" bakåt i tiden
15+
3. **Versionshantering**: Varje ändring ska vara spårbar med exakt datum
16+
4. **Teknisk enkelhet**: Systemet ska vara lätt att förstå och använda
17+
5. **Standardverktyg**: Helst undvika custom databaser eller proprietära system
18+
19+
Alternativen inkluderade:
20+
21+
- Separata filer per version med datum i filnamn
22+
- Databas med temporal data (PostgreSQL temporal tables)
23+
- Custom versionshanteringssystem
24+
- Git med manipulerade commit-datum
25+
26+
## Beslut
27+
28+
Vi använder **Git med backdated commits** där varje författning och ändring får en commit med det faktiska historiska datumet då den trädde i kraft eller utfärdades.
29+
30+
### Teknisk implementation
31+
32+
**Miljövariabler för datum**:
33+
```python
34+
env = {
35+
'GIT_AUTHOR_DATE': '2010-01-01 12:00:00 +0100',
36+
'GIT_COMMITTER_DATE': '2010-01-01 12:00:00 +0100'
37+
}
38+
subprocess.run(['git', 'commit', '-m', message], env=env)
39+
```
40+
41+
**Commit-strategi**:
42+
43+
1. **Initial commit**: Skapas med `utfardadDateTime` (utfärdandedatum)
44+
- Innehåller ursprungsversionen av författningen
45+
- Temporal filtrering appliceras upp till utfärdandedatumet
46+
47+
2. **Ändrings-commits**: Skapas med respektive `ikraft_datum`
48+
- Varje ändring får en separat commit
49+
- Commiten visar hur lagen ser ut efter ändringen trätt i kraft
50+
51+
3. **Upphävande-commits**: Skapas när en författning upphävs
52+
- Markerar när en lag slutar gälla
53+
54+
**Branch-struktur**:
55+
- Commits skapas på en dedikerad branch (t.ex. `git-export-YYYYMMDD`)
56+
- Branch kan pushas till separat repository (`se-lex/sfs`)
57+
58+
### Exempel på commit-historik
59+
60+
```
61+
2024-07-01 ✏️ Ändra Lag (2010:100) - SFS 2024:500
62+
2023-01-01 ✏️ Ändra Lag (2010:100) - SFS 2023:50
63+
2010-01-15 📜 Lag (2010:100) om exempel
64+
```
65+
66+
När man gör `git checkout <commit>` får man exakt hur lagen såg ut vid det datumet.
67+
68+
## Konsekvenser
69+
70+
### Positiva
71+
72+
- **Git som tidsmaskin**: `git log --since="2015-01-01" --until="2016-01-01"` visar alla ändringar under ett år
73+
- **Diff mellan versioner**: `git diff <commit1> <commit2>` visar exakt vad som ändrats
74+
- **Standardverktyg**: Alla Git-klienter fungerar (GitHub, GitLab, gitk, SourceTree, etc.)
75+
- **Gratis hosting**: GitHub/GitLab tillhandahåller gratis hosting och webb-UI
76+
- **Blame-funktion**: `git blame` visar exakt när varje rad ändrades
77+
- **Decentraliserat**: Varje klon innehåller hela historiken
78+
- **Visuell representation**: GitHub/GitLab visar automatiskt commit-graf och tidslinje
79+
- **API-tillgång**: Git-hostar erbjuder REST API:er för att hämta historiska versioner
80+
81+
### Negativa
82+
83+
- **Okonventionell användning**: Git är inte designat för backdated commits
84+
- Mitigering: Tydlig dokumentation, separata branches för Git-export
85+
86+
- **Commit-ordning**: Git sorterar efter commit-datum, inte när commiten skapades
87+
- Mitigering: Detta är faktiskt önskat beteende - vi vill ha kronologisk ordning
88+
89+
- **Merge-komplexitet**: Svårt att merge:a historiska branches
90+
- Mitigering: Git-export är en one-way operation, inget merging behövs
91+
92+
- **Repository-storlek**: Många commits kan göra repositoryt stort
93+
- Mitigering: SFS har ~50 000 författningar, hanteras fint av Git
94+
95+
- **Author vs Committer**: Båda datum sätts till historiskt datum
96+
- Mitigering: Konsekvent beteende, men metadata om faktiskt skapandedatum går förlorad
97+
98+
- **Duplicate-hantering**: Risk för dubbla commits med samma meddelande
99+
- Mitigering: Implementerad check i `check_duplicate_commit_message()`
100+
101+
### Tekniska konsekvenser
102+
103+
- **Temporal processing**: Varje commit-punkt kräver temporal filtrering upp till det datumet
104+
- **Branch-isolation**: Git-commits måste ske på dedikerad branch
105+
- **Clean state**: Branchen rensas innan ny export (`remove_all_commits_on_branch`)
106+
- **Performance**: Sekventiell processning av alla författningar tar tid
107+
- Optimering: Batch-processing i `temporal_commits_batch_processor.py`
108+
109+
## Alternativ som övervägdes
110+
111+
### 1. Separata filer med datum i namn
112+
113+
```
114+
2010-100/2010-01-15.md
115+
2010-100/2023-01-01.md
116+
2010-100/2024-07-01.md
117+
```
118+
119+
**Varför inte valt**:
120+
121+
- Ingen inbyggd diff-funktionalitet
122+
- Svårt att navigera mellan versioner
123+
- Ingen standardiserad tooling
124+
- Måste bygga custom UI för att visa ändringar
125+
126+
### 2. PostgreSQL temporal tables
127+
128+
```sql
129+
CREATE TABLE laws (
130+
id INT,
131+
content TEXT,
132+
valid_from DATE,
133+
valid_to DATE
134+
);
135+
```
136+
137+
**Varför inte valt**:
138+
139+
- Kräver databas-infrastruktur
140+
- Mindre tillgängligt för användare (kräver SQL-kunskap)
141+
- Ingen visuell representation utan custom UI
142+
- Svårare att hosta och dela publikt
143+
144+
### 3. Custom versionshanteringssystem
145+
146+
**Varför inte valt**:
147+
148+
- Reinventing the wheel
149+
- Måste bygga all tooling från grunden
150+
- Ingen befintlig community eller ekosystem
151+
- Högre underhållskostnad
152+
153+
### 4. Git tags istället för commits
154+
155+
```
156+
git tag "2010-100-v1" <commit>
157+
git tag "2010-100-v2" <commit>
158+
```
159+
160+
**Varför inte valt**:
161+
162+
- Tags visar inte temporal progression lika tydligt
163+
- Inget naturligt sätt att se alla ändringar kronologiskt
164+
- `git log` blir mindre användbart
165+
- Tags är metadata, inte innehåll
166+
167+
### 5. Separata branches per författning
168+
169+
```
170+
branches: 2010-100, 2010-101, 2010-102, ...
171+
```
172+
173+
**Varför inte valt**:
174+
175+
- 50 000+ branches blir ohanterbart
176+
- Svårt att se alla lagändringar kronologiskt
177+
- Branch-explosion överbelastar Git-UI:s
178+
179+
## Relaterade beslut
180+
181+
- [ADR-001](001-semantiska-temporal-taggar.md) - Temporal metadata som driver commit-genereringen
182+
- [ADR-002](002-import-fran-regeringskansliet.md) - Källdata för utfärdande- och ikraftträdandedatum
183+
184+
## Noteringar
185+
186+
- **Implementationer**:
187+
- `exporters/git/generate_commits.py` - Skapar initial och ändrings-commits
188+
- `exporters/git/git_utils.py` - Git-operationer med `GIT_AUTHOR_DATE` och `GIT_COMMITTER_DATE`
189+
- `exporters/git/temporal_commits_batch_processor.py` - Batch-processing för prestanda
190+
191+
- **Användning**:
192+
193+
```bash
194+
# Exportera till Git med historiska commits
195+
python sfs_processor.py --formats git --filter 2024
196+
197+
# Efter export, navigera i historiken
198+
cd <git-repo>
199+
git log --oneline --since="2020-01-01"
200+
git show <commit-hash>
201+
git diff <old-commit> <new-commit>
202+
```
203+
204+
- **Output-repository**: https://github.com/se-lex/sfs
205+
- Innehåller all SFS-lagstiftning med historiska commits
206+
- Publikt tillgänglig för utvecklare och jurister
207+
- API-åtkomst via GitHub REST API
208+
209+
- **Commit-meddelanden**: Använder emojis för att indikera typ av ändring
210+
- 📜 Initial författning
211+
- ✏️ Ändring av författning
212+
- 🗑️ Upphävande
213+
214+
- **Performance**: ~50 000 författningar tar flera timmar att processa
215+
- Optimering: Batch-processing, parallellisering övervägs
216+
217+
- **Framtida förbättringar**:
218+
- Metadata-fil per commit för att bevara faktiskt skapandedatum
219+
- Signerade commits för autenticitet
220+
- Incremental updates istället för full rebuild

0 commit comments

Comments
 (0)