Collaborating with Git for group projects
Companion to M02 · pull-first habits, shared repositories, conflict resolution
What this page is for
In M02 you met Git and GitHub as a solo workflow: you commit your changes on your laptop, push them to GitHub for backup, and rarely have to think about anyone else’s edits. That changes when you start your group project. Suddenly two or three people are touching the same .qmd files, and the question of whose changes are where becomes real. This page is meant to make that transition feel manageable.
Read it before your first group-project work session. Then come back to the Daily checklist at the bottom whenever you sit down to work with teammates.
What changes when you go from solo to collaborative
When you work alone in a Git repository, the timeline is simple: every commit you make extends a single straight line of history. Push when you want a backup, pull when you’ve worked on another machine, and there’s never any question about which version is current.
Group work breaks that simplicity. Each teammate’s laptop carries its own copy of the repository, each is making commits, and the shared GitHub repository is the place those parallel timelines get reconciled. The same file can be edited by two people at the same time, and the order in which everyone pushes their changes matters. The two skills that hold this together are:
- Pulling before you start working — so you’re editing the most recent version of every file, not a stale copy from yesterday.
- Coordinating who edits what — so you and your teammates rarely touch the same line of the same file at the same time, and conflicts stay rare and small.
The rest of this page unpacks both.
The pull-first habit
The single most important collaborative-Git habit is this: pull before you start working. Every single time.
Why this matters: while you were away from the project — for a day, an hour, even fifteen minutes — your teammates may have committed and pushed changes. If you open RStudio and start editing without pulling first, you’re editing a stale copy of the project. When you eventually push your work, Git has to figure out how to reconcile your edits with the newer history on GitHub — and if you happened to edit the same lines a teammate already edited, you’ve just created a conflict that would not have existed if you’d pulled first.
Pull before you push, too. If a teammate pushed while you were working, GitHub Desktop will ask you to pull before it lets you push — and that is the moment a conflict surfaces, not when you started. Pulling first at the start of a session means you began from current work; pulling again before you push is what reconciles anything that landed while you were busy.
The right rhythm:
- Open your laptop. Don’t open RStudio yet.
- Open GitHub Desktop first. Click the repository in the left sidebar.
- Click Fetch origin (top of the window). This asks GitHub “is there anything new?” — without pulling it yet.
- If GitHub Desktop says “Pull origin” (the button label changes), click it. This downloads any changes your teammates pushed since you last looked.
- Now switch to RStudio and start working.
Most days this pull-first check takes about ten seconds. (Days when GitHub Desktop pulls down a teammate’s work take a little longer; days with a conflict take a few minutes to resolve.) It is one of the simplest habits that prevents bigger headaches later.
The pull-first habit · phrase it as a rule
“Open GitHub Desktop before RStudio. Pull before you type.”
Say it out loud the first few sessions. After a week, it’s muscle memory.
Commit small, push often
Solo Git can hide sloppy commit habits. Collaborative Git makes them visible.
- Commit when you’ve finished one coherent thing. A polished figure, a cleaned-up wrangling chunk, a section of prose — anything that “belongs together.” A useful test: if you had to write a commit message in seven words or fewer, could you? If yes, commit. If not, your changes are doing too much at once and should be split into two commits.
- Every commit is a point you can get back to — and this is the one that will actually rescue you. Sooner or later an edit breaks something that worked twenty minutes ago, and you cannot retrace how. Git can restore a file to its state at any commit, but only as far back as your most recent one: commit every hour and the worst case is losing an hour’s work; commit once a day and the worst case is losing the day. Frequent commits are what turn “I have broken it and I don’t know what I changed” into a minor annoyance. Going back to an earlier version walks through the moves.
- Push at the end of every work session (and ideally at lunch, at coffee, whenever you take a break). Your teammates can’t see — or build on — work that’s sitting on your laptop. Pushing is how you make your contribution available to the team.
- Don’t sit on hours of uncommitted work. Uncommitted edits are not just hidden from teammates; they’re not backed up. A laptop dropped in the parking lot at 4:30 PM takes uncommitted work with it.
The combined rhythm: pull → edit → commit → push. Repeat several times a session, not once at the end.
Coordinating who works on what
The simplest way to avoid conflicts is to make sure two people aren’t editing the same file at the same time. For PSY 652 group projects (typically 2–3 students working on one Quarto notebook), three strategies work well together:
Divide files by responsibility. Project 1, for example, has a single
p1_data_brief.qmdnotebook with sections for the question, measurement, the analytic sample, Table 1, the figures, and what the findings mean. Assign each section a primary editor — the person who makes the keystrokes there, which is what prevents most conflicts.Primary editor does not mean sole expert. At least one teammate should read and review every section, and by the presentation everyone needs to understand the complete analysis — any of you can be asked about any part of it. Divide the typing, not the understanding.
Communicate before opening a file. A quick text or email — “I’m going to edit the wrangling section for the next hour” — is enough. The teammate then waits, or works on a different section. Coordination costs nothing.
Make a small commit and push the moment you finish a focused chunk. The longer your uncommitted edits sit, the more likely a teammate has already changed the same file. Frequent commits and pushes keep everyone’s view of the project in sync.
For a 2–3 person team working in a single notebook, you do not need to learn Git branches (a way to maintain parallel timelines and merge them deliberately). The coordination strategies above are simpler and more than enough.
This is a deliberately simplified course workflow: everyone commits directly to the main branch — but only after pulling first and coordinating who’s editing what. Most professional software teams use branches and pull requests (a structured way to propose changes and have them reviewed before merging into main) for larger collaborations; if you take a more advanced course or contribute to an open-source project later, those are the next things to learn.
When conflicts happen anyway
A conflict happens when Git tries to merge two sets of changes and cannot safely decide what the final file should look like. The most common case is when two people edited the same line of the same file. Conflicts can also happen when one person edited a file and another person deleted or renamed it.
This is normal. Conflicts are not a sign you did anything wrong — they usually mean two people edited overlapping parts of the project before those edits were brought together. Resolving them is a five-minute task once you know the shape.
What a conflict looks like in GitHub Desktop
When you click Pull origin and GitHub Desktop discovers a conflict, it stops and tells you: “There are conflicting files in your repository. You can attempt to resolve them in your external editor.”
If you open the conflicting file in RStudio, you’ll see something like this in the middle of it:
The mean SBP in this sample was
<<<<<<< HEAD
131.4 mmHg, slightly above the clinical threshold.
=======
133.2 mmHg, indicating elevated cardiovascular risk.
>>>>>>> origin/main
The lines between <<<<<<< HEAD and ======= are the version currently on your machine — in a pull-from-main workflow like this one, that’s almost always your edits. The lines between ======= and >>>>>>> origin/main are the version from GitHub — usually your teammate’s edits. Git is showing you both and asking you to choose.
Resolving the conflict
- Decide what the file should say. Sometimes it’s your version, sometimes it’s your teammate’s, sometimes it’s a combination of both. Sometimes a quick text or email — “Did you mean 131.4 or 133.2?” — is the right move before you decide.
- Edit the file in RStudio. Delete the conflict markers (
<<<<<<<,=======,>>>>>>>) and leave only the version you want. Save the file. - Switch back to GitHub Desktop. The conflict marker on the file disappears.
- Commit the resolution. GitHub Desktop will offer a default commit message like
Merge branch 'main' of github.com/.... You can accept it as-is or write something more descriptive (Resolve SBP-mean conflict in wrangling section). - Push. The team’s history now includes both your work and your teammate’s, plus your resolution.
Conflicts feel scary the first time. That reaction is completely normal. After the third or fourth one, they start to feel routine. The most important things to remember are: don’t panic, don’t delete the file, don’t force-push. Just edit the file into the version you want and commit the resolution.
Why you will not get conflicts on the rendered report
Everything above assumes a text conflict you can open and edit. There is one file that would never give you that, and your .gitignore is set up so you never meet it.
The rendered .html regenerates every time anyone renders, and embed-resources: true bakes the figures into it — so two teammates rendering the same source still produce different bytes. If that file were tracked, every push after a teammate’s push would collide on it, Git could not merge it, and hunting for <<<<<<< markers in forty thousand lines of markup and base64 would be hopeless. You would be resolving a conflict about something neither of you had actually changed.
That is exactly why programs/*.html is in your .gitignore. The report stays untracked while you work, and in your final week you delete that one line, have one person render, and commit the result. Project setup and reproducibility has the steps.
If you ever do face a conflict on a generated file — an exported .png in output/figures/, say — do not hand-edit it. The fix is a different shape:
- In GitHub Desktop, resolve the conflicted file by taking either version. It genuinely does not matter which.
- Commit that resolution.
- Regenerate the file by re-running the code that produces it.
- Commit the regenerated file and push.
A generated file has no “correct merge” — the correct version is whatever the current source produces. You are not reconciling two documents; you are clearing the jam and regenerating. If the .qmd is conflicted too, resolve that first — it is a text file, so use the ordinary procedure above — and only then regenerate.
When something isn’t working
Conflicts get the most attention, but four other things go wrong far more often — and all four look alarming while being quick to fix.
“GitHub Desktop says there are no changes”
You edited a file and the Changes tab is empty. Work down this list:
- Is the file saved? RStudio shows your edits on screen while the file on disk is unchanged, and Git only ever sees the disk. An unsaved file shows its name in red with a dot beside it. Press Cmd/Ctrl + S and look again. This is the most common cause by a wide margin.
- Are you editing the folder GitHub Desktop is watching? In GitHub Desktop, Repository → Show in Finder (Windows: Show in Explorer). In RStudio, type
getwd()in the Console. If those two paths are different, you have two copies of the project and have been editing the one Git is not tracking. - Is the right repository selected? GitHub Desktop shows the current one in the dropdown at the top left.
- Is the file one Git is set to ignore? Anything inside
data/raw/ordata/derived/, and — until your final week —programs/*.html. Those are missing on purpose. - Has GitHub Desktop simply lost track? Press Cmd/Ctrl + R to refresh, or quit and reopen it.
“It won’t let me push”
If it asks you to pull first, a teammate pushed while you were working. That is ordinary, not an error: click Pull origin, let it merge, then push. If you both changed the same lines you will get a conflict — see above.
If it says you are not signed in, or the push just fails, your account has become disconnected. Open Settings (Windows: Options) → Accounts and sign in again.
“My teammate can’t see my work”
Committing is not sharing. A commit records the change on your own laptop; the push is what sends it to GitHub. If teammates cannot see something you finished, it is almost always committed but not pushed — look for Push origin at the top of GitHub Desktop with a number beside it.
The mirror image is just as common: if you cannot see their work, you have not pulled.
“I can’t clone the repository”
Check that you accepted the invitation. GitHub sends it by email and it lands in spam more often than you would expect — you can also accept by visiting the repository’s URL while signed in. Until you accept, a private repository is invisible to you and will not appear in GitHub Desktop’s list of repositories to clone.
Fifteen minutes, then ask
None of these is worth an evening. If the list above has not sorted it out in about fifteen minutes, bring it to lab or email us — and say what you have already tried, which usually tells us where to look immediately.
Commit message hygiene
Every commit you make becomes a permanent line in your repository’s history. Six months from now, you (or a teammate, or your future advisor) will scroll through the history looking for when did we change the regression model? — and your commit messages are the only thing that will help.
| Bad | Better |
|---|---|
Update |
Drop participants under 18 from analytic sample |
fix |
Fix legend title in main bar chart |
more changes |
Add gender × age-group interaction to wrangling chunk |
final |
Set final figure caption per professor's feedback |
A useful template for a commit message: a verb in the imperative, followed by what changed, optionally followed by why. “Add age-group recoding to wrangling chunk so adults can be filtered by life stage.” The “why” part is what makes a commit message valuable to future-you.
A few rules of thumb (the don’ts)
- Don’t push broken code. Before you push, render your
.qmdto confirm it still builds. If the render fails, fix it before pushing. Pushing broken work means the next teammate who pulls it has a broken project too — and they may not realize the breakage is yours, not theirs. - Don’t push data files. The starter’s
.gitignorekeeps everything insidedata/raw/anddata/derived/out of Git (M02 covers this), so a.sav,.csv, or.rdsshould never appear in GitHub Desktop’s Changes list. Two things underdata/are tracked on purpose —data/README.mdand the.gitkeepplaceholders — so seeing those is correct, not a problem. But a teammate who edits the.gitignore, or builds a repo from scratch, can undo the protection: if an actual data file shows up underdata/raw/ordata/derived/, stop and ask before committing. - Never force-push
main. A force-push rewrites the shared history and can erase a teammate’s commits. GitHub Desktop will sometimes ask about “forcing” a push when its normal one is blocked. In this course the answer is always no. Pull, resolve any conflicts, and push normally — and if GitHub Desktop insists a force-push is required, stop and ask for help rather than agreeing to it. - Don’t commit credentials. API keys, passwords, anything secret should never enter your repository.
Daily checklist for collaborative work
Every group-project work session
Before you start:
- Open GitHub Desktop before RStudio.
- Click Fetch origin. If “Pull origin” appears, click it.
- Now open RStudio.
While you work:
- Stay in the file(s) your team has assigned you.
- Commit every time you finish a coherent chunk (a figure, a wrangling step, a paragraph). Write a real commit message.
- Render your
.qmdperiodically to make sure it still builds.
Before you stop:
- Render one last time. Fix any errors.
- Commit your final changes.
- Click Push origin.
- Tell your teammates what you worked on — text, email, whatever your team agreed on — so they know what to pull next.