Collaboration Workflows with GitHub and gitlab.nrw
20 May 2026
Tip
Prerequisite: Basic Git workflow — clone, commit, push (Session 21)
Session 21 covered
Today adds
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"
mainTwo 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
Branches and forks isolate work until it’s ready to be shared.
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 workmainA fork is a copy of an entire repository under your own account.
original: jobschepens/newproject (you have read access)
your fork: your-username/newproject (you have full access)
| 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.
| 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.
Everyone commits directly to main. Simple, but fragile.
Person A: edit → commit → push → main ✓
Person B: edit → commit → push → main ✗ (conflict!)
When it works:
When it breaks:
The standard for team research projects.
main ──────────────────────────────────► stable
│ ▲
└── feature-branch ────►│ (PR → review → merge)
Full cycle in your tool:
main and pull to get the latestNote
CLI equivalent: git switch -c branch-name → edit → git add . && git commit -m "msg" → git push origin branch-name
For contributing to a repository you do not own.
jobschepens/newproject (original)
│
└── fork ──► your-username/newproject (your copy)
│
└── branch ──► PR ──► original main
Full cycle:
upstream/mainNote
CLI equivalent: git remote add upstream <original-url> → git fetch upstream → git merge upstream/main
Commit one logical change at a time
Commit when the work is in a coherent state
How often?
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.
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
main frequently to avoid driftReview culture
Note
Even in a team of two, the habit of reviewing each other’s PRs pays off quickly — errors get caught, decisions get documented.
Not per commit, not per day — per logical unit of work
Signs it’s time to open a PR / MR
Keep PRs / MRs small and focused
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.
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:
Via github.com (any tool):
main, compare = your branchVia GitHub Desktop:
Tip
If the banner doesn’t appear: Pull requests tab → New pull request → select your branch.
Via gitlab.nrw (any tool):
mainVia VS Code with GitLab extension:
Ctrl+Shift+P) → GitLab: Create Merge RequestTip
Alternatively: left sidebar → Merge requests → New merge request → pick your branch.
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.
On GitHub / gitlab.nrw you can:
| 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.
A conflict occurs when two branches changed the same lines of the same file differently.
VS Code — opens a visual editor automatically:
GitHub Desktop — highlights conflicted files in red:
RStudio — Git pane shows conflicted files with an orange U marker:
<<<<<<<, =======, >>>>>>>) are visibleNote
Conflicts look scarier than they are — you just choose which version to keep.
Issues are not just for bugs — use them for:
Link issues to PRs/MRs with keywords:
Closes #12 in a PR description will auto-close issue #12 on merge.
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.
| 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.
Work in pairs — choose your workflow and tool (GitHub Desktop, VS Code, or RStudio):
Option A — Feature branch (you have write access):
contributors.md, stage and commitOption B — Fork & PR (external contributor):
Tip
Not sure which option? Start with Option A — it’s the most common workflow.
| 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) |
Concepts
The GUI cycle (any tool)
main → pullNote
CLI reference: git switch -c branch → git add . && git commit -m "msg" → git push origin branch → git switch main && git pull
Beginner-friendly
Going deeper
For research specifically
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 versionsdevelop is the integration branchdevelopdevelop → mainNote
For a research analysis pipeline with versioned outputs, a simplified Gitflow (just main + develop) can help.
git add -p)If one file has multiple unrelated changes, you can stage them separately:
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.
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:
mainTip
Even a two-person project benefits: it makes the PR workflow mandatory and prevents accidental direct pushes to main.
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-criteriaFor 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# 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 commitNote
VS Code, GitHub Desktop, and RStudio all have visual merge editors — you don’t need to edit the markers manually.
RDM Workshop Series · SFB 1252 Prominence in Language · Universität zu Köln