# Git Workflow

- [[#Core Principles|Core Principles]]
- [[#Branch Strategy & Environments|Branch Strategy & Environments]]
- [[#Code Review & Approval|Code Review & Approval]]
- [[#Commit Hygiene|Commit Hygiene]]
- [[#Submodules|Submodules]]
- [[#Upstream|Upstream]]
- [[#Tooling Tips & References|Tooling Tips & References]]

## Core Principles
We use Git to synchronize our development efforts. There are many benefits here:

1. `git log`: history of all changes made by everybody, with date, name, and reason (title/description), per repo, per file, per whatever (you go learn the man page to check all possible arguments if you need more or nobody tells you any cool magic tricks in person: type `man git-log`).
2. `git blame`: another view of the history, where you can check per-line who is responsible, who touched something last. This is very important because you can use this to avoid stepping on each other's toes.
3. `git merge`: multiple commits can be collected in branches and worked on in peace by groups of people, without disturbing others, until it's merged to master. This has to happen often to force us to stay in sync. Getting out of sync too much is VERY undesirable (it creates huge complications and generally it makes merging very difficult). Please note, we do not always merge—see [Upstream](#upstream) below.
4. Communication: working together is complicated. Git allows for many opportunities to attach meaningful messages to objects like commits, both in the title and in the longer-form description.

- Placeholder: Add decision record on default branch naming (`main` vs `master`) and repository initialization conventions.
- Placeholder: Document expectations for commit frequency, size, and linkage to GitLab issues.

With GitLab + merge requests there are even more opportunities for extra descriptions, abstractions, coalescing of commits (into branch + MR instead of squashing), etc.

## Branch Strategy & Environments
- Placeholder: Define branch types (feature, release, hotfix) and required protections.
- Placeholder: Describe how environment deployments map to branches (e.g., staging from `develop`).
- Placeholder: Capture automation expectations (CI pipelines, required checks) before merges.

## Code Review & Approval
We always want everybody to have a high level understanding about what's happening in the repos and branches, and what other team members are doing (struggling with, succeeded in, wisdom achieved,...).

We can use processes like merge requests and code review to increase opportunities for such kind of knowledge transfer. We often want to share also more detailed understandings, hopefully not always escalating into nitpicking: relevant outcome/conclusions/synthesis could be shared back to the team, maybe even to the bigger company. The end goal is always to efficiently communicate the relevant and valuable information.

- Placeholder: Capture review SLA, required approvers per repo, and when self-merges are allowed.
- Placeholder: Document checklist items reviewers must validate (tests, docs, security implications).

## Commit Hygiene
- Placeholder: Provide guidance on commit message format, referencing ticket IDs, and separating mechanical changes.
- Placeholder: Recommend tooling (`pre-commit`, lint hooks) and how to install/override them.
- Placeholder: Add process for rewriting history safely (interactive rebase rules, shared branch etiquette).

## Submodules
The reason is because we reference also external repos, or forks of other projects that have an upstream repo that we want to regularly fetch and then reintegrate back into our repo, where our commits are the minority. To handle such repos we use submodules, which are just references to a commit in another repo.

The biggest cost of submodules now is how to keep our own changes cleanly separated from upstream, to track changes that aren't upstreamed, help communicate with upstream, resolve conflicts when we merge upstream in, and end-to-end test our system in case the many upstream changes broke anything.

The easiest way to get going with all submodules is to git clone recursively:

```sh
git clone --recurse-submodules git@git.uniberg.com:ub-edge/uconfig/uconfigd.git
```

To get submodules after `git clone`:

```sh
git submodule update --init
```

Afterwards, `git pull` will not update the submodules automatically unless you use the correct arguments. If you don't want to type them every time use the following global Git settings instead:

```sh
git config --global submodule.recurse true
```

Beware, recursive submodule updates don't care what branch you had checked out in a given submodule, so you might easily oversee an unpushed change.

- Placeholder: Document policy for committing submodule pointers (fast-forward only? tag references?).
- Placeholder: Explain CI impact when submodule references lag behind and how to detect drift.

## Upstream
I have not seen good evidence what is the most feasible way to manage our patches to upstream: right now it's a giant multi-repo spaghetti mess where we sometimes commit and rebase or merge, or use patch files instead which might in turn get committed and rebased/merged again. Open to suggestions.

Some repos have upstream not controlled by us, thus branch names might not follow our usual pattern.

One thing that might be unusual to you in the OpenWrt package repo is their system where patches (as generated by `git format-patch`) will be picked up automatically in the build process if they are placed in certain subdirectories (grep for file ending `.patch`). When our patches are eventually included in upstream we have to remove the patch files in the repo so they don't get applied twice any more. On the plus side: this also relieves us from the responsibility over the patch.

Many packages are actually a reference to yet another git repo (which we might not mirror).

- Placeholder: Add mapping of critical upstreams with maintainers and sync cadence.
- Placeholder: Document workflow for contributing back (branch naming, PR template, communication channel).

## Tooling Tips & References
- Placeholder: List recommended Git aliases, GUI tools, and scripts maintained by the team.
- Placeholder: Provide troubleshooting guide for common pitfalls (detached HEAD in submodules, rebase conflicts).
