Skip to main content
Introduction to Devops

Git, GitHub, and Version Control

Published: 2026-08-14
Level: postgraduate
Audience: Postgraduate students of software engineering and delivery

Git, GitHub, and Version Control

The session opens with the cloud, which acts as a catalyst that speeds up the whole DevOps process, and then moves to the first real tool of the DevOps toolchain: the version control system. We cover the logic behind Git, how Git and GitHub work together, and the basic workflow you will exercise by hand in the tutorial session, where you will run the Git commands yourself. The virtual-lab platform also carries tutorials you can use to practice these commands. The agenda for the sessions ahead runs through the build automation step, then continuous integration, where the build process is integrated with unit testing and Selenium automation.

7.1 Cloud as a Catalyst for DevOps

Hook: Why does every DevOps discussion start with the cloud? Because the cloud removes the slowest part of the old delivery chain — ordering hardware and waiting for it to be configured — and replaces it with a request you can make in minutes. Before a single DevOps tool can speed anything up, the infrastructure has to be available on demand. That availability is exactly what the cloud provides.

The cloud is not a single product from one company. It is a way of delivering computing that any platform — public providers like AWS or Azure, or an organization's own private cloud — either follows or fails to follow. The categorization of cloud computing comes from NIST, the United States standards organization that defines cloud categories. Any cloud platform or cloud technology must satisfy a basic set of requirements, and each one maps to a promise it makes to its users.

7.1.1 The essential characteristics of cloud computing

NIST lists five characteristics that every genuine cloud offering must have. Think of them as the five promises a cloud provider makes, and the five tests you can run against any vendor who claims to sell you "cloud".

  • On-demand self-service: you request the computing you need yourself, directly, without going through human ordering. There is no ticket, no phone call, no waiting for an administrator to approve you. You click, or you run a command, and the resource appears.
  • Broad network access: the cloud services are reachable over the network from anywhere. A laptop in a hotel, a phone on a train, and a workstation in the office can all reach the same service through standard access methods, which is what makes remote and distributed teams practical.
  • Resource pooling: the provider pools its resources and serves many consumers out of that shared pool. One physical machine may host many virtual machines from different customers, and the pool is shared and reassigned as demand shifts. A customer usually does not know exactly which physical server their workload sits on.
  • Rapid elasticity: capabilities can be elastically scaled up or scaled down as per the need. If your load grows, you grow; if it shrinks, you shrink. To the customer the supply looks almost unlimited — you can take as much as you want at any time and give it back when you are done.
  • Measured service: the service is metered, because it must allow pay-per-use. You pay for the tenure during which the computing is actually used for your product or your service. The provider monitors and reports usage, so both sides can see exactly what was consumed.

From an operations standpoint, the two most important of these are on-demand self-service and measured service: the first is what makes automation possible, and the second is what forces you to keep the automation honest — every resource you leave running is a bill you keep paying.

Broadly, these characteristics sit underneath the service offerings that any cloud service or cloud industry provides: SaaS, PaaS, IaaS, and one more, serverless computing, which is also called function as a service. Today the focus stays on SaaS, PaaS, and IaaS.

Intuition — the electricity-grid picture: The standard analogy for the cloud is the electric grid. You plug a device into a wall socket and it works; you are charged for the electricity you use; and you do not need to know how the power company generates it. The cloud is the same: you ask for computing, you pay for what you consume, and you remain happily ignorant of the machinery behind the socket. The analogy breaks at the moment of an outage — when the power fails, you suddenly become very aware that complicated machinery exists behind your socket. The same is true of the cloud: a provider's outage makes you aware that many physical machines, networks, and disks stand behind the simple request you made.

7.1.2 Three ways cloud fastens the DevOps process

The motivating question is simple: why does cloud become the catalyst for DevOps, and how does it speed up the DevOps process? Three unique impacts of cloud on the DevOps process stand out.

First: the ability to create and switch environments simply. An environment is the full set of computing resources needed to run your software — servers, supporting software, data, network settings, and the external services it talks to. In-house, creating a fresh environment meant procuring machines and configuring them by hand. With a cloud platform it is very easy to create virtual machines, and any environment you want can be created with just a request. The environment becomes ready and available, and you can switch around the environment very easily. Simply creating and migrating environments makes it easy to clone new instances. If a test environment is corrupted, you do not repair it — you destroy it and spin up a fresh clone in minutes. DevOps relies on having separate environments for development, integration, user testing, and production, and the cloud makes maintaining that separation cheap instead of expensive.

Second: the ability to create VMs easily. Whenever you want to increase the capacity of your server or increase the number of instances, you can easily create new VMs, and whenever a VM is no longer required you can stop paying for it by stopping the VM. That pay-per-use logic needs automation and monitoring. Take an organization that opted for thousands of VMs running on a cloud platform. With a thousand VMs you pay for a thousand running instances, so you have to keep an eye on which instances are running and which unused ones should be shut down to stop the extra cost. Doing that manually means clicking the stop button on each instance yourself — a thousand clicks, repeated every time the workload changes. There is a tool called Janitor Monkey that brings automation to this field: it scans the account and the number of VMs, works out which VMs are not getting used in terms of balancing capacity and balancing load against user requests, and when certain VMs are not responding to requests, it automatically shuts down those unused VMs to stop the charges against them. The industry name for the underlying problem is VM sprawl (the mess created when too many virtual machines exist and nobody tracks them), and Janitor Monkey is one of the tools built to sweep it up.

Third: management of databases on the cloud platform. Managing a database on a cloud platform is very easy because you do not have to care about where the disk storage comes from. You do not worry about provisioning storage; you simply ask for storage to hold your database. The provider handles the physical disks, the replication, and the backups; you ask for a database of a certain size, and you get it.

7.1.3 Why the cloud removes waste

These three aspects improve the DevOps process because they remove waste from it. In-house, the pipeline used to be: order the hardware, order the storage devices, configure everything together, and only then start working on your application. On the cloud, the environment is ready on demand, storage for your database is available on request, and you can increase or decrease capacity as per the need of the market. The time you would have spent on hardware procurement and setup disappears, which is exactly why the cloud fastens the DevOps process.

Step in the old pipeline In-house (before cloud) On the cloud
Getting the hardware Order machines, wait for delivery, install in a datacenter Request VMs, ready in minutes
Getting the storage Order disk arrays, mount and format them Ask for storage; the provider provisions it
Configuring everything Install OS, patches, middleware, and settings by hand Pick an image or template; it arrives configured
Scaling to demand Buy more hardware in advance or wait Create or stop VMs as load rises and falls
Starting real work Only after every step above Immediately, on day one

This is the professor's own framing of why the cloud matters: every step that used to consume weeks of calendar time has collapsed into a request. The cloud does not make your application run faster — it removes the waste that used to sit between an idea and a running environment, which is precisely the kind of waste DevOps exists to eliminate.

Real-world: the NIST characteristics are the standard yardstick for judging any cloud offering, and the Janitor Monkey pattern of automated cleanup of unused virtual machines is a real cost-control practice for organizations running large fleets of cloud instances. The same pattern appears in many forms — AWS itself offers features that stop or end idle resources, and Netflix's Simian Army (of which Janitor Monkey is a member) is a documented, public example of automating hygiene at cloud scale.

Recap: The cloud is a catalyst for DevOps because it removes waste. On-demand self-service and measured service let you create, switch, and destroy environments on request, scale VMs up and down, and provision database storage without touching hardware — and because you pay per use, unused VMs must be shut down, which is exactly what automated tools like Janitor Monkey do. Next, we look at the three service models built on top of these characteristics — SaaS, PaaS, and IaaS — and what each one hands over to you.

7.2 Cloud Service Models: SaaS, PaaS, and IaaS

Hook: When you buy computing from a cloud provider, how much of the stack do you still control — and how much do you hand over? The answer to that single question separates the three service models cleanly: Software as a Service, Platform as a Service, and Infrastructure as a Service. The model you choose decides who patches the operating system, who manages the disks, and who is responsible when something breaks.

The three offerings are software as a service, platform as a service, and infrastructure as a service. The clean way to separate them is to ask: what does the consumer get, and what does the consumer still control?

7.2.1 Software as a Service (SaaS)

In SaaS, the consumer is provided the capability to use the provider's application running on cloud infrastructure. Take web-based email as an example. The email application of some provider is available on the cloud platform, and as a consumer you are able to access that email box from any place. SaaS means you are accessing one particular application that is running on the cloud platform. Being a consumer, you have no access or control to manage the cloud infrastructure — not the network, not the servers, not the operating system, not the storage. You do not even touch the licensing, because the vendor deals with the licensing of the software. Correlate this with Google Apps, Cisco WebEx, or Office 365. So if somebody asks which is the most restricted service provided by a cloud platform, the answer is SaaS, because you have no access control on the infrastructure at all.

Two details make the model concrete. First, the application is reached through a thin client — usually a web browser — so your own machine does very little work; the browser is a window into the provider's application. Second, you are not buying a piece of software you install; you are buying a service that already runs somewhere, and the provider runs, patches, and upgrades it for everyone at once. When Gmail adds a feature, every user gets it without installing anything. That is the SaaS promise, and the price of the promise is that you cannot touch the machinery underneath.

7.2.2 Platform as a Service (PaaS)

In PaaS, the consumer is provided the capability to deploy onto cloud infrastructure. The applications being deployed are created using programming languages, libraries, and services, and they can be either created by the consumer or acquired. The idea is a platform where the consumer wants to push their code or push their application for deployment. The consumer is not creating their infrastructure and is not controlling the network, servers, operating system, or storage — they are dealing with the application side. What the consumer does is specify what they want: for example, a .NET platform with Tomcat, with such and such libraries, services, or programming languages. You give that order to the cloud provider, and the provider returns the platform to you to perform the rest of the action. With PaaS you still do not manage or control the underlying cloud infrastructure, but you do have control over the deployed applications and possibly over the configuration settings for those applications' hosting environment. So you hold some authority to manipulate the configuration settings needed for the application you are going to deploy.

A typical PaaS interaction looks like this: you compile a Java web application into a deployable package, tell the provider which runtime you want, and push your package onto it. The provider runs the web server, keeps the operating system patched, and gives you dials for the settings you care about — how many instances to run, which database service to connect to. You never see the servers, and you never log into them. The trade-off is visibility: PaaS hides the lower layers so you can focus on your application, but if you later need deep control over the network or the operating system, moving out of the platform becomes harder.

