# Git Workflow for Library Versioning

Version control is the cornerstone of reliable library distribution. This document walks through common git patterns used by the Python Library Making skill, particularly when distributing via internal Git dependencies.

---

## 1. Repository Initialization

1. `git init` – start a new repository
2. Write `.gitignore` with appropriate ignores (see [scripts/init_library.py](../scripts/init_library.py))
3. `git add . && git commit -m "feat: initial library setup"`

> Tip: Use conventional commits (feat/fix/chore) to make changelogs easier.


## 2. Branching Strategy

* `main` or `master` – stable branch containing releasable code.
* `dev` – optional working branch for ongoing development.
* Feature branches: `feature/xyz` or `fix/issue-123`.

Keep `main` deployable; merge into it only after review.

---

## 3. Tagging Releases

Tags are how consumer projects lock to a specific version.

```bash
# after bumping version in pyproject.toml and __init__.py
git add pyproject.toml src/{package_folder}/__init__.py
git commit -m "chore: bump version to 0.1.1"

# create annotated tag (preferred)
git tag -a v0.1.1 -m "Release version 0.1.1"

# push tag to remote
git push origin v0.1.1
```

By convention, tags start with `v` (e.g., `v1.0.0`). Consumer projects should reference tags with `@vX.Y.Z` when installing via git url.

---

## 4. Updating Consumer Projects

To pull in updates:

```bash
cd ../consumer-project
uv lock --upgrade-package my-utils
```

The lockfile will record the specific commit or tag. If you wish to remain on older version, omit the `--upgrade-package` flag.

If you need to downgrade:

```bash
uv lock --package my-utils@v0.1.0
```

---

## 5. Handling Hotfixes

If you need to release a patch quickly from `main`:

1. Checkout main: `git checkout main`
2. Make the bug fix, bump patch version (e.g., 0.1.1 → 0.1.2)
3. Commit: `git commit -m "fix: ..."`
4. Tag and push: `git tag v0.1.2 && git push origin main && git push origin v0.1.2`

Consumers will update with `uv lock --upgrade-package my-utils` to get the fix.

---

## 6. Interacting with CI/CD

- Use `.gitlab-ci.yml` or GitHub Actions to run tests, build and publish.
- Example step for Git-based release:
  ```yaml
  stages:
    - test
    - release

  release:
    stage: release
    script:
      - uv lock --upgrade
      - uv run pytest
      - git tag v${CI_COMMIT_TAG}
      - git push origin ${CI_COMMIT_TAG}
    only:
      - tags
  ```

- For PyPI, pipeline can run `uv build` and `uv publish --token $PYPI_TOKEN` when a new tag is pushed.

---

## 7. Dealing with Merge Conflicts

* Always resolve version numbers manually; `pyproject.toml` may conflict when bumps happen concurrently.
* Rebase feature branches frequently against `main` to minimize conflicts.

---

## 8. Legacy Support

If converting an existing repository from flat layout or different package manager:
1. Create a migration branch.
2. Restructure files under `src/package/`.
3. Update imports throughout codebase.
4. Add `validate_structure.py` to catch residual issues.
5. Run `uv build` to ensure packaging still works.

---

**See also:**
* [Troubleshooting Git Issues](troubleshooting.md)
* [`scripts/init_library.py` automation](../scripts/init_library.py)
* [Reference pyproject templates](pyproject_template.md)
