Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/markdownlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Run markdownlint
uses: DavidAnson/markdownlint-cli2-action@v24.1.0
uses: DavidAnson/markdownlint-cli2-action@21c1be1b93ad9ed58fa840aacc3f279cde2a72ff # v24.2.0
with:
globs: '**/*.md'
config: '.markdownlint.json'
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### Added

- Five new practice modules, each with an exercise, extra practice and a self-test: 11 GitLab, 12 signing and security, 13 undoing mistakes, 14 planning with GitHub Projects and 15 newer Git and GitHub CLI commands
- `practice/11-gitlab/11.1-exercise/example-gitlab-ci.yml`, a two-stage pipeline to paste into a GitLab project
- GitLab terms plus the new Git and GitHub terms in the glossary, with matching sections in the command reference
- Rows in `docs/github-ui-vs-terminal.md` for issue branches, sub-issues, reverting and updating pull requests
- `CODEOWNERS`, `CODE_OF_CONDUCT.md`, `SECURITY.md` and `SUPPORT.md`, matching the rest of the fleet
- `.markdownlint.json` and a markdownlint CI workflow, with its own `.github/workflows/README.md`
- YAML issue forms for bug reports and enhancements plus a pull request template
Expand All @@ -24,6 +28,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

### Changed

- `actions/checkout` moved from v4.4.0 to v7.0.1 in the lint workflow and the module 08 example
- `markdownlint-cli2-action` pinned to a commit at v24.2.0
- `CONTRIBUTING.md` uses `git switch` throughout, with a practice-module example in place of the competitive programming one
- Tidied the contributor guide examples.
- The README's Contact section now links out to `SUPPORT.md` and `SECURITY.md` as callouts instead of plain prose
- The Repository Files table wording tidied
Expand All @@ -32,3 +39,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- The README's detailed command tables moved to `docs/`, keeping the root file short
- `cats.txt` moved from the repository root into `practice/00-cats-original`
- `CONTRIBUTING.md`'s example commit messages and project-type sections now name their commit prefix explicitly

### Fixed

- `docs/github-ui-vs-terminal.md` no longer says rulesets can only be created in the browser
62 changes: 32 additions & 30 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ Before coding, create a GitHub issue that describes the work.
Create a branch from `main` for the issue.

```powershell
git checkout main
git pull
git checkout -b feature/description-of-work
git switch main
git pull --ff-only
git switch -c feature/description-of-work
```

Common branch prefixes:
Expand All @@ -34,15 +34,15 @@ Common branch prefixes:
| `fix/` | Bug fixes |
| `docs/` | Documentation updates |
| `refactor/` | Code improvements without feature changes |
| `solve/` | Competitive programming solutions |
| `practice/` | Throwaway branches made while working through a module |

Examples:

```powershell
git checkout -b feature/telemetry-dashboard
git checkout -b fix/auth-validation
git checkout -b docs/readme-update
git checkout -b solve/347-top-k-frequent-elements
git switch -c feature/telemetry-dashboard
git switch -c fix/auth-validation
git switch -c docs/readme-update
git switch -c practice/undo-demo
```

### 3. Do the Work
Expand Down Expand Up @@ -127,8 +127,8 @@ When the PR is ready:
### 8. Clean Up Locally

```powershell
git checkout main
git pull
git switch main
git pull --ff-only
git branch -d feature/your-branch-name
```

Expand All @@ -147,17 +147,17 @@ This makes the project history easier to follow and demonstrates a professional

## Project Examples

### Competitive Programming Repositories
### Practice Modules

Use this for LeetCode, NeetCode, Codeforces and similar repos.
Use this for a new module or a new part of an existing one in this repository.

- Issue title: `Solve [ProblemName] - [Difficulty]`
- Label: `enhancement`
- Branch: `solve/[problem-code-or-name]`
- Example issue: `Solve Contains Duplicate - Easy`
- Example branch: `solve/contains-duplicate`
- Issue title: `Add [module or part]`
- Label: `content`
- Branch: `feature/[module-name]`
- Example issue: `Add a GitLab module`
- Example branch: `feature/gitlab-module`
- Commit prefix: `feat:`
- Example PR description: `closes #7 - Adds Python, C++ and Java solutions with complexity notes.`
- Example PR description: `closes #7 - Adds module 11 with an exercise, extra practice and a self-test.`