7.2.3 Infrastructure as a Service (IaaS)

In IaaS, the consumer is provided the capability to provision processing, storage, networks, and other fundamental computing resources as per their need. The consumer can create their own infrastructure and start from provisioning it: what kind of operating system package they want, what storage is needed, which networks, which other computing resources. Everything is created by the consumer on the cloud platform. Talk about an EC2 instance: if you say you are creating an AWS EC2 instance, you deploy the required configuration settings for that EC2 instance. You give an order like "EC2 instance with Linux operating system" or "EC2 instance with Windows operating system", and under that, whatever you want to do, you can deal with it. This is infrastructure or a server being created by the consumer but on the cloud platform — not in-house ordering of hardware and then configuring it together. You get on-demand infrastructure. With IaaS the consumer still does not manage or control the underlying cloud infrastructure, but the consumer has control over the operating system, the storage, and the deployed applications. Possibly you also have limited control of selecting the networking topology in terms of host firewalls and so on. So IaaS comes with full access: here you have very limited restriction.

Mechanically, what you order is a virtual machine (an emulation of a physical computer) created from an image — a file containing a bootable operating system and the software installed on it. When you say "EC2 instance with Linux", the provider finds a physical machine, starts a virtual machine on it from a Linux image, gives it an IP address, and hands the controls to you. From that moment the machine behaves like a standalone computer you own — you install software, patch the system, and configure the network, all on the cloud platform rather than on hardware you ordered in-house.

The three models form a spectrum of control. SaaS gives you the least control, PaaS adds control over your deployed applications and their configuration, and IaaS gives you control over operating system, storage, deployed applications, and even some networking choices.

Dimension SaaS PaaS IaaS
What you get A ready-made application A platform to deploy your application on Raw computing: servers, storage, networks
What you bring Nothing — just users Your code (created or acquired) Your operating system choice and your software
Who manages the infrastructure Provider entirely Provider (network, servers, OS, storage) Provider only the physical layer; you manage OS, storage, apps
What you control Almost nothing Deployed applications and some hosting settings OS, storage, deployed apps, some networking (firewalls)
Example Web-based email, Google Apps, Cisco WebEx, Office 365 A .NET or Java platform you push your application onto AWS EC2 instance you configure yourself

When picking between the models, the rule of thumb is: take the least control you can live with. If a ready-made application covers your need, choose SaaS; if you want to ship your own code without caring about servers, choose PaaS; if you need the operating system and network in your own hands, choose IaaS.

7.2.4 Serverless computing and function as a service

The fourth offering, serverless computing, is also called function as a service, or FaaS. It is mentioned today so you know it belongs on the same map of service offerings, and it will be covered in detail in subsequent sessions. For now, the key idea to keep in mind is that it takes the sharing of responsibility even further than PaaS: you hand the provider a function, the provider runs it when events arrive, and you pay only for the time the function actually executes.

7.2.5 Real-world: where the three models show up

Real-world: web-based email is the classic SaaS example — you consume the provider's application, the provider manages everything underneath, and the vendor handles licensing. Google Apps, Cisco WebEx, and Office 365 all ride on the SaaS model.

Real-world: AWS EC2 is the classic IaaS example. You order a virtual server with the operating system you choose and configure it yourself, which is exactly the provisioning story IaaS describes.

Real-world: PaaS sits between them — you hand the provider a specification of the platform (language, libraries, application server) and push your application onto the platform it returns.

Recap: The three service models are a spectrum of control. SaaS hands you a finished application and takes away every management task; PaaS hands you a platform and takes care of everything below your deployed application; IaaS hands you virtual machines and puts the operating system, storage, and networking decisions back in your hands. The deciding question is always the same: what do you get, and what do you still control? Next we leave the cloud behind and meet the first real tool of the DevOps toolchain — the version control system.

7.3 Version Control Systems: History and Generations

Hook: Have you ever saved over a file, realized minutes later that the previous version was the good one, and found that version gone forever? That single experience — a change you cannot undo — is the problem version control exists to solve. It records every change you ever make, so no version ever has to be lost again.

7.3.1 What a version control system does

A version control system is a system that records the changes to a file or set of files over time. Because every modification is tracked, anybody who wants to recall any previous version can easily do so. That single capability — keeping a track of all the modifications made to files over the life of a project — is the entire reason the discipline exists.

Version control systems go by several names — source control and revision control systems — and they are also known as the system of record for a project: the one authoritative codebase that everyone agrees is the truth. What gets tracked is not limited to code. Source code, documentation, database definitions, build scripts, and test files all live under version control, because the team needs the same history for every artifact that goes into building the software. The name of the game is always the same: record every change, so that any point in the project's history can be recalled.

7.3.2 Why version control matters

The benefits follow directly from that definition:

  • Change history: you keep a track of change history, and you can see who made what change at what time. Every modification is dated and attributed, so the project carries its own autobiography.
  • Concurrent working: this brings more collaboration. In the first generation, collaboration happened through a shared folder, and that shared folder worked like open heart surgery — anyone could access it at any time, and that became difficult to manage. Anyone can reach into an open chest and touch anything; a shared folder works the same way, and when two people edit at once, the folder cannot tell whose change came first or how to combine them. To manage great collaboration, and to trace conflicts and resolve those conflicts, you need a better version control system, which is where the second and third generations came in.
  • Traceability: you can trace who changed what and when across the whole project. When a defect appears, the history tells you which change introduced it, who wrote it, and why it was written.
  • Backup and restoration: since you are tracking all the changes to your files over time, you can back them up, and wherever you feel there is a problem, you can restore it easily. A broken change is not a disaster; it is just one entry in the history that can be rolled back.

7.3.3 The three generations of version control

The history of version control is told in three generations, and the cleanest way to separate them is by how networking and concurrency work.

First generation: there was no networking. Operations worked on one file at a time, and concurrency was maintained by locking the file. Think of the older behavior of a shared Google Sheet: if somebody clicked and started editing, the sheet used to get locked for others. That is the concurrency model — one file at a time, and if somebody is accessing it, it gets locked for others. The examples of first-generation version control systems are RCS and SCCS. RCS stands for Revision Control System, and SCCS stands for Source Code Control System. The reference material confirms the pairing: SCCS was written in 1972 at Bell Labs, and RCS evolved from the same lineage — so the garble "RCS, SC, CS" in the source resolves to RCS and SCCS.

Second generation: networking was centralized. Systems like SVN, or Subversion, belong here — most students will have worked on SVN. You can operate on multiple files, and concurrency is maintained with merge before commit: before you commit to the remote repository, you refresh your own repository with the central repository. If you are still using SVN, the first thing before you commit is always a merge, to make your local view up to date with the central repository.

Third generation: networking is distributed. Work happens through change sets, and the concurrency model becomes commit before merge: you first commit into your local repository and then you merge into the remote repository. Git, Bazaar, and Mercurial are the third-generation systems. Git was created by Linus Torvalds to maintain the Linux kernel, Mercurial is used by the Mozilla Foundation, and Bazaar is used by Ubuntu — the reference material confirms all three names. Bitbucket, which also appears in the source, is not a version control system itself; it is a hosting platform for Git repositories, in the same family as GitHub.

Generation Networking Unit of work Concurrency Example tools
First None — local only One file at a time Locking (whoever edits first blocks the others) RCS, SCCS
Second Centralized Multiple files, whole module Merge before commit (refresh from central repo, then commit) Subversion (SVN)
Third Distributed Change sets Commit before merge (commit locally, then push and merge) Git, Bazaar, Mercurial

7.3.4 First generation in detail: locking and shared folders

The first-generation story deserves a little more texture, because it explains why the later generations exist. With one file at a time and locking, two people could not work on the same file simultaneously — one held the lock, the others waited. Collaboration through a shared folder removed the lock but replaced it with a worse problem: the folder is open heart surgery, because anyone can access it at any time, and conflicts pile up with no mechanism to trace and resolve them. The need to trace and resolve conflicts cleanly is what pushed the industry toward the centralized model of generation two and then the distributed model of generation three, which is what we use with Git.

The locking style is known in the literature as pessimistic locking: before you edit a file you must get an exclusive lock, and everyone else is turned away until you release it. It prevents conflicts by preventing parallel work — which is exactly its weakness. On a larger team, developers wait for files they need, and refactoring a codebase becomes nearly impossible because every file you touch has to be locked one by one. The later generations use optimistic approaches instead: everyone edits freely, and the system merges changes when you commit, calling on a human only when two edits genuinely clash.

Real-world: version control is the backbone of every software team — open-source projects like the Linux kernel (with its thousands of contributors) and commercial products alike depend on it, and the release of a product is unthinkable without the ability to recall any historical version of the code.

Recap: A version control system records every change to a file or set of files over time, giving you change history, concurrent working, traceability, and backup. The three generations are: first, no networking with file locking (RCS, SCCS); second, centralized networking with merge before commit (SVN); third, distributed networking with commit before merge (Git, Bazaar, Mercurial). The move from locking to merging is the whole story — next we look at the centralized and distributed models side by side.

7.4 Centralized vs Distributed Version Control

Hook: Who holds the history of your project — one server, or every workstation? That single architectural choice splits the version control world in two. Centralized systems (the second generation) keep all history on one central server; distributed systems (the third generation) copy the full history onto every developer's machine. The difference sounds small, but it changes the daily rhythm of every developer who uses the tool.

7.4.1 Centralized source code management

In centralized source code management, like the second generation, the version control of the files happens only at the centralized server. There is no version control system managed on the local desktop or local environment. Picture two local systems: one employee working on one part of the project, another employee working on another part. In SVN, nobody used to clone the full project — people cloned only the module on which they were going to participate. So on the local system you do not have a version control system at all. You work with merge before commit: take an update from the centralized version control system, make your subsequent updates, bring your local repository up to date, and then commit your code to the centralized server. That is how SVN, or any centralized source code management system, works.

The name says it all: the version control system lives on the server. Your desktop holds only a working copy of the files you checked out, with no history of its own. Every check-in travels over the network to the central repository, which is the single source of truth — and the single point of failure.

