Module 2 · Version Control Systems
On this page 24 headings
Learning goals: How Git records history, how repositories communicate and how teams use branches, merging and rebasing.
Why Teams Need Version History
When different developers change the same application, an accidental defect can enter the code. Version history records earlier states so the team can understand what changed and can recover a stable version when necessary. This does not mean every new change is automatically correct.
Remember: Keep history so mistakes can be investigated and earlier versions recovered.
Client-Specific Versions
A software product may share common features across customers while including some customer-specific work. Version control helps developers manage different lines of development and trace which changes belong where. Without a clear strategy, maintaining several versions can become confusing.
Remember: Share common work where appropriate and track customer-specific changes carefully.
What Version Control Tracks
In software engineering, version control systems fall under software configuration management. They track and manage changes over time through branching, merging and commits; maintain different revisions with labels, e.g. 1.2, 1.3, 2.0, 3.2.1; and maintain change history including who changed what. Additional features (not exhaustive) include comparing revisions, integrated code-review tools, issue-tracking tools and collaborative development.
Remember: History is more useful when changes and commit messages are clear.
Centralised vs Distributed VCS
Centralised VCS: a central repository on a server that everybody shares; a client–server model. Check out the whole or part of the repository → make changes → push back to the server. Examples: Perforce, SVN. It is highly dependent on the server: if anything goes wrong, development halts until the server is up again; the entire history can be lost if no backups are configured. Distributed VCS: the entire repository, with full change history, is mirrored locally; central hosting is possible but there is no complete dependency on it. Git is one of the most popular distributed VCS.
Remember: Git is distributed: local repositories contain commit history.
Why are version control systems important?
Version control increases productivity; improves communication and collaboration; saves space on multiple revisions through diffs/snapshots; and improves efficiency even as teams scale. Nowadays the question is not whether to use one, but which one to use.
Git and ways to use it
Git is free and open source, originally authored by Linus Torvalds in 2005 for development of the Linux kernel. Its focus is speed (nearly every operation is local), data integrity (the entire repository is mirrored, with multiple copies, making data very hard to lose), and working on multiple tasks simultaneously through multiple branches and parallel development.
Using Git
Use the command line (install git), use Git with IDEs, or use the GitHub portal through a GUI.
Three States of a Git File
A Git file can be modified in the working directory, staged (marked) with git add, and committed to local history with git commit. Only staged files are committed, even if more files were modified.
Remember: Working Directory → Staging Area → Local Repository.
Local Repository and Remote Repository
The local repository belongs to a developer's computer; the remote repository is a shared location used for collaboration. git push publishes suitable local commits to the remote, while git pull brings remote changes into the current local branch and integrates them. Pulling may require resolving conflicts.
Remember: Local and remote histories communicate, but are not automatically identical.
Start a Repository: Init or Clone
Use git init when you have a new project folder and want Git to begin tracking it. Use git clone when an existing repository already lives elsewhere and you want a local copy. Both can lead to a local Git repository, but their starting situations are different.
Remember: New folder: git init. Existing repository: git clone.
Git Add, Commit, Push
A typical publishing sequence starts with files in the working directory. git add selects the changed content for staging; git commit records a local snapshot; git push sends appropriate local commits to a remote repository. The middle step matters: staging and committing are not the same as publishing.
Remember: git add → git commit → git push; each command has a distinct purpose.
Git Pull Updates Local Work
Imagine Developer A pushes a change. Developer B's existing local copy does not automatically update. When B runs git pull, Git obtains and integrates remote updates into the current local branch. Git may report a conflict if B has incompatible local work.
Remember: Pull before collaborating on shared code, and read any conflict message carefully.
More Git Commands
git status reports file states. git diff shows changes between commits, a commit and the working tree, etc. git reset HEAD <filename> unstages the file. The lecture describes git checkout <filename> as undoing changes that are committed but not yet pushed to remote. git log shows commit history.
Remember: Inspect the state before modifying history or the staging area.
Branches Let Developers Work Independently
A branch is a pointer to a commit/snapshot; the default branch in the lecture is master, created at initialization. A developer can switch branches on the fly. git branch feature1 creates a branch; git branch lists local branches; git checkout <branch> switches; git checkout -b <branch> creates the branch if it does not exist.
Remember: Branches separate ongoing work until the changes are deliberately integrated.
Merge Combines Work
A merge combines work from branches. Git does a three-way merge if there are no conflicts; else resolve the conflicts and then merge.
Remember: Run git merge feature1 while checked out on the destination branch.
Urgent Issue Interrupts a Feature
Sometimes a high-priority bug needs attention before a planned feature is done. Rather than mixing unfinished feature code into an emergency fix, create a separate issueP branch from the stable base, fix and test the bug, merge the fix, and return to feature1. The feature work stays on its own branch.
Remember: An urgent fix should not force unfinished feature code into production.
Feature Branch Starts at C2
In the lecture example, the existing history is C0 → C1 → C2, and master points to C2. Creating feature1 at that moment makes feature1 point to the same C2. No new commit is required just to create the branch name; the two branches separate when new commits are made.
Remember: After branching, master and feature1 can initially point to the same commit.
Feature Commit C3 and Priority Commit C4
Next, the feature branch receives commit C3, while the urgent issue branch receives a separate commit C4. Both descend from the common earlier work C2. The C3 feature work and the C4 urgent fix are independent until the team chooses to combine them.
Remember: C3 and C4 are siblings in the original branch history, not consecutive commits.
Merge Priority Fix Before Feature
git checkout master; git merge issueP; git branch -d issueP. The master pointer moves from C2 to C4. Then master is ahead of feature1 by one commit.
Remember: Merge issueP into master, then delete issueP.
Merge Feature After Priority Fix
git checkout master; git merge feature1. Git does a three-way merge if there are no conflicts; else resolve the conflicts and then merge.
Remember: Merge feature1 into master after incorporating the priority fix.
Merge Conflicts: Resolve, Then Merge
If a file x.py was changed in issueP (C4) and also in feature1 (C3), Git does not know which changes to keep; you are asked to resolve the conflicts if Git cannot.
Remember: Resolve the conflicts, then merge.
Rebase: Why Feature Needs fun1()
feature1 needs fun1(), but fun1() was added on master after feature1 branched. Rebase incorporates changes from one branch to another, changing the base commit of feature1 so fun1 is available to test locally. Conflicts can occur while rebasing; resolve them to complete the rebase.
Remember: Rebase changes the base commit of feature1.
Git Rebase Replays Commits
git checkout feature1; git rebase master → feature1 is at C5 on top of C4. Then merge feature1 into master, after which both point to C5.
Remember: After rebase, feature1 points to C5; after the subsequent merge, master also points to C5.
Quick revision and self-check
Question: Does git commit push changes to the remote?
Answer: No. Commit saves local history; push publishes suitable commits.
Question: Where does feature1 point immediately after it is created from C2?
Answer: At C2, the same starting commit as master.
Question: After rebasing feature1 on C4, does master automatically move to the replayed commit?
Answer: No. Only the feature branch moves in the illustrated rebase.
For more details, see the book at git-scm.com.