### Feature Projects

Expand Down Expand Up @@ -216,41 +216,43 @@ To practise real external review:
Issue already created:

```text
#42 Solve Top K Frequent Elements - Medium
#42 Add a self-test to module 13
```

Terminal:

```powershell
git checkout main
git pull
git checkout -b solve/347-top-k-frequent-elements
git switch main
git pull --ff-only
git switch -c test/13-self-test

# Write the solution files.
# Write the self-test.

git add .
git commit -m "feat: solve LeetCode 347 with hash map approach"
git push origin solve/347-top-k-frequent-elements
git commit -m "test: add a self-test to module 13"
git push origin test/13-self-test
```

GitHub PR:

```text
Title: Solve Top K Frequent Elements - Medium
Title: Add a self-test to module 13

closes #42

Adds Python, C++ and Java solutions with time and space complexity notes.
Adds six questions covering restore, reset, revert and recovering with the reflog.
```

After merge:

```powershell
git checkout main
git pull
git branch -d solve/347-top-k-frequent-elements
git switch main
git pull --ff-only
git branch -D test/13-self-test
```

`-D` rather than `-d` because a squash-merge leaves the branch looking unmerged to Git.

## Rule Going Forward

For meaningful changes, use:
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ I use this repository to practise Git, GitHub and the professional workflow habi

## Practice modules

The real content lives in [practice/](practice), ten modules covering everything from staging a file for the first time through to the real aliases I use daily. Each module is split into an exercise, extra practice and a self-test. See [practice/README.md](practice/README.md) for the full list.
The real content lives in [practice/](practice), fifteen modules covering everything from staging a file for the first time through to the real aliases I use daily, GitLab and the newest Git and GitHub CLI commands. Each module is split into an exercise, extra practice and a self-test. See [practice/README.md](practice/README.md) for the full list.

## Documentation

Expand All @@ -34,6 +34,11 @@ Detailed reference lives in [docs/](docs) rather than cluttering this file:
| Reflog, bisect, worktrees and hooks | Not started |
| Newer GitHub features (rulesets, merge queue, Codespaces) | Not started |
| My real daily aliases end to end | In progress |
| The same workflow on GitLab | Not started |
| Commit signing and keeping secrets out | Not started |
| Undoing mistakes and recovering work | Not started |
| Planning with GitHub Projects | Not started |
| Newer Git and GitHub CLI commands | Not started |

I update this table as I actually work through each module, not in advance.

Expand Down Expand Up @@ -71,7 +76,8 @@ The full step by step process, including opening issues, pushing branches, revie
## What is next for me

- Work through the remaining practice modules, in particular the GitHub Actions and remote collaboration ones.
- Add a module on GitHub Projects once I actually use one for something real.
- Work through [14-github-projects](practice/14-github-projects) on a real project board rather than a practice one.
- Revisit [15-newer-git-and-gh](practice/15-newer-git-and-gh) whenever Git or `gh` ships a new release.
- Keep [09-advanced](practice/09-advanced) updated as GitHub ships new features worth trying.
- Follow up in `dotfiles` on the alias gaps found in [practice/10-daily-workflow-and-aliases](practice/10-daily-workflow-and-aliases).

Expand Down
55 changes: 55 additions & 0 deletions docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,40 @@ Every command that shows up across the practice modules, explained properly. The
| `git fetch --prune` | Fetches and also removes local references to branches deleted on the remote |
| `git push origin --delete <branch>` | Deletes a branch on the remote, not just locally |

## Undoing more safely

| Command | What it actually does |
| --- | --- |
| `git reset --soft HEAD~1` | Moves the branch back one commit, keeping the changes staged |
| `git revert -m 1 <merge hash>` | Undoes a merge commit, keeping the first parent's side |
| `git restore --source=<commit> <file>` | Puts one file back to how it was in an earlier commit without moving the branch |
| `git switch --detach <commit>` | Checks out a commit without a branch, for looking around |
| `git push --force-with-lease` | Force-pushes only if the remote branch is still where I last saw it |
| `git fsck --lost-found` | Finds commits no branch or reflog entry points at any more |

## Signing