Worked example — a day with centralized SVN: Two employees, A and B, work on the same project. A is assigned the login module, B the billing module. In SVN neither employee clones the whole project; each checks out only the module they will work on.

  1. svn checkout <server>/login — A pulls the login module into her working copy. Her machine now has files, but no repository and no history.
  2. A edits login.py for an hour.
  3. svn update — A refreshes her working copy from the central server before committing. If B touched a shared file, A's working copy is now merged with B's changes locally.
  4. svn commit — A's change travels over the network to the central server, which records the new revision.

The order is fixed: merge before commit. The merge happens on the way in, so the central repository never receives a change that conflicts with the latest state it already holds.

7.4.2 Distributed source code management

In distributed source code management, you have a version control system on both sides — on your local system and on the remote server. You definitely need a remote server, because every organization needs a central place where the work of all team members can be collaborated. There can be multiple teams working on the same project, and each team has multiple members contributing — say team one with eight members and team two with nine members. To collaborate all that work you need a remote server, and every team member also has their own local repository: a version control system on their own workstation. The full project is available to every team member. And that is where the workflow differs: you commit first in your local system, then merge to the remote system by pushing the code to the remote system and creating a merge request.

Two things change compared with the centralized model. First, the full project — every file and the entire history — lives on every workstation, not only on the server. Second, the commit order flips: you commit into your own local repository first, and only later do you push those commits to the remote server, where they are merged with everyone else's work.

Worked example — a day with a distributed system (Git): A project has two teams — team one with eight members, team two with nine members — all working on the same codebase. The remote server (for example, a GitHub repository) holds the shared work; each of the seventeen members also holds a full local repository.

  1. git clone <remote-url> — A gets the full project, complete history included, onto her workstation for the first time. This first clone is the one network-heavy step.
  2. A edits the files, then git commit — the change is saved into her local repository. No network was used, and nobody else can see the change yet.
  3. A repeats: edit, commit, edit, commit — as many local commits as she likes, all offline and fast.
  4. git push — A's commits travel to the remote server, and she creates a merge request so the team can review and merge her work into the shared line.

The order is commit before merge: the commit happens locally, and the merge with the remote happens later, only when she pushes. If the remote has moved on since her last pull, the push is refused and she first refreshes, merges, and pushes again.

7.4.3 Advantages and disadvantages of each

Looking at both models side by side:

  • Centralized — single point of failure. If everything is lost from the central server, it is really difficult to restore, because you do not hold an exact copy of the full project anywhere else, and restoring it is tedious. In distributed, the version control system exists on each and every team member's system, so the project is never held in one place only. If the central server burns down in the distributed model, any developer's machine can rebuild it.
  • Centralized — remote commits are slow. Every operation or change you make gets committed to the central server, so every commit is a remote commit. In distributed, apart from push and fetch, every command works on your local system, so work is really fast.
  • Centralized — continuous connection. You need a continuous internet connection to work with the centralized server and maintain your version control system. In a DVCS you do not need an internet connection until and unless you are pushing your changes to the remote repository. A developer on a train or an airplane keeps working at full speed in the distributed model.
  • Distributed — you need more space. Because an exact, full project is available on the local system as well, you need more disk space. Every clone is a full backup, and full backups cost disk.
  • Distributed — you need great bandwidth. During the first phase, when you clone the project into your local system for the first time, a large project needs great bandwidth. That first clone moves the whole history, not just the files you need.
Dimension Centralized (e.g., SVN) Distributed (e.g., Git)
Where the history lives Central server only Every workstation plus the remote server
Commit speed Every commit is a network round trip Commits are local and instant
Working offline Not possible — server required Fully possible until you push or pull
Disaster recovery Hard — restore from backups Easy — any local clone restores the project
Disk and bandwidth Small working copies Full history on every machine; heavy first clone
Concurrency order Merge before commit Commit before merge

The trade-off is clear: centralized systems are cheap and simple per developer but fragile and slow; distributed systems cost disk and a heavy first clone, and in return give speed, offline work, and safety.

7.4.4 Tools and technology in the market

The market splits along the same two lines. For centralized version control, open-source options are Subversion, CVS (Concurrent Versions System), Vesta, and OpenCVS; commercial options are AccuRev, Helix Core, IBM Rational ClearCase, and Team Foundation Server. For distributed version control, open-source options are Git, Bazaar, and Mercurial; commercial options include Visual Studio Team Services, Plastic SCM by Codice Software, and Code Co-op.

