How Developers Code & Collaborate before Version Control Systems

Introduction

Before modern tools like Git or GitHub existed, developers still worked in teams, often on the same codebase. But without automatic versioning or branching, even simple changes could get messy. So, how did they avoid chaos?

Believe it or not, two command-line tools — diff and patch — laid the groundwork for the version control systems we use today.


🔍 diff: Spot the Differences

The diff command compares two files and outputs the differences between them. It’s the original “code review” tool in the Unix world.

diff original.c modified.c

By default, diff outputs changes in a format that shows which lines were added, removed, or modified.

Example:

Most developers preferred the unified diff (-u) format, which includes context lines for readability:

diff -u original.c modified.c > changes.patch

Command Breakdown:

PartMeaning
diffThe Unix command-line tool for comparing files.
-uUnified format: shows a few lines of context around changes. Preferred for patches and code reviews.
original.cThe original (older) version of the file.
modified.cThe new (modified) version of the file.
>Shell redirection: sends the output into a file instead of printing it to the terminal.
changes.patchThe output file that will contain the diff in patch-friendly format.

This is the resulting patch file that would be sent to other developers:


🔧 patch: Apply the Differences

The patch command takes a diff file (often with a .patch or .diff extension) and applies the changes to a target file.

patch < changes.patch

Example:

This would update original.c by applying the changes described in changes.patch. The magic here is that patch knows how to locate the right place in the file, even if the file has moved around slightly, as long as the surrounding context hasn’t changed too much.

Command Breakdown:

CommandExplanation
cat original.cDisplays the original content of original.c. Shows the code before patching.
patch < changes.patchApplies the patch from changes.patch to the target file (original.c).
cat original.c (after patch)Displays the updated content to confirm the patch was applied successfully.

See how the “Hello World“ changed into “Hello Safi“ by using the patch command.


🧪 A Minimal Workflow

Let’s say Alice and Bob are collaborating on a C program:

  1. Alice writes main.c and emails it to Bob.

  2. Bob makes changes to the file on his machine.

  3. Bob runs:

     diff -u main.c original_main.c > update.patch
    
  4. Bob emails update.patch to Alice.

  5. Alice runs:

     patch < update.patch
    
  6. Now Alice’s local main.c is now in sync with Bob’s changes.


✅ Pros and ❌ Cons of Using diff and patch

ProsCons
Lightweight – No need to set up a full version control system.No history tracking – You only get the current change, not the past.
Portable – Patch files are plain text; easy to email or transfer.No collaboration support – No concept of branches or concurrent edits.
Transparent – Easy to read and understand patch contents.Error-prone – Manual context mismatches can cause failed patches.
Educational – Teaches the core concepts behind version control.No automation – No built-in merge, rebase, or rollback features.
Still relevant – Used in kernel devs and patch-based workflows.Not scalable – Difficult to manage in large teams or complex projects.

Connect with me

  1. Email: m.safi.ullah@outlook.com

  2. GitHub: https://github.com/safi-io/

If you liked the article, make sure to subscribe to this newsletter

If you have any queries, you can also comment on this article.


The Banner Image was generated by https://magicstudio.com/ai-art-generator/

0
Subscribe to my newsletter

Read articles from Muhammad Safiullah Khan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Muhammad Safiullah Khan
Muhammad Safiullah Khan

I am a third-year CS undergraduate student based in Pakistan. Currently, I am focused on sharpening my core skills in computing and programming. My ultimate goal is to become a technology agnostic software engineer. That's all for now!