| Command | What it actually does |
| --- | --- |
| `git config --global gpg.format ssh` | Tells Git to sign with an SSH key instead of GPG |
| `git config --global commit.gpgsign true` | Signs every commit without needing `-S` each time |
| `git log --show-signature` | Shows each commit with the result of checking its signature |
| `git verify-commit HEAD` | Checks one commit's signature |
| `git tag -s <name> -m "message"` | Creates a signed annotated tag |

## Newer Git commands

| Command | What it actually does |
| --- | --- |
| `git config get <key>` | Reads a setting, the newer form of `git config --get` |
| `git config list --show-origin` | Lists every setting with the file it came from |
| `git repo info --all` | Reports facts about the repository, such as its object and reference formats |
| `git last-modified` | Shows the commit that last changed each path |
| `git range-diff <old>...<new>` | Compares two versions of the same series of commits, such as before and after a rebase |
| `git maintenance start` | Schedules background tasks that keep a repository fast |
| `git backfill` | Fetches the file contents a partial clone skipped, in batches |
| `git sparse-checkout set <folder>` | Keeps only the named folders on disk |

## Diagnosing history

| Command | What it actually does |
Expand All @@ -97,5 +131,26 @@ Every command that shows up across the practice modules, explained properly. The
| `gh issue close` | Closes an issue directly, without needing a linked pull request |
| `gh label list` | Lists every label that actually exists on the current repository |
| `gh run watch` | Streams a running workflow's logs live in the terminal |
| `gh run rerun <id> --failed` | Reruns only the jobs that failed in a workflow run |
| `gh issue develop <number> --checkout` | Creates a branch linked to an issue and switches to it |
| `gh issue create --parent <number>` | Opens a new issue as a sub-issue of another |
| `gh pr checks --watch` | Waits for a pull request's checks, reporting when they finish |
| `gh pr update-branch` | Brings a pull request branch up to date with its base |
| `gh pr revert <number>` | Opens a pull request that reverts a merged one |
| `gh ruleset check <branch>` | Lists every rule that would apply to a branch name |
| `gh project item-add <number> --owner "@me" --url <issue url>` | Adds an issue or pull request to a project |
| `gh release verify` | Checks a release's attestation |

## GitLab CLI (`glab`)

| Command | What it actually does |
| --- | --- |
| `glab auth login` | Signs in to GitLab.com or a self-managed instance |
| `glab repo create <name>` | Creates a new project |
| `glab mr create --fill` | Opens a merge request from the current branch, filled in from its commits |
| `glab ci status` | Shows the pipeline for the current branch |
| `glab ci view` | Opens an interactive view of the pipeline's jobs and logs |
| `glab ci lint` | Checks `.gitlab-ci.yml` for mistakes before pushing |
| `glab mr merge --squash --remove-source-branch` | Squash-merges the merge request and deletes its branch |

See [practice/10-daily-workflow-and-aliases](../practice/10-daily-workflow-and-aliases) for the shorter alias I actually type for most of the commands above.
6 changes: 5 additions & 1 deletion docs/github-ui-vs-terminal.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ The same task, done through the GitHub web interface and through the terminal, s
| Delete a merged branch | Delete branch button that appears after merge | `git branch -d name` locally then `git push origin --delete name` on GitHub, `gdone` does both plus pruning in one step |
| Add a label | Labels menu in the issue or pull request sidebar | `gh issue edit N --add-label x` / `gh pr edit N --add-label x`, `ghaddlabel N x` tries both automatically |
| Create a release | Releases -> Draft a new release, pick or create a tag | `git tag -a vX.Y.Z -m "message" && git push origin vX.Y.Z`, then `gh release create` |
| Enable a branch ruleset | Settings -> Rules -> Rulesets -> New ruleset | `gh api repos/{owner}/{repo}/rulesets` for read-only inspection, rulesets themselves are UI-only to create as of writing |
| Enable a branch ruleset | Settings -> Rules -> Rulesets -> New ruleset | `gh ruleset list` and `gh ruleset check <branch>` to inspect them, `gh api -X POST repos/{owner}/{repo}/rulesets --input ruleset.json` to create one from a JSON file |
| Add an image to an issue or comment | Drag and drop directly into the text box | Not possible from the terminal, `gh` has no equivalent, this is a genuinely UI-only action |
| Start a branch for an issue | Development section in the issue sidebar -> Create a branch | `gh issue develop N --checkout` |
| Add a sub-issue | Create sub-issue button under the issue body | `gh issue create --parent N` |
| Revert a merged pull request | Revert button at the bottom of the merged pull request | `gh pr revert N` |
| Update a pull request branch from its base | Update branch button in the merge box | `gh pr update-branch` |
| Check a workflow run's logs | Actions tab -> the run -> the job -> the step | `gh run list` then `gh run view <id> --log` for one run, `gh run watch` for a live stream |
| Fork a repository | Fork button, top right of the repository page | `gh repo fork` or `ghfork` |
| Sync a fork with upstream | Sync fork button on the fork's own page | `git fetch upstream && git merge upstream/main` or the shorter `gh repo sync` |
Expand Down
64 changes: 63 additions & 1 deletion docs/glossary.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Glossary

