Version Control II

Collaboration Workflows with GitHub and gitlab.nrw

20 May 2026

Overview

  • Why branches, pull requests, and merge requests matter
  • Forks vs branches — when to use which
  • Collaboration workflows — from solo to team to open-source
  • Good commit and branch practices
  • How to review and discuss changes before merging
  • What good project structure looks like for shared research repos
  • Hands-on: opening a pull request / merge request together

Tip

Prerequisite: Basic Git workflow — clone, commit, push (Session 21)

Recap: Where We Left Off

Session 21 covered

  • What version control is and why it matters
  • Repositories, commits, remotes
  • GitHub vs GitLab vs gitlab.nrw
  • Clone → edit → commit → push

Today adds

  • Working in parallel without conflicts
  • Forks and branches as collaboration tools
  • Proposing and reviewing changes
  • Organizing shared projects
  • Communicating through the platform

Before We Start: Check Your Git Identity

Git embeds your name and email in every commit. Check they’re configured in your tool:

VS Code: Open the terminal panel (Ctrl+`) and run git config user.name to check. To set: open Settings → search git user → fill in Git: User Name and Git: User Email.

GitHub Desktop: Preferences (Ctrl+,) → Git tab → Name and Email fields.

RStudio: Tools → Terminal → type git config user.name to check. Set via Tools → Global Options → Git/SVN or in the terminal.

Note

Your identity only needs to be set once per machine. GitHub Desktop usually pre-fills it from your GitHub account.

CLI: git config --global user.name "Your Name" and git config --global user.email "you@uni-koeln.de"

The Problem with Working on main

Two collaborators, one branch — things go wrong fast:

Person A: edit → commit → push ✓  (accepted)
Person B: edit → commit → push ✗  (rejected: not up to date)
                    ↓
               git pull → CONFLICT in analysis.R
                    ↓
          must resolve manually before pushing
  • Mistakes land directly in the shared version with no review
  • Hard to separate “finished work” from “work in progress”

Branches and forks isolate work until it’s ready to be shared.

What Is a Branch?

A branch is a parallel line of work inside the same repository.

Tool How to create a branch
GitHub Desktop Branch menu → New Branch → type a name → Create Branch
VS Code Click the branch name in the status bar → Create new branch
RStudio Git pane → branch dropdown → New Branch
github.com Repository → branch dropdown → type a new name → Create branch
  • main stays stable while you work
  • Your work is isolated until you’re ready
  • Others can review before anything is merged
  • Easy to delete after merging — no trace left in main

What Is a Fork?

A fork is a copy of an entire repository under your own account.

  • Created on the platform (GitHub / gitlab.nrw) with one click
  • You have full write access to your fork
  • The original repository is unaffected
  • You can propose changes back via a pull request / merge request
original:   jobschepens/newproject     (you have read access)
your fork:  your-username/newproject  (you have full access)

Forks vs Branches: Key Differences

Branch Fork
Lives in Same repository Separate copy of the repository
Who uses it Someone with write access Anyone, including outside contributors
Visibility Visible to all repo members Lives on your own account
Use case Internal team collaboration Contributing to repos you don’t own
Sync with original No extra setup — pull from the same remote Manual (git fetch upstream)
Typical in Research group repos Open-source, cross-institute work

Tip

Rule of thumb: If you have write access → use a branch. If you don’t → fork.

Four Common Collaboration Workflows

Workflow Who it’s for Core pattern
Centralized Small team, everyone trusted Commit directly to main
Feature branch Team with code review Branch → PR → merge
Fork & PR Open or cross-institute Fork → branch → PR → merge
Gitflow Software with releases main + develop + feature/release branches

For most research group projects: Feature branch workflow is the right balance.
For contributing to someone else’s repo: Fork & PR workflow.

See Advanced Topics for Gitflow details.

Workflow 1: Centralized

Everyone commits directly to main. Simple, but fragile.

Person A:  edit → commit → push → main ✓
Person B:  edit → commit → push → main ✗ (conflict!)

When it works:

  • Solo researcher
  • Very small team with near-zero overlap
  • Quick one-off fixes

When it breaks:

  • Two people edit the same file at the same time
  • A mistake goes straight to the shared version
  • No review step before changes take effect

Workflow 2: Feature Branch

The standard for team research projects.

main ──────────────────────────────────► stable
        │                       ▲
        └── feature-branch ────►│ (PR → review → merge)

Full cycle in your tool:

  1. Create branch — Branch menu / status bar / Git pane → New Branch
  2. Edit files — work as normal in your editor
  3. Stage & commit — tick changed files, write a message, click Commit
    • GitHub Desktop: left panel → check files → write summary → Commit to branch
    • VS Code: Source Control panel (Ctrl+Shift+G) → stage (+) → message → ✓
    • RStudio: Git pane → check boxes → Commit → write message → Commit
  4. Push — click Push origin / Sync / Push
  5. Open PR / MR — platform will show a banner → Compare & pull request
  6. After merge — switch back to main and pull to get the latest

Note

CLI equivalent: git switch -c branch-name → edit → git add . && git commit -m "msg"git push origin branch-name

Workflow 3: Fork & Pull Request

For contributing to a repository you do not own.

jobschepens/newproject  (original)
        │
        └── fork ──► your-username/newproject  (your copy)
                          │
                          └── branch ──► PR ──► original main

Full cycle:

  1. Fork — on github.com / gitlab.nrw: click Fork (top right of the repo page)
  2. Clone your fork — GitHub Desktop: File → Clone Repository → choose your fork
  3. Create a branch — Branch menu → New Branch
  4. Edit, stage, and commit — same as the feature branch workflow
  5. PushPush origin
  6. Open PR — github.com shows a banner on your fork → Compare & pull request → target: the original repo
  7. Sync your fork later — github.com: your fork page → Sync fork button; GitHub Desktop: Branch → Merge into current branch → choose upstream/main

Note

CLI equivalent: git remote add upstream <original-url>git fetch upstreamgit merge upstream/main

Good Practices: When and How to Commit

Commit one logical change at a time

  • Each commit should do one thing and be describable in a single sentence
  • Don’t bundle unrelated edits (e.g., fixing a typo + restructuring a script)

Commit when the work is in a coherent state

  • After completing a self-contained step: added a function, wrote a section, fixed a specific bug
  • Not mid-sentence, not with broken code that won’t run
  • Think: “If I had to revert to this commit, would it make sense?”

How often?

  • More often is better than less — small commits are easier to review and revert
  • A few commits per work session is normal; dozens is fine too
  • Avoid “one giant commit at the end of the day”

Writing Good Commit Messages

Bad:   "fixed stuff"
Bad:   "update"
Good:  "Fix participant exclusion logic for Study 1"
Good:  "Add descriptive stats table for German adult data"

Format that works:

Short summary (50 chars or less)

Optional longer explanation after a blank line.
What changed, why, and any relevant context.

Good Practices: Branches and Reviews

Branch naming

feature/add-exclusion-criteria
fix/typo-in-consent-form
docs/update-readme-methods

Use a prefix (feature/, fix/, docs/) so the purpose is clear at a glance.

Keep branches short-lived

  • Merge or rebase against main frequently to avoid drift
  • Delete branches after merging — they clutter the repo and create confusion

Review culture

  • A review comment is not a criticism — it is a question or a suggestion
  • Respond to every comment, even if just “Done” or “Disagree, here’s why”
  • Approve when you are satisfied, not just when you are tired of reviewing

Note

Even in a team of two, the habit of reviewing each other’s PRs pays off quickly — errors get caught, decisions get documented.

Good Practices: PR / MR Frequency

Not per commit, not per day — per logical unit of work

  • Open a PR / MR when a self-contained piece of work is ready for review
  • This might be a few commits or a few dozen — size matters more than time

Signs it’s time to open a PR / MR

  • A feature, fix, or section is complete and coherent on its own
  • You want feedback before going further
  • The branch has diverged enough that merging later would be painful

Keep PRs / MRs small and focused

  • One PR per feature / fix / task — not one PR for everything done this week
  • Smaller PRs are reviewed faster and more carefully
  • Large PRs (“mega-PR”) tend to get rubber-stamped

Rules of thumb

Situation Recommended cadence
Active collaboration Open a PR after each task (hours to 1–2 days of work)
Solo research project Open a PR at each meaningful milestone
Shared writing (docs/papers) One PR per section or revision round

Tip

If in doubt: open early and mark it Draft — you get feedback sooner and the review stays manageable.

Pull Requests and Merge Requests

GitHub calls them Pull Requests (PRs)
GitLab / gitlab.nrw calls them Merge Requests (MRs)
→ Same idea, different name.

A PR / MR is a formal proposal to merge one branch into another:

  1. You push your branch (or fork)
  2. You open a PR / MR with a description
  3. A collaborator reviews and comments
  4. Changes are discussed and revised
  5. The branch is merged (or closed)

How to Open a PR on GitHub

Via github.com (any tool):

  1. Push your branch to GitHub
  2. Go to the repository on github.com — a yellow banner appears: “branch-name had recent pushes”
  3. Click Compare & pull request
  4. Fill in the title and description; set base = main, compare = your branch
  5. Assign a reviewer in the right sidebar → Create pull request

Via GitHub Desktop:

  1. After pushing, GitHub Desktop shows a Create Pull Request button — click it
  2. Your browser opens the PR form on github.com — fill in and submit

Tip

If the banner doesn’t appear: Pull requests tab → New pull request → select your branch.

How to Open an MR on gitlab.nrw

Via gitlab.nrw (any tool):

  1. Push your branch to gitlab.nrw
  2. Go to the repository — a blue banner appears: “You pushed to branch-name”
  3. Click Create merge request
  4. Fill in the title and description; set Source branch = your branch, Target branch = main
  5. Assign a reviewer under ReviewersCreate merge request

Via VS Code with GitLab extension:

  1. Push your branch
  2. Open the Command Palette (Ctrl+Shift+P) → GitLab: Create Merge Request
  3. Fill in the form that opens in the browser

Tip

Alternatively: left sidebar → Merge requestsNew merge request → pick your branch.

Anatomy of a Good PR / MR

Title
Short, specific, action-oriented
“Add regression table for English data”

Description
- What changed and why - Any decisions or trade-offs made - Reviewer instructions if needed - Links to related issues: Closes #12

Review checklist
- Does the code/text do what it claims? - Are there errors or unclear sections? - Are commit messages informative? - Is anything missing?

Note

Even solo researchers benefit: a PR forces you to write down what you did and why.

Reviewing Changes

On GitHub / gitlab.nrw you can:

  • Browse the diff — exactly what changed line by line
  • Leave inline comments on specific lines
  • Use suggestions to propose exact text changes
  • Approve or request changes before merging
- participants were recruited via email
+ Participants were recruited via email (N = 48; see consent form).

Merge Strategies

Strategy What it does When to use
Merge commit Keeps all commits, adds a merge commit Default; preserves full history
Squash and merge Combines all commits into one Messy branch history
Rebase and merge Replays commits linearly on top of main Clean linear history

For research work: merge commit is usually fine and most transparent.

Warning

Rebase rewrites commit hashes. Never rebase a branch that others are also working on — it rewrites history and will conflict with anyone who pulled the old version.

Merge Conflicts: What They Are and How to Resolve Them

A conflict occurs when two branches changed the same lines of the same file differently.

VS Code — opens a visual editor automatically:

  • Click Resolve in Merge Editor on the conflicted file
  • Choose Accept Current, Accept Incoming, or Accept Both
  • Save → click Complete Merge in the editor toolbar

GitHub Desktop — highlights conflicted files in red:

  • Click Open in editor next to the conflicted file
  • VS Code opens with the merge editor (same as above)
  • After saving, return to GitHub Desktop → the file is now staged → Commit merge

RStudio — Git pane shows conflicted files with an orange U marker:

  • Open the file — conflict markers (<<<<<<<, =======, >>>>>>>) are visible
  • Edit manually to keep the correct version, delete the markers
  • Stage the file in the Git pane → Commit

Note

Conflicts look scarier than they are — you just choose which version to keep.

Issues: Tracking Work and Discussions

Issues are not just for bugs — use them for:

  • Tasks: “Write methods section for Study 2”
  • Questions: “Should we exclude participants below 18?”
  • Decisions: “Agreed: use APA 7th edition throughout”

Link issues to PRs/MRs with keywords:
Closes #12 in a PR description will auto-close issue #12 on merge.

Project Structure for Shared Repositories

A clear structure reduces confusion for everyone:

my-project/
├── README.md          ← what is this, how to use it
├── data/
│   ├── raw/           ← never modified, version controlled
│   └── processed/
├── scripts/           ← analysis code
├── docs/              ← notes, pre-registrations, papers
├── results/           ← outputs (often in .gitignore)
└── CONTRIBUTING.md    ← how to contribute (for shared repos)

Tip

A good README is often more valuable than comments in code.

GitHub vs gitlab.nrw: Key Differences

Feature GitHub gitlab.nrw
Hosting Public cloud (Microsoft) NRW university infrastructure
Data residency US servers Germany / NRW
Suitable for Public/open-source projects Sensitive or unpublished research
CI/CD GitHub Actions GitLab CI/CD
Account Personal GitHub account University login (Shibboleth)

Recommendation for CRC 1252:
Use gitlab.nrw for unpublished data and analysis; GitHub for public dissemination.

Hands-On Exercise

Work in pairs — choose your workflow and tool (GitHub Desktop, VS Code, or RStudio):

Option A — Feature branch (you have write access):

  1. Clone https://github.com/jobschepens/newproject via your tool’s Clone dialog
  2. Create a new branch (Branch menu / status bar / Git pane)
  3. Add your name to contributors.md, stage and commit
  4. Push → open a PR on github.com → have your partner review and merge

Option B — Fork & PR (external contributor):

  1. Click Fork on https://github.com/jobschepens/newproject
  2. Clone your fork via GitHub Desktop: File → Clone Repository
  3. Create a branch, make a change, commit, push
  4. Open a PR from your fork → original repo on github.com

Tip

Not sure which option? Start with Option A — it’s the most common workflow.

Common Pitfalls and How to Avoid Them

Pitfall What goes wrong Fix
Long-lived branches Diverges from main, painful to merge Merge or rebase often
Giant commits Hard to review, hard to revert Commit small, logical units
Force-pushing shared branches Rewrites history others have built on Only force-push your own private branches
Stale fork Your fork falls behind the original Use Sync fork on github.com or Branch → Merge into current branch → upstream/main in GitHub Desktop
No description in PR Reviewer has no context Always write at least two sentences
Merging without review Defeats the purpose Require review before merge (see Advanced: Branch Protection)

Summary

Concepts

  • Branch = parallel work within a repo
  • Fork = your own copy of a repo
  • PRs / MRs formalize the review process
  • Issues track tasks and decisions
  • Choose workflow by access level and team size

The GUI cycle (any tool)

  1. Clone the repo
  2. Create a branch
  3. Edit → stage → commit
  4. Push
  5. Open PR / MR on the platform
  6. Review → merge
  7. Switch back to main → pull

Note

CLI reference: git switch -c branchgit add . && git commit -m "msg"git push origin branchgit switch main && git pull

Resources

Further Reading

Beginner-friendly

Going deeper

For research specifically

Advanced Topics

Advanced: Gitflow

Used in software development with versioned releases. Rarely needed for research, but good to know.

main      ──────────────────────────── v1.0 ──── v2.0
develop   ──────────────────────────────────────────►
               │              ▲
               └── feature ──►│
  • main only ever contains released, stable versions
  • develop is the integration branch
  • Feature branches merge into develop
  • Release branches cut from developmain

Note

For a research analysis pipeline with versioned outputs, a simplified Gitflow (just main + develop) can help.

Advanced: Staging Part of a File (git add -p)

If one file has multiple unrelated changes, you can stage them separately:

git add -p analysis.R

Git shows each change (“hunk”) one at a time and asks what to do:

Key Action
y Stage this hunk
n Skip this hunk
s Split into smaller hunks
q Quit

This lets a single file produce multiple focused commits — useful when you fixed a bug and refactored code in the same session.

Advanced: Branch Protection Rules

Branch protection rules prevent direct pushes to important branches and enforce review workflows.

On GitHub: Settings → Branches → Add branch protection rule
On gitlab.nrw: Settings → Repository → Protected branches

Common settings for a research repo:

  • Require a pull request before merging — no direct push to main
  • Require approvals — at least 1 reviewer must approve
  • Require status checks — CI must pass before merge
  • Restrict who can push — limit to maintainers

Tip

Even a two-person project benefits: it makes the PR workflow mandatory and prevents accidental direct pushes to main.

CLI Reference: Feature Branch Workflow

For reference — all steps of the feature branch workflow on the command line:

# 1. Create and switch to a new branch
git switch -c feature/add-exclusion-criteria

# 2. Stage and commit changes
git add .                    # stage all changes (or: git add filename)
git commit -m "Add participant exclusion criteria"

# 3. Push branch to remote
git push origin feature/add-exclusion-criteria

# → open PR on github.com / MR on gitlab.nrw (web UI)

# 4. After merge: update local main
git switch main
git pull

# 5. Clean up (optional)
git branch -d feature/add-exclusion-criteria

CLI Reference: Fork & PR Workflow

For reference — full fork workflow on the command line:

# After forking on the platform (web UI):

# 1. Clone your fork
git clone https://github.com/your-username/newproject
cd newproject

# 2. Link the original repo as 'upstream'
git remote add upstream https://github.com/jobschepens/newproject

# 3. Create a branch, edit, commit, push
git switch -c fix/typo-in-readme
git add .
git commit -m "Fix typo in README"
git push origin fix/typo-in-readme

# → open PR: your fork → original repo (web UI)

# 4. Sync your fork after the PR is merged
git fetch upstream
git switch main
git merge upstream/main

CLI Reference: Resolving a Merge Conflict

# Git marks the conflict in the file like this:
# <<<<<<< HEAD (your branch)
# Participants were recruited via email (N = 48).
# =======
# Participants were recruited via the university mailing list.
# >>>>>>> main

# 1. Open the file and choose which version to keep
#    (delete the markers and unwanted lines)

# 2. Stage the resolved file
git add analysis.R

# 3. Complete the merge
git commit

Note

VS Code, GitHub Desktop, and RStudio all have visual merge editors — you don’t need to edit the markers manually.