A note on the names: the distributed commercial list was hard to hear in the source, and the readable entries — Visual Studio Team Services (now Microsoft's Azure DevOps), Plastic SCM by Codice Software, and Code Co-op — are confirmed real products. The broader commercial landscape also includes Perforce and StarTeam on the centralized side, which the reference material lists alongside ClearCase and AccuRev.

Open source Commercial
Centralized Subversion, CVS, Vesta, OpenCVS AccuRev, Helix Core, IBM Rational ClearCase, Team Foundation Server
Distributed Git, Bazaar, Mercurial Visual Studio Team Services, Plastic SCM, Code Co-op

Real-world: this is the map used when organizations evaluate version control tooling. The centralized column still runs in many enterprises, but the distributed column — Git above all — is what most modern teams adopt.

Recap: Centralized version control keeps the history on one server: cheap, simple, but a single point of failure with slow remote commits and a hard requirement on connectivity. Distributed version control copies the full history onto every workstation: fast, offline-friendly, disaster-proof, at the cost of disk space and a heavy first clone. Git belongs to the distributed column, and it is the tool we turn to next.

7.5 Git and GitHub

Hook: People say "I use Git" and "I have a GitHub account" in the same breath, as if the two were one thing. They are not: Git is the version control system that runs on your machine, and GitHub is a website that hosts copies of your repositories so teams can collaborate. Knowing which part does what is the first step to using both well.

7.5.1 What Git is

Git is a popular source control system. First of all it is a version control system, and second, it supports the distributed way of working, which is why it becomes part of the DevOps toolchain. Importantly, it is fully open source: it is free and gives full access. Anyone can read its code, anyone can use it without paying, and any team can adopt it without licensing questions — which is one reason it spread so fast. On GitHub the story is similar: previously you could only create public repositories, but now even the creation of private repositories is available for free. A repository (repo for short) is the store where a project's files and their history live — on your machine it is the .git folder, and on GitHub it is the hosted copy the team shares.

7.5.2 Why use Git

  • It is really fast. It supports distributed working, so every command you execute runs on your local system, which is what makes it fast. There is no network round trip hidden inside git add or git commit.
  • You can work in a disconnected environment. You do not need a network to start working with Git. Your repository is maintained on your local system, so you can fully work disconnected from the internet. Commits, history, even branching all work on the train; only push and pull need the network.
  • It is powerful and easy at the same time. Powerful, because it has a lot of commands. Easy, because even when some command goes wrong, it gives you suggestions. If you run git commit before you have added anything, Git pops up in your command-line editor, or gives a suggestion in the desktop application: "I think you have forgotten to do this; first execute so and so and then do this." That intelligent way of working makes Git easy — the tool tells you what you forgot, instead of leaving you to guess.
  • You can work with branching. This is the main part, because branching is where Git supports the distributed way of working — and at the same time, branching is proof that Git can also support a centralized way of working. For a team that is newly moving into distributed working, opting for Git and GitHub is the best solution: they can work in a centralized way, just changing the commands and the way of working, and once they get matured they can start using the branching feature to make it distributed.
  • Pull requests. This is beyond the basics. The pull request is not directly part of Git; Git has to be collaborated with some remote system to activate this feature. It comes from the remote repository side — GitHub, or Bitbucket, will help create the pull request.

7.5.3 What GitHub adds

GitHub is a hosting service for Git. And it is more than a version control system: it is more than source control for your code. It supports managing issues, working with teams, and other features. You can have a scrum board or Kanban boards to visualize who is working on what and what progress is being made. You can track your issues, and you can get great visualization of the number of commits that have happened. All of this means GitHub provides other features, not only source control for your code. It is free, and there are paid options too, but the free tier covers the daily-need features, so anyone can start contributing and working with GitHub. The distinguishing idea is that GitHub is built around collaboration: the pull request, the review flow, the issue tracker, and the project boards are all team features layered on top of plain Git.

7.5.4 The Git–GitHub relationship

Even in distributed working, you need a remote server to coordinate collaboration among distributed teams, and you also have a local system. So in the Git and GitHub combination, Git becomes your local version control system and GitHub becomes your central server, where the work of all distributed teams is collaborated. Remember the earlier principle: the distributed model still designates one shared remote as the place where everyone's work meets — GitHub plays that role here. On the local side you can work either with Git Bash, the console, or with a desktop application: people who are not from a Linux background and do not prefer commands can work with Git Desktop. So at the local level the options are Git Bash or Git Desktop; on the GUI side you can look at GitHub Desktop or SourceTree. The tutorial session will mostly demo the console option.

7.5.5 Prerequisites and connecting your machine

The prerequisite to work with Git and GitHub is to create an account on GitHub, and you can sign up using your Gmail account. Git and GitHub support almost all platforms — Windows, Mac, and Linux.

To connect your local machine with GitHub and start working as a distributed version control system, you have two options:

  • HTTPS: sometimes when you clone, or the first time you push some changes to a remote repository, it will ask you for a username and password. Simple to set up, but the credential prompts keep recurring.
  • SSH key: you generate an SSH key and give that certificate only once. After that it is easier to work, because Git will not ask you a number of times for user id and password. The trade-off is a one-time setup: you generate a key pair, register the public half with GitHub, and from then on authentication is automatic.

7.5.6 GitHub main features

  • Code management: you have a remote repository for your code — that is certain, because you need the remote side for collaboration.
  • Pull requests: whenever you push code and would like to merge it into a particular branch — from a feature branch to the main branch, for example — you create a pull request. That is an announcement: "my code is done, I want it reviewed and then merged into the subsequent branch."
  • Issue management: you can create issues, name them, classify them as an enhancement or a bug, and manage the lifecycle of your maintenance tickets. An issue is a tracked conversation about a piece of work, and the lifecycle — open, assigned, in progress, closed — gives the team a visible picture of what remains.
  • CI/CD pipeline: GitHub can be integrated with any integration server — Jenkins (which is the syllabus tool), TeamCity, or anything else, and even CircleCI works — to create a CI/CD pipeline. GitHub Actions also has the capability to act as an integration server itself. The hosting site becomes the trigger: every push can start a build and a test run automatically.
  • Global search: you can do a global search across public repositories and clone any of them under your local system. To show Git and GitHub in a lab you do not need to write a code base from scratch — in fact, someone who has not worked in a real-time environment for years can still run a full lab. Search for a project in a language you are comfortable with, say Java, and you will get a thousand or more results. Clone the repository that is best suitable for you, and you can get your hands dirty immediately without writing code from scratch. The same habit works in industry: reading real, production-grade code from public repositories is one of the fastest ways to learn.

7.5.7 Student Questions and Answers

Q: Do I need GitHub Desktop if I already have Git installed? A: No. If you are comfortable with Git and have your account ready, that is fine — GitHub Desktop is not needed. The desktop application is an optional convenience for people who prefer a graphical interface; the version control engine underneath is the same Git either way.

Real-world: GitHub is where open-source projects live and where teams host private code, track issues, run boards, and wire CI/CD pipelines through Jenkins, TeamCity, CircleCI, or GitHub Actions itself. Global search plus clone is also a standard way to study real production code.

Recap: Git is the fast, open-source, distributed version control system on your machine; GitHub is the hosting service that supplies the remote side — pull requests, issues, boards, CI/CD hooks, and global search. The combination gives new teams a centralized-style start and room to grow into full distributed branching. Next we open the hood of Git itself: the three states a file can be in and the four areas where files live.

7.6 The Foundation of Git: States, Areas, and Snapshots

Hook: Where does a file "live" in Git, and how does it travel from your editor to the repository? Git answers with a tidy mental model: every file is always in one of three states, and the file moves between four areas as it travels. Once you see the map, the commands stop being magic — git add and git commit are just the two tickets that move a file along the line.

7.6.1 The three states of a file

Source code is nothing but a file where you write your code. In Git, your file is always in one of three states.

  • Modified: the content available on your local system has changed. The changes you made to your local file put the file into the modified state. Git knows the file differs from what it last recorded, but has not yet done anything with the difference.
  • Staged: every time you execute git add, you are staging that file, and the file is promoted to the stage state. Stage state means the file is ready to get committed into the repository, your version control system. Staging is the checkpoint where you decide, change by change, what belongs in the next commit.
  • Committed: once you run the commit command, the changes are committed to the local repository, and the file is promoted to the committed state. The change is now safe inside Git's history — it survives until the history itself is changed.

The three states form a one-way promotion for each round of work: modify, then stage, then commit. You cannot commit a change that has not been staged first.

7.6.2 The four areas where files live

Since you have three states, you have three areas in which your file resides. In the modified state, the file resides in your working directory on the local system. Once you add it, the file resides in the staging area. Once you commit it, the file gets promoted and resides in the .git repository — your local Git repository, under which it is committed. And after that there must be a fourth area.

The map of areas matches the states one to one, and each state is defined by the area it lives in: the working directory (your ordinary project folders, where you edit), the staging area (the holding pen for changes you have marked with git add), and the local repository (the .git folder that holds the committed history). The fourth area is the one students usually guess last — it is the destination of git push.

Worked example — one file through the three states: Take a small project with a single file, login.py. You edit the file and save it. Run git status and Git reports:

modified: login.py

The file is in the modified state — it lives in your working directory and differs from the last recorded version. Now run git add login.py. The file is staged: Git now reports it as "Changes to be committed", and the file lives in the staging area — a copy of the change is waiting there, safe from further edits to your working copy. Finally run git commit -m "fix login redirect". The change is committed: it now lives in the .git repository as part of the permanent history, and git status reports a clean tree. The whole trip is: edit → git add → staged → git commit → committed.

7.6.3 Student Questions and Answers

Q: You said three states, so what is the fourth area once you push the code? A: The remote repository on GitHub is the fourth area. Once you push the code, it goes and holds in the remote GitHub repository. So there are three areas on your local system — working directory, staging area, and .git repository — and the fourth one is on your remote GitHub repository. The push command is what moves a committed change from the third area into the fourth.

7.6.4 Snapshots and branches

Git works with the concept of snapshots. Whenever you execute a commit, the commit creates a snapshot, and that snapshot has a pointer that points to a particular snapshot, together with the author, the committer, and the commit message: who is the author, who is the committer who committed those changes, and the commit message. That information is stored with each snapshot. A branch is also a snapshot — more precisely, a branch is nothing but a snapshot that points to a particular commit.

Two ideas sit behind this model. First, Git does not store diffs as its primary record — each commit stores a complete snapshot of the project as it looked at that moment, plus a pointer to the snapshot that came before it. The history is a chain of snapshots: commit 3 points back to commit 2, which points back to commit 1. Second, a branch is a label that sits on a particular commit. In standard Git terminology, a branch is a movable pointer to a commit: as you add commits, the branch label moves forward with you. When you "create a branch", you are creating a new label at your current commit so that work can diverge from there. The professor's phrasing captures the same idea in snapshot terms — a branch is a snapshot that points to a particular commit — and the takeaway for the exam is identical: branches are lightweight pointers in history, not copies of files.

7.6.5 Basic Git commands

The basic commands are git config, init, clone, status, add, commit, branch, checkout, push, fetch, merge, pull, log, reset, and revert. Some behavior worth noting now: git checkout moves your pointer to a particular branch. If you run git branch and create a branch called feature A, Git will not point to that newly created branch by default — you have to run git checkout and provide the branch name to make sure Git points to this particular branch. So git checkout is also how you toggle between branches. You will have a demo of all these basic commands in the tutorial session.

Exam note: The three states, the four areas, and the snapshot model are the foundation of Git, and the command names above are the vocabulary of the tutorial experiments. If you learn one thing from this section, learn the map: edit (modified, working directory) → git add (staged, staging area) → git commit (committed, .git repository) → git push (remote repository on GitHub).

7.7 Working with Repositories: The Daily Git Workflow

Hook: What does a developer actually do on an ordinary working day? The answer is a short, fixed loop: get the project, change it, record the changes, and share them. Git's daily workflow — clone, modify, add, commit, pull, push — is the same six steps whether you are writing code or maintaining test scripts, which makes it the single most important routine to master.

7.7.1 Clone: bring the repository to your machine

Take a scenario where you have a project on GitHub — a repository, call it test or any name. You want that repository in your working directory on your local system. The first thing to do is clone it: git clone brings all the repository content into the working directory. That is the first job done — the project folder is now available locally.

Two details are worth noting. First, git clone gives you more than the current files — it downloads the full history along with them, which is why the very first clone of a large project is the heaviest network operation in the whole workflow. Second, the clone connects the local copy to the remote automatically: Git remembers where the repository came from, so later pushes and pulls know which server to talk to.

7.7.2 Modify, stage, and commit

Once the project is available, your daily job is to contribute to it. Say you have added a file, made some modification, added a configuration file, or put new resources into your working directory. Whatever changes you did are modified changes, because they now exist only on your local system. Before you commit, you are supposed to add them: git add makes sure those changes are now staged, meaning the changes are under the staging area. Then git commit commits those changes into the .git repository available on the local system. Apart from clone, every command you have executed so far runs on your local system, so they are really fast — you do not need great bandwidth and you do not need an internet connection, because you are working locally.

7.7.3 Push: share your changes

Once the changes are done and the team member is ready to push that code — the changes are complete and should reside in the GitHub repository so that other team members can access them — you run git push, which pushes the code changes to the GitHub repository. Until the push happens, your commits exist only on your machine: they are safe, but invisible to everyone else. The push is the moment your private work becomes shared work.

7.7.4 Fetch vs pull: staying in line with the remote

Now consider the conflict scenario. You are pushing changes, but there is a possibility that another team member working on the same project has already pushed some code changes to the GitHub repository. Are those changes available in your working directory? Definitely not. At that point Git tells you there is a conflict: the remote repository on which you are pushing is not in line with your local repository, because somebody made modifications to it. That message helps you understand that you need to make your local repository in line with the changes that happened on the remote repository. For that you run git fetch, or you can run git pull. Fetch brings the remote changes into the .git repository, but those changes are not yet reflected in the working directory — they are in the .git repo only. You still need to run git merge so those changes become available in your local working directory. Git pull is nothing but fetch plus merge: if you run git pull, it makes the changes available in the working directory and in the .git repository at the same time. Then you can push again.

The distinction matters because the two commands answer different questions. git fetch says: "download what the remote has, but do not touch my working files" — a safe, read-only step that lets you look at other people's changes before deciding to take them. git pull says: "download and integrate right now" — it runs the merge for you. When you are told your push was rejected because the remote moved on, the cure is: refresh from the remote, resolve any differences locally, and push again.

7.7.5 Student Questions and Answers

Q: A student suggested treating fetch and merge as separate steps, so what is the difference between git fetch and git pull? A: Git pull is fetch plus merge. Fetch brings the remote changes into your local .git repository, but those changes are not reflected in the working directory, so you still need a merge. Git pull performs both jobs in one command, so the changes land in the working directory and the .git repository together. The student's instinct was right that two jobs exist — fetch and merge — and the correction is only that git pull bundles them; git fetch alone leaves you with a merge still to do.

7.7.6 The daily loop

This is the workflow developers and testers run on a daily basis while working with Git and GitHub: clone the project, modify files, add the changes, commit them to the local repository, pull or fetch plus merge to stay in line with the remote, and push when the work should be shared. It is the generic flow that everyone follows every day — a developer writing code or a tester writing test scripts and maintaining them in a GitHub repository.

Worked example — one complete daily loop: A tester joins a project and works through the full loop with a test script.

  1. git clone https://github.com/team/project.git — the project folder appears locally, with full history.
  2. Edit test_login.py, adding two new test cases — the file is now modified.
  3. git add test_login.py — the change is staged.
  4. git commit -m "add login test cases" — the change is committed to the local .git repository.
  5. git pull — the tester's local line is refreshed with the latest remote changes (fetch plus merge in one command), because a teammate pushed meanwhile.
  6. git push — the commit now travels to the GitHub repository, where the rest of the team can see it.

Every step except clone and the final push runs locally and instantly; only steps 1, 5, and 6 touch the network. The same six steps repeat every working day, which is why practicing them by hand in the tutorial session matters more than memorizing anything else about Git.

Exam note: The daily loop is clone, modify, add, commit, pull (or fetch plus merge), push. The distinction the professor emphasizes — and a likely exam question — is why git pull exists when git fetch and git merge exist: pull is simply fetch plus merge, and fetch alone leaves changes only in the .git repository, invisible in your working directory.

7.8 GitHub Special Files and Repository Features

Hook: Open any serious repository on GitHub and you will find the same small set of files near the top — a README, a license, a changelog, a code of conduct — followed by a familiar set of tabs for issues, pull requests, insights, and settings. These are the conventions that let a stranger understand a project in minutes and a team run it for years. Knowing what each one is for is part of being a working GitHub citizen.

7.8.1 Special files in a repository

When somebody works with GitHub, they come across some special files. The first is the README file. README is a file that GitHub knows by name and renders automatically on the landing page: once you add the README file to your repository, whatever content is in it is automatically available on the first page of your repository. In the README you generally write about your project repository — how to work with it, the basic commands, the prerequisites for the project, and what the project is meant for. All this information is needed on the landing page, and README is typically written in Markdown, which is why the extension is readme.md. Markdown is a lightweight way to format text — headings, lists, code blocks — so the README reads as clean web content without the author writing HTML.

The other special files are:

  • License: it makes sure who can access the file and what licenses are needed to work with the project. The license states the legal terms under which others may use, copy, modify, and redistribute the code — open-source projects pick one of the standard licenses (MIT, Apache, GPL), and the license file tells contributors and users which one applies.
  • Changelog: the record of changes to the project. It is a dated list of what changed in each version — new features, fixed bugs, breaking changes — so users can see at a glance what a release contains.
  • Code of conduct: the rules and regulations to start collaborating on the project. It sets expectations for how contributors treat each other, which matters most for open-source projects with contributors from many organizations and backgrounds.

README is the most popular one — everybody uses it — and apart from that, license, changelog, and code of conduct are the ones most industries use.

7.8.2 Repository features

Beyond the special files, repositories carry a set of features:

  • Topics: you can tag your repository with topics, for example java. If someone does a global search and types java, your repository will also be seen in the results. Topics make the global search efficient — instead of searching for "java project with a build script and a testing framework", you browse the java topic and find repositories that already declared themselves.
  • Projects: you can execute project management for your particular project by creating a project board — a Kanban board or a Scrum board. That helps manage project activity: who is working on what, whether any alteration is needed in resource planning or capacity planning, and moving one particular task to another person. The board turns the backlog into a visual flow of cards moving from "to do" to "done".
  • Issues: you can create issues, mark them as a bug, track progress, and manage the issue management track to request improvements to the project. Issues carry labels, assignees, and conversation threads, so a bug report becomes a tracked ticket with an owner.
  • Pull requests: you announce the changes you want to make available for review, and then merge them into the main branch or any other subsequent branch.
  • Insights: there is a tab to get insight on the repository. You can see the frequency of commits happening to the repository, which merges happened, everything that has been modified or changed in the repository — all of it visualized. Insights answer questions like "is the team still active?" and "which files change most often?"
  • Settings: this is the great one. You can add collaborators, remove collaborators, delete your repository if you no longer want it, and connect your GitHub account with a cloud platform such as AWS — if you want to push code to an S3 bucket, some settings are needed to get it accessible, and that is done from the settings tab. The collaborator management is what people access most in settings, along with integrating GitHub with other tools and applications.

7.8.3 Configuration files and merges

A note about configuration files: if there are any configuration files in the project, you need to handle them specially, because they should be avoided from the merge. You have to set up the repository in that way.

Why? A configuration file often holds machine-specific or environment-specific values — a local database password, a personal API key, a developer's favorite editor settings. If every developer commits their own version, merges constantly collide on that one file, and worse, secrets can leak into the shared history. The standard mechanisms for keeping such files out of merges are: (1) a .gitignore file that excludes the file from version control entirely, so each developer keeps their own untracked copy; (2) committing a template like config.example.yml and telling developers to copy it to their local name; and (3) for files that must stay in the repository, a Git attribute rule that always keeps the local version when merging. The professor's instruction — "you have to set up the repository in that way" — points at exactly this configuration work: the repository is prepared so that merges never touch the personal settings.

Real-world: industry practice is to ship every repository with a README at minimum, and license, changelog, and code of conduct for most projects. Topics, project boards, issues, insights, and settings are the everyday surface of GitHub used by engineering teams, including the connection to cloud storage like AWS S3.

Recap: Every well-run repository carries the same special files — README (auto-rendered on the landing page), license, changelog, and code of conduct — and exposes the same feature set: topics, project boards, issues, pull requests, insights, and settings. Configuration files are handled specially so that personal, machine-specific settings never enter merges. Next we look at what turns this into a team workflow: branching and the two flows built on it.

7.9 Branching and Workflows: Git Flow vs GitHub Flow

Hook: How can ten developers work on the same codebase at the same time without constantly breaking each other's work? The answer is branching: instead of everyone pushing into one shared line, each piece of work gets its own line, called a branch, and the lines are merged back only when the work is ready. Branching is the heart of GitHub — and the two flows built around it, Git flow and GitHub flow, decide how many branches your team keeps alive at once.

7.9.1 Branching basics and the centralized workflow

When it comes to distributed version control, Git is the system most organizations opt for. Its best beauty is that it lets you work either in a centralized workflow or in a feature workflow. The centralized workflow is nothing but support for your distributed version control system in a centralized style: even though you are working in a distributed way, it gives you a feel of working as centralized, and that helps your team adopt the new tools and technology. They still feel they are working in a centralized way, and once they get comfortable, you move to creating feature branches and the feature workflow.

Branching is the main heart of GitHub. The main branch holds the latest code, the latest version of your software. When your team wants to perform some changes, they can create a branch — call it a feature branch — and commits happen on that particular branch. Once the commits are done and the code changes are matured, the team would like to merge it into the main branch, so they raise a pull request.

The key idea of the centralized workflow: it uses the distributed tool with centralized habits. Everyone pushes directly to a single shared branch — the master branch — so the team gets the safety and history of Git without learning the full branching model. The feature workflow comes later, once the team is comfortable: each feature gets its own branch, and nothing touches the main line without review.

7.9.2 The pull request flow

A pull request is an announcement: "code base is ready, code changes are made, kindly review it so that it can merge to the main line, your main branch." You push to a branch, and then your review members are able to review the changes. If they feel the changes are up to date, they approve. If there are certain changes that need to be done, they reject the pull request, and subsequent comments are provided to the particular team member. Those changes are accommodated, and once the pull request is approved by that certain set of people, it gets merged into your main line. That is where the distributed way of working starts.

Even if you do not create any branches — if you are working in a centralized way — the logic holds: you just have a single repository with a single branch, the master branch. Whenever your code gets pushed, that is nothing but a merge, and before it merges into the master branch there will be a pull request, to make sure the code has been reviewed. Only then it resides in and merges into the master branch.

So the pull request is the gatekeeper of the main line. It bundles three jobs into one ceremony: the code is reviewed by human eyes, discussions and fixes happen in the open, and the merge into the main branch is recorded for history.

7.9.3 Git flow: many branches for multi-version products

For the distributed way of working, you basically have two flows: Git flow and GitHub flow. Git flow is more complex than GitHub flow. In Git flow you have many branches, and it is mostly suitable for those applications that have different versions working in the production environment. That means you have an application 1.1 available for customer X and an application 1.2 available for customer Y — you have to manage a different version of a product for different customers. In that case it is best to opt for Git flow. The branch structure is:

  • Hotfix branches: when hot fixes come in from the customer and you just want to make those changes, with the awareness that this patch will resolve those concerns, you use a hotfix branch. The hotfix is cut from the release in production, fixed, and merged back — without dragging along half-finished features.
  • Release branches: the releases of the product. A release branch holds the code that is being prepared to ship, so that new feature work does not destabilize the version heading to production.
  • Development branch: under the development branch you can create feature branches — feature A, feature B, feature C. The development branch is the integration line where finished features meet before they are promoted toward release.
  • Feature branches: on feature A one team is working, on feature B another team, on feature C a third team. Each team commits freely on its own line, isolated from the others.

The merge path is fixed: the feature branches get merged to the development branch by merging the changes into the develop branch. From the development branch, the code gets merged to the release branch, and from the release branch it gets merged to the master branch.

Worked example — a change traveling through Git flow: The team ships version 1.1 to customer X and version 1.2 to customer Y, so it runs Git flow. A developer starts a new feature, "search by date".

  1. Create the feature branch from develop: git checkout develop, then git branch feature/search-by-date.
  2. Commits happen on the feature branch — the developer's work is isolated; the develop line keeps running and releasing.
  3. The feature matures; the team raises a pull request and the reviewer approves.
  4. The feature branch is merged into the develop branch.
  5. When several features are ready, develop is merged into a release branch for customer Y's 1.2.
  6. When the release is validated, the release branch is merged into master — the code that customer Y receives.

The path is always the same: feature → develop → release → master. Hotfixes take a shortcut: they are cut from the release in production and merged back into both master and develop, because the fix must land in the live version and in future work at the same time.

7.9.4 GitHub flow: one branch for simple products

GitHub flow is pretty simple: you do not have these multiple branches. GitHub flow combines the main line and the release branch into a single master branch. The main line and the master branch both are merged — this is a single branch now, which is your main line, and that becomes your master branch. The hotfix branch is treated just like a feature branch. Under that you definitely have feature A, feature B, feature C — multiple feature branches — but you do not have a release branch or a develop branch, just a master branch. GitHub flow is suitable for an application where you are not maintaining or managing multiple versions of your software.

Worked example — a change traveling through GitHub flow: A single product ships one version at a time, so the team keeps one master branch and nothing else permanent.

  1. Create a feature branch from master: git checkout master, then git branch feature/payment-tab.
  2. Commits happen on the feature branch.
  3. The developer pushes the branch and raises a pull request into master.
  4. The reviewers approve; the branch is merged into master, and the code is deployed.

A hotfix is treated exactly the same way — it is just another feature branch cut from master and merged through a pull request. No develop branch, no release branch, no promotion path: every change flows feature → master.

Dimension Git flow GitHub flow
Permanent branches master, develop, release branches Only master
Feature branches Cut from develop, merged into develop Cut from master, merged into master
Hotfix handling Dedicated hotfix branch, merged to master and develop Treated like any feature branch
Release handling Separate release branch per version Release comes straight off master
Best for Multi-version products (1.1 for customer X, 1.2 for customer Y) Single-version products without version maintenance

Pick Git flow when you must keep several versions of a product alive for different customers; pick GitHub flow when one version is always the latest and you want the simplest possible pipeline.

7.9.5 Know the logic, not just the commands

This is where people get lagged: people know Git commands because they have a cheat sheet. The cheat sheet sits on their desktop — git add, git status, git log, git push, git pull, git revert, git reset — and they execute these daily. But if somebody asks you the logic — why git fetch, why not git pull, why not git reset, why only git revert — you should be able to answer. Focus on the concept right now; the commands follow from it.

Pitfall — the cheat-sheet trap: Memorized commands without the underlying logic break down the moment the situation changes slightly. A developer who can recite git pull by heart but cannot explain that it is fetch plus merge will not know what went wrong when the pull refuses to complete. The same applies to git revert versus git reset: knowing when each exists is the examinable skill, not typing them.

Exam note: Expect to reason about why one command exists rather than another — the fetch vs pull logic and the revert vs reset logic are exactly the kind of distinction this session emphasizes. Likewise, be ready to explain which flow a product needs: Git flow's fixed promotion path (feature → develop → release → master) for multi-version products, or GitHub flow's single master line for simple, single-version products.

Real-world: Git flow is the workflow of choice for products that ship multiple versions to different customers (application 1.1 for customer X, 1.2 for customer Y), while GitHub flow with its single master branch suits products without multi-version maintenance — and many modern teams run a GitHub-flow-like model with continuous deployment straight from master.

7.10 Merging, Merge Conflicts, and Undoing Work

Hook: Two realities of teamwork that every developer eventually meets: merges that refuse to complete because two people edited the same lines, and commits you wish had never happened. Git answers the first with conflict markers and a manual resolution step, and the second with a family of undo commands — git revert and git reset — each with its own appetite for destruction. Knowing which undo to reach for is the difference between a five-minute fix and a lost afternoon.

7.10.1 When merge conflicts occur

Whenever you merge, there can be conflicts. Conflicts usually occur when multiple people are editing on the same line, or editing an already deleted file — you are doing something to a file that is not there anymore — or editing the same file that was already updated. When conflicts happen, the merge will fail, and you get an error that the branches are not in line: there is a conflict that needs to be resolved. To solve a merge conflict there is no automation — you cannot deal with merge-conflict resolution automatically. You need manual intervention to make sure which version is up to date, take that call, and then perform the merge.

The three classic triggers are worth naming precisely: (1) two people edit the same line of the same file — Git cannot guess which version should win; (2) someone edits a file that another developer deleted — Git cannot both keep the edit and honor the deletion; (3) someone edits a file that has already been updated on the other branch — the versions have genuinely diverged. In every case, resolving the conflict is a human decision: the tool reports the disagreement, and a person decides which version is correct.

7.10.2 How Git and GitHub surface conflicts

Git and GitHub help smooth over this process. They let you know if there are any merge conflicts: the merge automatically fails if any conflicts exist, and then they tell you what the conflict is, where the conflict is, which is the latest update that happened, and what your changes are. Then you can manually intervene. There is a demo of this, but in this session there is no time to run it — resolving conflicts will be seen in the tutorial session.

The value of the reporting is that the merge never silently picks a wrong version. Git stops at the first disagreement, marks the conflicting regions inside the file with special markers, and lists the files that need attention — so the developer opens the file, reads both versions, keeps the right lines, removes the markers, and commits the resolution.

7.10.3 Revert: the safe undo

Git revert undoes a single commit. It is a safe way to undo your work. Say you have committed, and you know something went wrong and you want to revert your commit. You run git revert, which creates one more commit to undo the change. The snapshot has changed, and the pointer in your snapshot gets changed: logically, the new commit has a pointer pointing to the previous commit, undoing your last commit. So git revert is a new commit that undoes a single commit.

Why is this the "safe" undo? Because history is never rewritten: the bad commit stays in the log, and a new commit appears on top of it that cancels its effect. Every step is recorded, and the team's shared history stays intact — which matters when other people may have built work on top of the commit you want to undo.

7.10.4 Reset: soft, mixed, and hard

Git reset gives three options — three invocations: hard, mixed, or soft.

  • Soft: soft is similar to revert. Only the pointer is getting changed — under the staging area, your commit pointers are getting changed with git reset soft. It is just the same as a revert. The standard behavior matches the professor's picture: git reset --soft moves the branch pointer back to an earlier commit while leaving your changes staged, so you can recommit them differently. The one difference from git revert to note: revert records the undo as a new commit, while soft reset moves the pointer and keeps the changes ready in the staging area.
  • Mixed: mixed means you are doing an undo, and the changes get removed from your .git as well as from the staging. The things you added into your staging area get removed, and they will not be in your .git repository either. In standard terms, git reset with no flag (mixed) moves the pointer back and clears the staging area, while the working files keep the changes — the undo is half done, with the changes still visible in your working directory.
  • Hard: hard takes everything back to the clone state, the baseline of your local working directory. Until that, everything is removed. This is why people say it is not a good option to opt for git reset hard. But sometimes, when something does not work, employees tend to run git reset hard to go back to the clone state of the project. For that matter people create a local folder where they mention the changes they did, and then they rework — because if some issues come up, they can opt for git reset hard to undo everything and stand on the baseline of the code in the local repository.

Worked example — the undo ladder on a small history: Your local history is three commits: C1 → C2 → C3, with C3 the latest. Something in C3 is wrong.

  • git revert C3 creates a new commit, C4, whose snapshot is C3's snapshot with the bad change removed. History reads C1 → C2 → C3 → C4, and the team sees a clear, documented undo. Safest option.
  • git reset --soft C2 moves your branch pointer back to C2. C3's changes stay in the staging area, ready to be recommitted. No new commit is made.
  • git reset --mixed C2 (plain git reset C2) moves the pointer back to C2 and empties the staging area. The changes from C3 still sit in your working files, unstaged — you can rebuild the commit differently.
  • git reset --hard C2 moves the pointer to C2, empties the staging area, and overwrites the working files to match C2 — C3's changes are gone from the working copy entirely. If C3 was never pushed anywhere else, it is effectively destroyed locally.

The sense-check: each rung of the ladder discards more. Revert discards nothing — it adds a record. Soft keeps your changes staged. Mixed keeps them in the working folder. Hard throws everything back to the baseline, which is why the professor's safety ranking is: the safest way is git revert; if needed, you can work with git reset mixed; but never, ever try git reset hard.

7.10.5 Student Questions and Answers

Q: Could a small case for rebase be shown in the session? A: Noted — the request will be conveyed so that a small case for rebase (and restore) can be shown, most likely in the tutorial session. For now, keep the distinction from this section in mind: rebase is another way of moving commits onto a newer base, and like reset, it rewrites history — which is why the safe, shareable undo stays git revert.

Exam note: Merge conflict resolution and the revert vs reset logic are covered hands-on in the tutorial session, and the reasoning is examinable: conflicts happen on same-line edits, deleted files, or already-updated files and always need manual resolution; git revert creates a new commit that undoes a single commit; git reset soft, mixed, and hard discard progressively more; and the safety ranking runs from revert (safest) through reset mixed to reset hard (never).

Real-world: teams protect their shared main line by never force-rewriting pushed history — git revert is the standard tool for undoing public commits, while reset-based undos are reserved for local, unpublished work.

7.11 Git Tagging

Hook: After a release, how does a team point back to exactly the code that went out — weeks or months later? Tags. A tag is a named bookmark fixed to one commit in history, and it answers precisely that: the code that shipped as v1.1.1 is the commit the tag v1.1.1 points to, forever.

7.11.1 What a tag is

Tagging is the command to tag a reference point for a specific point in your Git history. If you want to mark a version for a particular release, you mark it, for example, as v1.1.1. That tag creates the baseline, and the tag becomes the baseline for the upcoming changes. The version number is a human label — v1.1.1, v2.0, release-2024-01 — and the tag binds that label to a concrete commit, so "version 1.1.1" always means one specific snapshot of the code, no matter how much history accumulates afterwards.

A tag is useful as a baseline in both directions: looking back, you can restore or inspect the exact released code; looking forward, any new work is understood as "built on top of the v1.1.1 baseline".

7.11.2 Tags vs branches

A tag is like a branch, but it does not change. Once you give a tag, there will be no change in that branch. You have to now create a new branch, make the changes, then push to the master branch, and give the tag again. A tag means there are no changes and no commits in that particular tag. Unlike branches, tags, after being created, have no further history of commits.

The mental model is: a branch is a pointer that moves — it advances with every new commit, which is exactly what makes it useful for ongoing work. A tag is a pointer that stays put — once created, it never advances, which is exactly what makes it useful for marking history. If the team wants to continue working after a release, they do not commit "onto the tag"; they create a new branch from it, or keep working on their normal branch, and when the next release is ready they tag that commit with the next version number.

Branch Tag
What it points to A commit A commit
Does it move? Yes — advances with each commit No — frozen at creation
Typical use Ongoing development Marking releases and baselines (v1.1.1)
History after creation Keeps growing No further commits

7.11.3 Common tag operations

The common operations with tags: you can create a tag, list the tags that are there, delete a tag, and share a tag — sharing a tag is a way to share your latest code base of the project.

Worked example — tagging a release: The team finishes version 1.1.1 of the product on the master branch.

  1. git tag v1.1.1 — the current commit is marked with the release name. The tag now names the baseline for this release.
  2. git tag — lists all tags; v1.1.1 appears alongside the earlier ones.
  3. Development continues: new commits land on master, and the branch pointer moves forward — the tag does not.
  4. A bug report arrives for v1.1.1. The team checks out the tagged commit and can rebuild the exact released code to investigate.
  5. When version 1.1.2 ships, the team tags that new commit: git tag v1.1.2.
  6. Sharing: the tag travels with the repository — when the team pushes the code base, the tags go with it, so every member and the CI server share the same release names.

The sense-check: the tag stayed at the v1.1.1 commit through every later change, so the release baseline never drifted.

Real-world: version tags like v1.1.1 are how released code bases are marked in industry, giving every release a fixed reference point that the team can return to — and release pipelines themselves are often triggered by the creation of a release tag.

Recap: A tag is a frozen pointer that marks a reference point in Git history — typically a release baseline like v1.1.1. Unlike branches, tags never receive further commits; new work continues on a branch and gets its own tag at the next release. Create, list, delete, and share are the four everyday tag operations.

7.12 Clean Code Practices

Hook: Why does clean code belong in a lecture about version control? Because Git preserves whatever you write — every line you commit becomes part of a permanent, shareable record that your whole team reads. Code is written once and read many times, by many people, over years. Naming and structure are not aesthetics; they are how a code base stays understandable after the original author has moved on.

7.12.1 Naming and keeping code simple

These are common practices most developers already know, and they matter because Git preserves whatever you write. Follow standard naming conventions: do not give int i or int j. Rather, give the variable a name that says what it is for — int variable1 for some purpose, or better, a name describing that purpose. The purpose of that particular variable has to be given in the naming convention. The same applies to functions: do not create function f1; if it is written to perform add functionality, name it add. Proper naming standards should be followed.

The principle is that the name carries the meaning. A variable called i in a loop is fine while the loop is three lines long, but the same i buried in a long method tells the reader nothing about what it counts. A descriptive name — studentCount, retryAttempts, invoiceTotal — turns every use of the variable into a piece of documentation. The same logic holds for functions: f1() hides its job, add() announces it.

Keep it simple: the simpler it is, the better, because you can reduce the complexity. If someone new has joined your team, that person will be in a good position to understand the code if it is smaller in size. Be aware of the 40-lines-of-code rule: a function should not have more than 40 lines of code. If the functionality cannot be completed within 40 lines, call a new function to execute the same — but do not extend it beyond 40 lines. Keeping it simpler, modular, and smaller makes it easier to accommodate new changes and reduces complexity.

The 40-line rule is a discipline, not a law: when a function threatens to grow past the limit, that is a signal that it is trying to do more than one job — split it. Smaller functions are easier to read, easier to test, and easier for a new teammate to change without breaking something.

7.12.2 Functions and arguments

Keep functions small: each function should do one thing. Use descriptive function names. Prefer fewer arguments: if you are calling a function, the arguments passed should be fewer — do not pass arguments like nine, ten, or eleven. Try to reduce the number of arguments passing through the functions.

Two signals tell you a function needs restructuring: a long body, and a long parameter list. A function that does one thing has one reason to change; a function that does several things must be changed carefully whenever any one of them changes. Likewise, a function called with nine or ten arguments forces the caller to remember the order and meaning of each — the better design is to bundle related values together or split the responsibility so fewer values need to travel.

7.12.3 Consistency, comments, and readability

Be consistent: if you do something a certain way, do all similar things in the same way. Use self-explanatory variables, following the naming conventions, and provide comments in a standard way, stating for what purpose this particular code line has been written. Give a single line of comment; do not write a history in the comments. Choose descriptive and unambiguous names. Always try to explain yourself in the code with proper comments. Declare variables close to their use. Keep lines short. The code should be readable, fast, generic, and reusable — keep it modular so you can reuse the code, maintain it, and accommodate new changes easily.

Each rule in this list protects a specific reader. Consistency means the team develops one style, so nothing surprises the next person. Self-explanatory variable names plus a single-line comment per tricky line explain why without burying the code in prose — a comment history is redundant, because Git already keeps the full history of every line. Declaring variables close to their use and keeping lines short both shrink the window a reader must hold in memory at once.

Worked example — renaming for meaning: Before — a fragment that records how many students passed:

int i = 0;
for (int j = 0; j < grades.length; j++) {
    if (grades[j] >= 40) {
        i++;
    }
}
System.out.println(i);

Step 1 — replace the letter names with purposeful names. The professor's minimal fix renames i to variable1, but the better fix names the purpose directly:

int passedCount = 0;
for (int student = 0; student < grades.length; student++) {
    if (grades[student] >= 40) {
        passedCount++;
    }
}
System.out.println(passedCount);

Step 2 — apply the same rule to functions. A function written to perform addition is not f1(); it is add():

int f1(int a, int b) {   // before
    return a + b;
}

int add(int a, int b) {  // after
    return a + b;
}

Step 3 — keep functions under the 40-line rule. If a function's logic outgrows 40 lines, extract a helper function for the subtask instead of extending the body. The sense-check: every name now states its purpose, and a new team member can read the code without a translator.

Real-world: clean code practices are the everyday standard of professional development — code review culture, linters, and team style guides all exist to enforce exactly the naming, small-function, and consistency rules above, and the code that survives in a repository is the code people can still understand next year.

Recap: Clean code is a version control concern because Git preserves everything you commit. Name variables and functions by purpose (not i or f1), keep functions small and under 40 lines with few arguments, and stay consistent with comments that explain why — the result is code that is readable, modular, and easy to change.

Exam Guidance Summary

Quiz structure

Four quizzes are scheduled for the course, each worth five marks, giving twenty marks in total. Only the best two quizzes count, and those two become your ten quiz marks. So even if you miss one quiz, it does not matter — make sure to attend all the other three quizzes to score well.

Q: Can the deadline for quiz one be extended or revoked? A: That is not possible under the operating constraints. There are four quizzes of five marks each — twenty marks in total — and only the best two are considered, which become your ten marks out of ten. Missing this quiz does not matter; attend the other three quizzes and score well.

Hands-on preparation

Exam note: the tutorial session, held after the eighth contact session, is where you will have the lab experiments for executing the Git commands, so attend it and be ready with your setup. The virtual-lab platform (Platify) also carries tutorials under the resources that you can execute to practice these Git commands.

Exam note: the concepts emphasized in this session are the three states of a file, the four areas, snapshots, the daily workflow, fetch vs pull, revert vs reset, merge conflicts, tags, and the two branching flows. The point of the session is the logic behind the commands — why fetch and not only pull, why revert and not always reset — not memorizing a cheat sheet.

Setup and study advice

To prepare: download Git — all the instructions are on the Git official site — and go with Git Bash if you are comfortable with the console, or a desktop application if you prefer a user interface. Create your GitHub account: you can use your personal Gmail id, or, preferably, the institute's email account, because that will help you in your assignment as well. Be proactive during the tutorial: work along while the facilitator is doing it, and that will help you identify any errors or issues you face, which you can immediately ask about.

Your first mid-semester exam is coming, so prepare well. The assignment will be released after the mid-semester, so it does not disturb you during your examination; by then you will have had two tutorial sessions, on GitHub and on Jenkins, which will help you execute the assignment.

Exam note: The ten quiz marks come from the best two of four quizzes; the tutorial after the eighth contact session is where the Git lab experiments happen, and the Platify virtual lab carries practice tutorials. Study the logic, not the cheat sheet: three states, four areas, snapshots, the daily workflow, fetch vs pull, revert vs reset, merge conflicts, tags, and the two branching flows.

Key Industry Applications

Cloud as the DevOps accelerator

Real-world: the three cloud service models appear everywhere — web-based email, Google Apps, Cisco WebEx, and Office 365 are SaaS, where the vendor handles licensing; AWS EC2 is the textbook IaaS case; PaaS sits between them as the platform you order and push applications onto.

Real-world: the Janitor Monkey pattern — automatically shutting down unused virtual machines to stop pay-per-use charges — is a genuine cost-control practice for organizations running thousands of cloud instances. The same cleanup discipline now ships inside the big clouds themselves, so the pattern has become standard cloud hygiene rather than a niche tool.

Version control in industry

Real-world: Git is the distributed version control system that most organizations opt for, with GitHub and Bitbucket as the remote hosting side; Git Bash, GitHub Desktop, and SourceTree are the common clients.

Real-world: the market map spans centralized systems — Subversion, CVS, Vesta, OpenCVS on the open-source side; AccuRev, Helix Core, IBM Rational ClearCase, Team Foundation Server commercially — and distributed systems — Git, Bazaar, Mercurial on the open-source side; Visual Studio Team Services, Plastic SCM, Code Co-op commercially.

Real-world: GitHub's project boards (Scrum and Kanban), issue tracking, insights, topics, and global search are used daily by engineering teams, and the settings tab is where teams add collaborators and connect repositories to cloud platforms such as AWS S3.

Real-world: CI/CD pipelines are wired by integrating GitHub with integration servers — Jenkins (the syllabus tool), TeamCity, or CircleCI — and GitHub Actions can serve as an integration server on its own. Every push can trigger a build, unit tests, and Selenium automation, which is the continuous integration step the course agenda builds toward.

Real-world: Git flow is the workflow of choice for products that ship multiple versions to different customers (application 1.1 for customer X, 1.2 for customer Y), while GitHub flow with its single master branch suits products without multi-version maintenance.

Real-world: most industry repositories ship the special files — README as the landing-page document, plus license, changelog, and code of conduct — and use tags such as v1.1.1 to fix release baselines in history.

ITD Lecture 7 notes · Git, GitHub, and Version Control

Introduction to Devops· postgraduate· 2026-08-14

Sections Breakdown

17.1 Cloud as a Catalyst for DevOps

The NIST essential characteristics of cloud computing and the three ways the cloud accelerates DevOps: simple environment creation and switching, easy VM creation with pay-per-use cleanup, and on-demand database storage.

27.2 Cloud Service Models: SaaS, PaaS, and IaaS

The spectrum of control across the three cloud service models — what you get and what you still manage — plus serverless computing as the fourth offering.

37.3 Version Control Systems: History and Generations

What a version control system does, why it matters, and the three generations from file locking (RCS, SCCS) to centralized SVN and distributed Git.

47.4 Centralized vs Distributed Version Control

Where history lives in each model, the merge-before-commit versus commit-before-merge orders, the trade-offs, and the tool market on both sides.

57.5 Git and GitHub

What Git is, why teams use it, what GitHub adds, how the two combine in distributed working, connection options, and GitHub main features.

67.6 The Foundation of Git: States, Areas, and Snapshots

The three states of a file, the four areas, the snapshot model, branches as pointers, and the basic Git command set.

77.7 Working with Repositories: The Daily Git Workflow

The daily loop of clone, modify, add, commit, pull, push, and the fetch versus pull distinction.

87.8 GitHub Special Files and Repository Features

README, license, changelog, and code of conduct, plus topics, boards, issues, pull requests, insights, settings, and keeping configuration files out of merges.

97.9 Branching and Workflows: Git Flow vs GitHub Flow

Branching basics, the pull request as gatekeeper of the main line, and when to choose Git flow promotion over GitHub flow single master.

107.10 Merging, Merge Conflicts, and Undoing Work

When conflicts occur and how Git surfaces them, plus the undo ladder from git revert through reset soft, mixed, and hard.

117.11 Git Tagging

Tags as frozen reference points for releases, tags versus branches, and the everyday tag operations.

127.12 Clean Code Practices

Naming by purpose, the 40-lines-of-code rule, few arguments, and consistent comments — the code Git preserves forever.

13Exam Guidance Summary

Quiz structure, hands-on preparation for the Git tutorial session, and setup and study advice.

14Key Industry Applications

Where the cloud models, version control tools, GitHub features, and CI/CD integrations appear in industry.

Postgraduate students of software engineering and delivery

Exam Revision Notes

Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.

Cloud as a Catalyst for DevOps

Must-know: The five NIST characteristics of cloud computing and the three ways the cloud fastens DevOps: simple environment creation/switching, easy VM creation with pay-per-use cleanup, and on-demand database storage.

⚠️ Top pitfall: Leaving unused VMs running: with pay-per-use you pay for every running instance, so idle VMs must be shut down (automated by tools like Janitor Monkey) or the bill grows silently.

Self-check: Which NIST characteristic forces pay-per-use, and why does it create the need for VM cleanup automation?

Connects to: Section 7.2

Cloud Service Models: SaaS, PaaS, and IaaS

Must-know: The spectrum of control across SaaS, PaaS, and IaaS: SaaS = least control (use the provider's app), PaaS = deploy your app onto a managed platform, IaaS = provision and manage VMs, storage, and networking yourself. SaaS is the most restricted service model.

⚠️ Top pitfall: Confusing which model gives which control: in PaaS the consumer still does not control network, servers, OS, or storage — only the deployed applications and hosting configuration. Only IaaS hands over OS, storage, and networking choices.

Self-check: Which of the three models is the most restricted, and why?

Connects to: Section 7.1

Version Control Systems: History and Generations

Must-know: The three generations of version control separated by networking and concurrency: first generation locks one file at a time (RCS, SCCS), second generation centralizes with merge before commit (SVN), third generation distributes with commit before merge (Git, Bazaar, Mercurial).

⚠️ Top pitfall: Confusing the concurrency models: generation two merges before commit (SVN style), while generation three commits first and merges later (Git style) — the order is reversed.

Self-check: What concurrency model did the first generation use, and why did it break down for collaboration?

Connects to: Section 7.4

Centralized vs Distributed Version Control

Must-know: The two models: centralized (SVN) does version control only on the server and merges before commit; distributed (Git) keeps a full repository on every workstation and commits before merge, pushing to a remote server. Trade-offs: single point of failure and slow remote commits versus extra disk space and bandwidth for the first clone.

⚠️ Top pitfall: Assuming a distributed system works like SVN: in Git the commit order flips — you commit locally first, and the merge with the remote happens later when you push; the remote is also a required central place for collaboration.

Self-check: Why is the centralized model called a single point of failure, and how does the distributed model remove that risk?

Connects to: Section 7.3, Section 7.5

Git and GitHub

Must-know: Git is the local distributed version control system; GitHub is the remote hosting and collaboration service. Reasons to use Git: fast local commands, offline work, suggestions when a command is wrong, branching, and pull requests (which come from the remote side).

⚠️ Top pitfall: Confusing Git with GitHub: pull requests are not part of Git itself — they come from the remote repository side (GitHub or Bitbucket); Git alone has no pull request feature.

Self-check: Which of Git's advantages comes from the distributed model, and what role does GitHub play in that model?

Connects to: Section 7.4, Section 7.6

The Foundation of Git: States, Areas, and Snapshots

Must-know: The three states (modified, staged, committed) and the four areas (working directory, staging area, .git repository, remote GitHub repository); the promotion path is edit, git add, git commit, git push. A commit creates a snapshot with a pointer to the previous snapshot, author, committer, and message.

⚠️ Top pitfall: Forgetting that git branch does not switch to the new branch: after creating a branch you must run git checkout <branch> to move your pointer to it.

Self-check: Which command promotes a file from modified to staged, and which area does the file occupy after commit?

Connects to: Section 7.7

Working with Repositories: The Daily Git Workflow

Must-know: The daily workflow: clone, modify, add, commit, pull (or fetch plus merge), push. Fetch brings remote changes only into the .git repository; merge makes them available in the working directory; git pull performs both in one command. Apart from clone and push, every command runs locally.

⚠️ Top pitfall: Running git fetch and assuming the remote changes are now in your working files: fetch only updates the .git repository — you still need a merge; use git pull to do both at once.

Self-check: If your push is rejected because a teammate pushed first, which two commands bring your repository in line with the remote, and which one does both jobs?

Connects to: Section 7.6, Section 7.10

GitHub Special Files and Repository Features

Must-know: The special files: README renders automatically on the landing page and is typically written in Markdown; license sets usage terms; changelog records changes; code of conduct sets collaboration rules. Configuration files must be kept out of merges (e.g., .gitignore or template files).

⚠️ Top pitfall: Committing personal configuration files with machine-specific values: they collide on every merge and can leak secrets — exclude them with .gitignore or keep them as untracked local copies.

Self-check: Why is the README file special on GitHub, and why should configuration files be kept out of merges?

Connects to: Section 7.9

Branching and Workflows: Git Flow vs GitHub Flow

Must-know: Git flow: feature branches merge into develop, develop into release, release into master (hotfixes cut from the live release) — for multi-version products like app 1.1 for customer X and 1.2 for customer Y. GitHub flow: single master branch, feature branches merged straight into it, hotfixes treated as feature branches — for single-version products.

⚠️ Top pitfall: The cheat-sheet trap: knowing the commands (git add, pull, reset, revert) without the logic (why fetch before pull, why revert over reset) fails as soon as a situation changes; the logic is what the exam tests.

Self-check: In Git flow, what is the fixed merge path for a feature, and which flow treats a hotfix exactly like a feature branch?

Connects to: Section 7.10

Merging, Merge Conflicts, and Undoing Work

Must-know: Conflict triggers: same-line edits, edits to deleted files, edits to already-updated files — always manual resolution. Undo ladder: git revert creates a new commit undoing one commit (safest); git reset soft moves the pointer keeping changes staged; mixed clears the staging area; hard returns everything to the clone state and is never recommended.

⚠️ Top pitfall: Running git reset --hard to fix a mess: it returns everything to the baseline and removes your changes entirely, which is why the professor says never, ever try git reset hard — prefer git revert.

Self-check: Which undo option creates a new commit instead of moving the pointer, and why is it the safest?

Connects to: Section 7.7, Section 7.9

Git Tagging

Must-know: A tag is a frozen reference point for a specific commit in Git history (e.g., v1.1.1) that becomes the baseline for upcoming changes. Unlike branches, tags have no further history of commits — to keep working you create a new branch, make changes, push to master, and tag again.

⚠️ Top pitfall: Expecting a tag to move like a branch: tags are frozen at creation and never receive commits; new work continues on a branch and receives its own tag at the next release.

Self-check: How does a tag differ from a branch after it is created, and how is a release baseline marked?

Connects to: Section 7.6, Section 7.9

Clean Code Practices

Must-know: Naming and simplicity: give variables and functions names that state their purpose (not int i or function f1 but names like variable1 or better, purpose-describing names; add for an add function). The 40-lines-of-code rule: a function should not exceed 40 lines — call a new function instead. Prefer fewer arguments and keep each function doing one thing.

⚠️ Top pitfall: Writing long single-purpose-violating functions with generic names like f1 and int i: the code is preserved forever by Git, so unclear names and long bodies burden every future reader and change.

Self-check: What does the 40-lines-of-code rule say, and why does clean code belong in a version control lecture?

Connects to: Section 7.3

Exam Guidance Summary

Must-know: Quiz rules: four quizzes of five marks each, only the best two count and become the ten quiz marks; missing one quiz is acceptable if the other three are attended. The tutorial session after the eighth contact session holds the Git lab experiments, and Platify carries practice tutorials.

⚠️ Top pitfall: Skipping a quiz without a plan: since only the best two of four quizzes count, you can miss one, but you must still attend and score well in the other three to protect your ten quiz marks.

Self-check: How many quizzes count toward the quiz marks, and where can you practice the Git commands?

Connects to: Section 7.6, Section 7.7, Section 7.9, Section 7.10

Key Industry Applications

Must-know: Where each model shows up in industry: SaaS (web-based email, Google Apps, Cisco WebEx, Office 365), IaaS (AWS EC2), PaaS in between; Git with GitHub/Bitbucket hosting; CI/CD via Jenkins, TeamCity, CircleCI, or GitHub Actions; Git flow for multi-version products, GitHub flow for single-version products; README, license, changelog, code of conduct, and v1.1.1-style release tags.

⚠️ Top pitfall: Treating Git as the only version control option: the industry map still includes centralized systems (Subversion, CVS, Vesta, OpenCVS; AccuRev, Helix Core, ClearCase, TFS) that many enterprises run.

Self-check: Which cloud service model does AWS EC2 exemplify, and which workflow suits a product shipping different versions to different customers?

Connects to: Section 7.1, Section 7.2, Section 7.4, Section 7.9

Was this lecture useful?

Loading comments…
🤖

BitsNotes AI Assistant

Subject Notes Assistant

Configure AI Chat

Choose how to access the chatbot
Have your own API key?

Switch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.

🔑 Enter API key above to fetch live models from provider, or enter model name manually.
OpenAI-Compatible API Support

Choose any provider preset (Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenAI, Groq, Ollama, etc.) or enter a custom endpoint URL.

Security & Privacy First

Your API key is sent directly from your browser to your specified provider. BitsNotes servers never store or see your key.