Plain definitions for every term used across the practice modules, Git and GitHub side by side. My [git-unlocked](https://github.com/zaccesss/git-unlocked) repository has a much larger [full glossary](https://github.com/zaccesss/git-unlocked/blob/main/09-reference/glossary.md) covering GitLab and other platforms too, this one stays scoped to what actually appears in this repository.
Plain definitions for every term used across the practice modules, Git and GitHub side by side. My [git-unlocked](https://github.com/zaccesss/git-unlocked) repository has a much larger [full glossary](https://github.com/zaccesss/git-unlocked/blob/main/09-reference/glossary.md) covering other platforms too, this one stays scoped to what actually appears in this repository.

## Git terms

Expand Down Expand Up @@ -43,6 +43,24 @@ A binary search through commit history to find the exact commit that introduced
**Worktree**
A second working directory checked out from the same repository, letting me have two branches open side by side without cloning twice.

**Restore**
Putting a file back to how it was in the staging area or a commit, without moving any branch. `git restore` replaced the file-level uses of `git checkout`.

**Reset**
Moving the current branch to another commit. `--soft` keeps the changes staged, `--mixed` (the default) keeps them unstaged and `--hard` throws them away.

**Revert**
A new commit that undoes an earlier one, the safe undo for anything already pushed because no existing history is rewritten.

**Detached HEAD**
Checking out a commit directly rather than a branch. New commits made there belong to no branch until one is created for them.

**Signed commit**
A commit carrying a cryptographic signature from a GPG or SSH key, which GitHub and GitLab show as Verified when the key is on the author's account.

**Partial clone**
A clone that skips some objects, such as file contents with `--filter=blob:none`. It fetches them later when needed or with `git backfill`.

**Remote**
A named reference to another copy of the repository, usually on GitHub. `origin` and `upstream` are conventional names, not special keywords.

Expand Down Expand Up @@ -105,6 +123,50 @@ A full cloud development environment tied to a repository, configurable so it op
**Private vulnerability reporting**
GitHub's built-in flow letting someone report a security issue privately through the Security tab, without needing a separate email address.

**Sub-issue**
An issue attached to a parent issue, so the parent shows progress as its children close.

**GitHub Project**
A planning board or table that lives on an account or organisation and pulls in issues and pull requests from any of its repositories.

**Push protection**
Secret scanning that blocks a push containing a recognised token before it reaches GitHub.

**Vigilant mode**
An account setting that marks every unsigned commit of mine as Unverified, so a commit made in my name without my key stands out.

**Release attestation**
A signed statement from GitHub about a release and its assets, checked with `gh release verify`.

## GitLab terms

**Project**
GitLab's name for a repository plus everything around it: issues, merge requests, pipelines and settings.

**Group**
GitLab's equivalent of an organisation, holding projects and subgroups with shared members and permissions.

**Merge request (MR)**
GitLab's name for a pull request.

**Pipeline**
A run of the jobs defined in `.gitlab-ci.yml`, grouped into stages that run in order.

**Job**
One task in a pipeline, run by a runner, usually in a fresh container.

**Runner**
The machine or container that picks up pipeline jobs and runs them.

**Artifact**
Files a job saves so a later stage or a person can use them.

**Protected branch**
A branch only chosen roles can push or merge to, GitLab's equivalent of branch protection.

**glab**
The official GitLab CLI, GitLab's equivalent of `gh`.

## See also

- [docs/command-reference.md](command-reference.md) - every command in this repository, explained in full
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Print a message
run: echo "This workflow ran on ${{ github.ref_name }}"
Expand All @@ -31,7 +31,7 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Count files in the practice folder
run: find practice -type f | wc -l
Loading
Loading