1 of 28

Version Control and Collaborative Workflows

Fall 2026

1

2 of 28

Reminder of what we did last week

  1. Discussed the version control readings
  2. Practiced a “simple” GitHub workflow with the class-exercises-fall2026 repo that involved:
    1. Forking and cloning it
    2. Creating a new branch
    3. Created a new folder (lab02)
    4. Adding some new files (ContainsPair.java, contains_pair.py)
    5. Pushing your branch to GitHub
    6. Making a pull request

3 of 28

Today’s Agenda

  1. Reading discussion
  2. Collaborative Workflows
  3. Activity

3

4 of 28

Today’s Agenda

  1. Reading discussion
  2. Collaborative Workflows
  3. Activity

4

5 of 28

Discussion Questions

  1. When you clone a repository what happens? What files are downloaded from the origin?
  2. What commands do you issue to put one of your own local directories under version control?
    • After issuing that command, what happens, specifically?
  3. What data structures does git use? How do they work together?

6 of 28

When you clone a repository what happens? What files are downloaded from the origin?

    • ​

7 of 28

What commands do you issue to put one of your own local directories under version control? After issuing that command, what happens, specifically?

8 of 28

What data structures does git use?

​

Git uses three core object types:

Blobs – A blob stores the actual contents of a file at each commit. Each time you commit a file, a new blob is created that stores the entire contents of the new file (even if you just change one line).

Trees or Graphs– A tree is a snapshot of the directory structure of your repo at a particular point in time. Remembers things like file names, what file is stored where, permissions, etc. A tree has pointers to the current version of the blob at each point in time.

Commits – A commit contains metadata (e.g., author, timestamp, commit message) and a pointer to a single tree object that represents the state of the project at the time of the commit.

9 of 28

Tl;dr Data Structure Summary

​

  • Git uses a graph data structure to keep track of branches, commits, and which changes belong to which commits.
  • When you create a new branch, the most recent commit becomes the root of your new branch. Then, later, you can figure out how to connect it back to the main code branch (often called “the trunk”)
  • Merging and rebasing are two strategies for reintegrating the changes associated with the branch by modifying the pointers, and sometimes the underlying code if there are conflicts.

10 of 28

Today’s Agenda

  1. Reading discussion
  2. Collaborative Workflows
  3. Activity

10

11 of 28

Collaborative git workflows

When you start collaborating with other people, the workflow gets more complex. A few other concepts to introduce here:

  1. Branching
  2. Rebasing v. Merging
  3. Pull Requests
  4. Handling conflicts

11

12 of 28

Branching

Branches allow you to create new features (often experimental) without altering the main branch (where the authoritative version of the code lives).

Important ideas:

  • Think of branches as “works in progress”
  • You can easily create new branches and switch between them
  • Use “pull requests” to incorporate branches into the codebase

12

13 of 28

Branch Commands Using git

13

git checkout -b my-new-branch

Creates a new branch

git branch

Tells you which branch you’re on

git checkout main

Switches you from your current branch to the main branch

git checkout my-new-branch

Switches you from your current branch to the my-new-branch branch

git branch -d my-new-branch

Deletes my-new-branch from your local repo

git merge my-new-branch

Merges changes from my-new-branch into the current branch.

git rebase my-new-branch

Rebases changes from my-new-branch into the current branch.

14 of 28

Understanding Code History

15 of 28

Basic Git History

  • A is the first commit you ever made
  • C is your most recent commit

16 of 28

Feature Branch

You decide you want to make a new login page for your app. You make a new branch called Feature-Branch and make 3 commits Z, Y, and X that collectively have code for the login page. You are now ready to integrate your branch into the main codebase.

What should happen next?

17 of 28

Fast-Forward

Since no one else has made any changes to the repo since you made your branch, you can simply integrate your changes using a “fast-forward”

  • Head is updated to point to Feature-Branch

18 of 28

Feature-Branch When Main is Ahead

New scenario: Since you made your branch, new code (commit D) has been incorporated into the repo that your code doesn’t have.

What should happen next?

19 of 28

Option 1: Merge Commit

A merge commit creates two parent pointers:

  • One to your updates (X)
  • One to the most recent updates from your collaborator (D)

20 of 28

Option 2: Rebasing

  • Can we fast-forward?
  • Not immediately!
  • Why not?

21 of 28

Option 2: Rebasing

Rebasing involves actually making your code history look like you actually branched from D (your collaborator’s commit). In other words, you “rewrite history”. The steps:

  • Re-apply changes to create 3 new commits on top of D
  • Then, fast forward

22 of 28

One More Option: Squash

  • Squash branch into a single commit and rebase.

23 of 28

Conflicts

What happens if Commit D and Feature-Branch modify the same file?

  • Merge: conflicts are handled in Merge Commit
  • Rebase: conflicts are handled during the rebase process (e.g., Z’, Y’, and X’)

24 of 28

Handling Conflicts

  • Git conflicts can happen when two developers edit the same file on their (respective branch) and git can’t figure out how to reconcile the changes automatically (should I use Developer A’s changes, Developer B’s changes, or some combination of the two)?
  • Conflicts are a normal part of collaborating with other people, but can be minimized through solid communication and planning.

24

25 of 28

Trade-Offs

Merge Commits

  • Generally easier in practice
  • Back out an entire branch with a single commit
  • Preserves Full History�

Rebase

  • Maintains Linear History
  • Rewrites History

26 of 28

Class policy decision: rebasing instead of merging

27 of 28

Pull Requests

  • When you’re ready for the code on your branch to be reviewed, make a pull request on GitHub.
  • There, it will be reviewed, and when it’s ready, it will be incorporated into the codebase (via merge or rebase).

27

28 of 28