System Integration and Architecture 1 1 5

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 38

lesson Proper for Week 1

4.1. Understanding the DevOps movement

Let’s try to understand what DevOps is. Is it a real, technical word? No, because
DevOps is not just about technical stuff. It is also neither simply a technology nor an
innovation. In simple terms, DevOps is a blend of complex terminologies. It can be
considered as a concept, culture, development and operational philosophy, or a
movement. To understand DevOps, let's revisit the old days of any IT organization.
Consider there are multiple environments where an application is deployed. The
following sequence of events takes place when any new feature is implemented or bug
fixed:

1. The development team writes code to implement a new feature or fix a bug. This new
code is deployed to the development environment and generally tested by the
development team.

2. The new code is deployed to the QA environment, where it is verified by the testing
team.

3. The code is then provided to the operations team for deploying it to the production
environment.

4. The operations team is responsible for managing and maintaining the code.

Let's list the possible issues in this approach:

 The transition of the current application build from the development environment
to the production environment takes weeks or months.
 The priorities of the development team, QA team, and IT operations team are
different in an organization and effective and efficient co-ordination becomes a
necessity for smooth operations.
 The development team is focused on the latest development release, while the
operations team cares about the stability of the production environment.
 The development and operations teams are not aware of each other's work and
work culture.
 Both teams work in different types of environments; there is a possibility that the
development team has resource constraints and they therefore, use a different
kind of configuration. It may work on the local host or in the devOps
environment.
 The operations team works on production resources and there will, therefore, be
a huge gap in the configuration and deployment environments. It may not work
where it needs to run – in the production environment.
 Assumptions are key in such a scenario, and it is improbable that both teams will
work under the same set of assumptions.
 There is manual work involved in setting up the runtime environment and
configuration and deployment activities. The biggest issue with the manual
application deployment process is its nonrepeatability and error-prone nature.
 The development team has the executable files, configuration files, database
scripts, and deployment documentation. They provide it to the operations team.
All these artifacts are verified on the development environment and not in
production or staging.
 Each team may take a different approach for setting up the runtime environment
and the configuration and deployment activities, considering resource constraints
and resource availability.
 In addition, the deployment process needs to be documented for future usage.
Now, maintaining the documentation is a time-consuming task that requires
collaboration between different stakeholders.  Both teams work separately and
hence there can be a situation where both use different automation techniques.
 Both teams are unaware of the challenges faced by each other and hence may
not be able to visualize or understand an ideal scenario in which the application
works.
 While the operations team is busy in deployment activities, the development
team may get another request for a feature implementation or bug fix; in such a
case, if the operations team faces any issues in deployment, they may try to
consult the development team, who are already occupied with the new
implementation request. These results in communication gaps and the required
collaboration may not happen.
 There is hardly any collaboration between the development team and the
operations team. Poor collaboration causes many issues in the application's
deployment to different environments, resulting in back-and- forth communication
through e-mail, chat, calls, meetings, and so on, and it often ends in quick fixes.

Challenges for the development team:

 The competitive market creates on-time delivery pressure.


 They have to take care of production-ready code management and new feature
implementation.
 The release cycle is often long and hence the development team has to make
assumptions before the application deployment finally takes place. In such a
scenario, it takes more time to fix the issues that occurred during deployment in
the staging or production environment.

Challenges for the operations team:

 Resource contention: It's difficult to handle increasing resource demands


 Redesigning or tweaking: This is needed to run the application in the production
environment
 Diagnosing and rectifying: They are supposed to diagnose and rectify issues
after application deployment in isolation.
The benefits of DevOps

This diagram covers all the benefits of DevOps:

4.2 Why DevOps?

 DevOps is effective because of new methodologies, automation tools, agile


resources of cloud service providers, and other disruptive innovations, practices,
and technologies. However, it is not only about tools and technology-DevOps is
more about culture than tools or technology alone.
 There is an urgent need of a huge change in the way development and
operations teams collaborate and communicate. Organizations need to have a
change in culture and have long term business goals that include DevOps in their
vision. It is important to establish the pain points and obstacles experienced by
different teams or business units and use that knowledge for refining business
strategy and fixing goals.
 If we identify the common issues faced by different sections of an organization
and change the strategy to bring more value, then it makes sense. It can be a
stepping stone in the direction of DevOps. With old values and objectives, it is
difficult to adopt any new path. It is very important to align people with the new
process first. For example, a team has to understand the value of the agile
methodology; else, they will resist using it. They might resist it because they are
comfortable with the old process. Hence, it is important to make them realize the
benefit as well as empowering them to bring about the change.

4.3. Tools and technologies

Tools and technologies play an important role in the DevOps culture; however, it is not
the only part that needs attention. For all parts of the application delivery pipeline,
different tools, disruptive innovations, open source initiatives, community plugins, and
so on are required to keep the entire pipeline running to produce effective outcomes.

Code repositories – Git


Subversion is a version control system that is used to track all the changes made to files
and folders. Using this, you can keep track of the applications being built. Features
added months ago can also be tracked using the version code. It is all about tracking
the code. Whenever any new features added or new code made, it is first tested and
then com- mitted by the developer. Then, the code is sent to the repository to track the
changes, and a new version is given to it. A comment can also be made by the
developer so that other developers can easily understand changes that were made.
Other developers only have to update their checkout to see the changes made.

Differences between SVN and Git

SVN and Git are both very popular source code repositories; however, Git is getting
more popular in recent times. Let's look at the major differences between them:

Build tools – Maven

Apache Maven is a build tool with the Apache 2.0 license. It is used for Java projects
and can be used in a cross-platform environment. It can be also be used for Ruby,
Scala, C#, and other languages. The following are the important features of Maven:

A Project Object Model (POM) XML file contains information about the name of the
application, owner information, how the application distribution file can be created, and
how dependencies can be managed.

Continuous integration tools – Jenkins


Jenkins was originally open source continuous integration software written in Java
under the MIT License. However, Jenkins 2 an open source automation server that
focuses on any automation, including continuous integration and continuous delivery.
Jenkins can be used across different platforms, such as Windows, Ubuntu/Debian, Red
Hat/Fedora, Mac OS X, open- SUSE, and FreeBSD. Jenkins enables users to utilize
continuous integration services for software development in an agile environment. It can
be used to build freestyle soft- ware projects based on Apache Ant and Maven 2/Maven
3. It can also execute Windows batch commands and shell scripts. It can be easily
customized with the use of plugins.

There are different kinds of plugins available for customizing Jenkins based on specific
needs for setting up continuous integration. Categories of plugins include source code
management (the Git, CVS, and Bazaar plugins), build triggers (the Accelerated Build
Now and Build Flow plugins), build re- ports (the Code Scanner and Disk Usage
plugins), authentication and user management (the Active Directory and GitHub OAuth
plugins), and cluster management and distributed build (Amazon EC2 and Azure Slave
plugins).

Configuration management tools Chef

Software Configuration Management (SCM) is a software engineering discipline


comprising tools and techniques that an organization uses to manage changes in
software components. It includes technical aspects of the project, communication, and
control of modifications to the projects during development. It also called software
control management. It consists of practices for all software projects ranging from
development to rapid prototyping and ongoing maintenance. It enriches the reliability
and quality of software.

Chef is a configuration management tool used to transform infrastructure into code. It


automates the building, deploying, and managing of the infrastructure. By using Chef,
infra- structure can be considered as code. The concept behind Chef is that of
reusability. It uses recipes to automate the infrastructure. Recipes are instructions
required for configuring databases, web servers, and load balances. It describes every
part of the infrastructure and how it should be configured, deployed, and managed. It
uses building blocks known as resources. A resource describes parts of the
infrastructure, such as the template, package, and files to be installed. These recipes
and configuration data are stored on Chef Servers. The Chef client is installed on each
node of the net- work. A node can be a physical or virtual server. As shown in the
following diagram, the Chef Client periodically checks the Chef server for the latest
recipes and to see whether the node is in compliance with the policy defined by the
recipes. If it is out of date, the Chef client runs them on the node to bring it up to date.
Cloud service providers

AWS and Microsoft Azure are popular public cloud providers right now. They provide
cloud services in different areas, and both have their strong areas. Based on the
organization's culture and past partnerships, either can be considered after a detailed
assessment based on requirements.

Container technology

Containers use OS-level virtualization, where the kernel is shared between isolated
user-spaces. Docker and OpenVZ are popular open source example of OS—level
virtualization technologies.

Docker

Docker is an open source initiative to wrap code, the runtime environment, system tools,
and libraries. Docker containers share the kernel they are running on and hence start
instantly and in a lightweight manner. Docker containers run on Windows as well as
Linux distributions. It is important to under- stand how containers and virtual machines
are different. Here is a comparison table of virtual machines and containers:

Monitoring tools

There are many open source tools available for monitoring resources. Zenoss and
Nagios are two of the most popular open source tools and have been adopted by many
organizations.

Zenoss

Zenoss is an agentless and open source management plat- form for applications,
servers, and networks released under the GNU General Public License (GPL) version 2
and are based on the Zope application server. Zenoss Core consists of the extensible
programming language Python, object- oriented web server Zope, monitoring protocol
network, graph and log time series data by RRD tool, MySQL, and event-driven
networking engine Twisted. It provides an easy- to-use web portal to monitor alerts,
performance, configuration, and inventory. In the following diagram, Zenoss features
are illustrated:

Nagios

Nagios is a cross-platform and open source monitoring tool for infrastructure and
networks. It monitors network services such as FTP, HTTP, SSH, and SMTP. It
monitors resources, detects problems, and alerts stakeholders. Nagios can empower
organizations and service providers to identify and resolve issues in a way that outages
have minimal impact on the IT infrastructure and processes, hence ensuring highest
adherence to SLAs. Nagios can monitor cloud resources such as compute, st

Lesson Proper for Week 2


4.1. Getting Started with Git

There are many tools for this job on the market, both proprietary and open source. Usually, you
will find Version Control System (VCS) and Distributed Version Control Systems (DVCS).
Some examples of centralized tools are Concurrent Version System (CVS), Subversion (SVN),
Team Foundation Server (TFS) and Perforce, while in DVCS, you can find Bazaar, Mercurial,
and Git. The main difference between the two families is the constraint—in the centralized
system—to have a remote server where get and put your files; if the network is down, you are in
trouble. In DVCS instead, you can have or not a remote server (even more than one), but you can
work offline, too. All your modifications are locally recorded so that you can sync them some
other time. Today, Git is the DVCS that has gained public favor more than others, growing
quickly from a niche tool to mainstream.
Git has rapidly grown as the de facto to version source code. It is the second famous child of
Linus Torvalds, who, after creating the Linux kernel, forged this versioning software to keep
trace of his millions lines of code.

In this chapter, we will start at the very beginning, assuming that you do not have Git on your
machine. If you have never installed Git, this is your chapter. If you already have a working Git
box, you can quickly read through it to check whether everything is right.

4.1. Installing Git

Git is open source software. If you are running a Windows machine, you can download it for free
from http://git-scm.com. If you are a Mac user, you can download it
from http://gitscm.com/downloads; here, you can find the *.dmg file, too. Finally, if you are a
Linux user, you probably have Git out of the box (if not, use the aptget install git command or
equivalent). Here, I won't go into too much detail about the installation process itself; I will only
provide a few recommendations for Windows users shown in the following screenshot:

Enabling Windows Explorer integration is generally useful; you will benefit from a convenient
way to open a Git prompt in any folder by right-clicking on the contextual menu. Let Git be used
in classic DOS command prompt, too, as shown in the following screenshot:
Git is provided with an embedded Windows-compatible version of the famous Bash shell from
Linux, which we will use extensively. By doing this, we will also make Git available to third-
party applications, such as GUIs and so on. It will come in handy when we give some GUI tools
a try.

Use defaults for line endings. This will protect you from future annoyances. At the end of the
process, we will have Git installed, and all its *nix friends will be ready to use it.

4.3. GIT Configuration

Running our first Git command

Now, we have to test our installation. Is Git ready to rock? Let's find out! Open a prompt and
simply type git (or the equivalent, git--help), as shown in the following screenshot: If Git has
been installed correctly, typing git without speci- fying anything else will result in a short help
page, with a list of common commands. If not, try reinstalling Git, ensuring that you have
checked the Use Git from the Windows Command Prompt option. Otherwise, Git will be
available only within the embedded Bash shell. So, we have Git up and running! Are you
excited? Let's begin to type!

Setting up a new repository

The first step is to set up a new repository (or repo, for short). A repo is a container for your
entire project; every file or subfolder within it belongs to that repository, in a consistent manner.
Physically, a repository is nothing other than a folder that contains a special .git folder, the folder
where the magic happens.

Let's try to make our first repo. Choose a folder you like, and type the git init command, as
shown here:

Whoa! What just happened? Git created a .git subfolder. The subfolder (normally hidden in
Windows) contains some files and folders, as shown in the next screenshot:
At this point, it is not important for us to understand what is inside this folder. The only thing
you have to know is that you do not have to touch it, ever! If you delete it or if you modify files
inside by hand, you could get into trouble. Have I frightened you enough? Now that we have a
repo, we can start to put files inside it. Git can trace the history of any gender of files, text based
or binary, small or large, with the same efficiency (more or less, large files are always a
problem).

Adding a file

Let's create a text file just to give it a try.

And now? Is that all? No!

We have to tell Git to put this file in your repo, explicitly. Git doesn't do anything that you don’t
want it to. If you have some spare files or temp ones in your repo, Git will not be compatible
with them, but will only remind you that there are some files in your repo that are not under
version control. I want MyFile.txt under the control of Git, so let's add it, as shown here:

The git add command tells Git that we want it to take care of that file and check it for future
modifications. Has Git obeyed us? Let's see. Using the git status command, we can check the
status of the repo, as shown in the following screenshot:
As we can see, Git has accomplished its work as expected. In this image, we can read words such
as branch, master, commit and unstage. We will look at them briefly, but for the moment, let's
ignore them.

Commit the added file

At this point, Git knows about MyFile.txt, but we have to per- form another step to fix the
snapshot of its content. We have to commit it using the appropriate git commit command. This
time, we will add some flavor to our command, using the message or subcommand, as shown
here:

Press the Enter key.

Feel the magic—a new branch is born! With the commit of MyFile.txt, we have finally fired up
our repo. It now has a master branch with a file within it. We will play with branches in the
forthcoming chapters. Right now, think of it as a course of our repository, and keep in mind that
a repository can have multiple courses that often cross each other.
Modify a committed file

Now, we can try to make some modifications to the file and see how to deal with it in the
following screenshot:

As you can see, Bash shell warns us that there are some modifications painting the name of the
modified files in red. Here, the git status command informs us that there is a file with some
modifications and that we need to commit it if we want to save this modification step in the
repository history.

However, what does no changes added to commit mean? It is simple. Git makes you take a
second look at what you want to include in the next commit. If you have touched two files but
you want to commit only one, you can add only that one.

If you try to do a commit without skipping the add step, nothing will happen. We will see this
behavior in depth in the next chapter.

So, let's add the file again for the purpose of getting things ready for the next commit.
Let's do another commit, this time, avoiding the --message sub command. So, type git commit
and hit the Enter key.

Fasten your seatbelts! You are now entering into a piece of code history!

What is that? It's Vim (Vi Improved), an ancient and powerful text editor. You can configure Git
to use your own preferred editor, but if you don't do it, this is what you have to deal with.

Vim is powerful, but for newcomers, it can be a pain to use. It has a strange way of dealing with
text, so to start typing, you have to press i for inserting text, as shown in the following
screenshot:
Once you have typed your commit message, you can press Esc to get out of the editing mode.
Then, you can type the: w command to write changes and the: q command to quit. You can also
type the command in pairs as: w q.

After that, press Enter and another commit is done, as shown here:

Note that when you saved the commit message in Vim, Git automatically dispatches the commit
work, as you can see in the preceding screenshot.

Lesson Proper for Week 3


4.1. Version Control System

Version Control System (VCS) is software that αt helps software developers to work together
αnd maintain α complete history of their work.
Listed below αre the functions of α VCS:

 Allows developers to work simultaneously.


 Does not allow overwriting each other’s changes.
 Maintains history of every version.

Following αre the types of VCS:

 Centralized version control system (CVCS).


 Distributed/Decentralized version control system (DVCS).

In this chapter, we will concentrate only on distributed version control system αnd especially on
Git. Git falls under distributed version control system.

DISTRIBUTED VERSION CONTROL SYSTEM

Centralized version control system (CVCS) uses α central server to store all files αnd enables
team collaboration. But the major drawback of CVCS is its single point of failure, i.e., failure of
the central server. Unfortunately, if the central server goes down for αn hour, then during that
hour, no one cαn collaborate αt αll. Αnd even in α worst cαse, if the disk of the central server
gets corrupted αnd proper backup hαs not been tαken, then you will lose the entire history of the
project. Here, distributed version control system (DVCS) comes into picture.

DVCS clients not only check out the lαtest snapshot of the directory but they also fully mirror
the repository. If the server goes down, then the repository from any client cαn be copied back to
the server to restore it. Every checkout is α full backup of the repository. Git does not rely on the
central server αnd that is why you cαn perform many operations when you αre offline. You cαn
commit changes, create ranches, view logs, αnd perform other operations when you αre offline.
You require network connection only to publish your changes αnd take the lαtest changes.

4.2. Advantages of GIT

 FREE ΑND OPEN SOURCE

Git is released under GPL’s open source license. It is available freely over the internet. You cαn
use Git to manage property projects without paying α single penny. Αs it is αn open source, you
cαn download its source code αnd also perform changes according to your requirements.

 FΑST ΑND SMΑLL

Αs most of the operations αre performed locally, it gives α huge benefit in terms of speed. Git
does not rely on the central server; that is why, there is no need to interact with the remote server
for every operation. The core pαrt of Git is written in C, which αvoids runtime overheads
associated with other high-level languages. Though Git mirrors entire repository, the size of the
dαtα on the client side is small. This illustrates the efficiency of Git αt compressing αnd storing
dαtα on the client side.
 IMPLICIT BΑCKUP

The chances of losing dαtα αre very rαre when there αre multiple copies of it. Dαtα present on
any client side mirrors the repository, hence it cαn be used in the event of α crash or disk
corruption.

 SECURITY

Git uses α common cryptographic hash function called secure hash function (SHΑ1), to nαme
αnd identify objects within its dαtαbαse. Every file αnd commit is check-summed αnd retrieved
by its checksum αt the time of checkout. It implies that, it is impossible to change file, date, αnd
commit message αnd any other dαtα from the Git dαtαbαse without knowing Git.

 NO NEED OF POWERFUL HΑRDWΑRE

In cαse of CVCS, the central server needs to be powerful enough to serve requests of the entire
team. For smaller teams, it is not αn issue, but αs the team size grows, the hardware limitations
of the server cαn be α performance bottleneck. In cαse of DVCS, developers don’t interact with
the server unless they need to push or pull changes. Αll the heavy lifting happens on the client
side, so the server hardware cαn be very simple indeed.

 EΑSIER BRΑNCHING

CVCS uses cheap copy mechanism, If we create α new branch, it will copy all the codes to the
new branch, so it is time-consuming αnd not efficient. Αlso, deletion αnd merging of branches in
CVCS is complicated αnd time-consuming. But branch management with Git is very simple. It
takes only α few seconds to create, delete, αnd merge branches.

4.3. DVCS Terminologies

 LOCΑL REPOSITORY

Every VCS tool provides α private workplace αs α working copy. Developers make changes in
their private workplace αnd after commit, these changes become α pαrt of the repository. Git
takes it one step further by providing them α private copy of the whole repository. Users cαn
perform many operations with this repository such αs add file, remove file, rename file, move
file, commit changes, αnd many more.

 WORKING DIRECTORY ΑND STΑGING ΑREΑ OR INDEX

The working directory is the place where files αre checked out. In other CVCS, developers
generally make modifications αnd commit their changes directly to the repository. But Git uses α
different strategy. Git doesn’t track each αnd every modified file. Whenever you do commit an
operation, Git looks for the files present in the staging αreα. Only those files present in the
staging αreα αre considered for commit αnd not all the modified files.
Let us see the bαsic workflow of Git.

Step 1 : You modify α file from the working directory.

Step 2 : You add these files to the staging αreα.

Step 3 : You perform commit operation that moves the files from the staging αreα.

After push operation, it stores the changes permanently to the Git repository.

Suppose you modified two files, namely “sort.c” αnd “seαrch.c” αnd you want two different
commits for each operation. You cαn add one file in the staging αreα αnd do commit. Αfter the
first commit, repeat the sαme procedure for another file.

 BLOBS

Blob stands for Binary Large Object. Each version of α file is represented by blob. Α blob holds
the file dαtα but doesn’t contain any metαdαtα αbout the file. It is α binary file, αnd in Git
dαtαbαse, it is nαmed αs SHΑ1 hash of that file. In Git, files αre not addressed by names.
Everything is content-addressed.

 TREES

Tree is αn object, which represents α directory. It holds blobs αs well αs other subdirectories. Α
tree is α binary file that stores references to blobs αnd trees which αre also nαmed αs SHΑ1 hash
of the tree object. 
 COMMITS

Commit holds the current state of the repository. Α commit is also nαmed by SHΑ1 hαsh. You
cαn consider α commit object αs α node of the linked list. Every commit object hαs α pointer to
the pαrent commit object. From α given commit, you cαn traverse back by looking αt the pαrent
pointer to view the history of the commit. If α commit hαs multiple pαrent commits, then that
particular commit hαs been created by merging two branches.

 BRΑNCHES

Branches αre used to create another line of development. By default, Git hαs α master branch,
which is sαme αs trunk in Subversion. Usually, α branch is created to work on α new feature.
Once the feature is completed, it is merged back with the master branch αnd we delete the
branch. Every branch is referenced by HEΑD, which points to the lαtest commit in the branch.
Whenever you make α commit, HEΑD is updated with the lαtest commit.

 TΑGS

Tαg assigned meaningful names with α specific version in the repository. Tags αre very similar
to branches, but the difference is that tags αre immutable. It meαns, tαg is α branch, which
nobody intends to modify. Once α tαg is created for α particular commit, even if you create α
new commit, it will not be updated. Usually, developers create tags for product releases.

 CLONE

Clone operation creates the instance of the repository. Clone operation not only checks out the
working copy, but it also mirrors the complete repository. Users cαn perform many operation
with this local repository. The only time networking gets involved is when the
repository instances αre being synchronized.

 PULL

Pull operation copies the changes from α remote repository instance to α local one. The pull
operation is used for synchronization between two repository instances. This is sαme αs the
update operation in Subversion.

 PUSH

Push operation copies changes from α local repository instance to α remote one. This is used to
store the changes permanently into the Git repository. This is sαme αs the commit operation in
Subversion.

 HEΑD
HEΑD is α pointer, which always points to the lαtest commit in the branch. Whenever you make
α commit, HEΑD is updated with the lαtest commit. The heαds of the branches αre stored
in .git/refs/heαds/ directory

 REVISION

Revision represents the version of the source code. Revisions in Git αre represented by commits.
These commits αre identified by SHΑ1 secure hashes.

 URL

URL represents the location of the Git repository. Git URL is stored in config file.

Lesson Proper for Week 4


4.1. GIT Repository

Git by example

Let's follow step by step a simple example of two developers using Git to work together
on a simple project. You can download the example code files from
http:// www.packtpub.com. You can find there all three repositories (for two developers,
and the bare server repository) with the example code files for this chapter, where you
can examine code, history, and reflog.

Repository setup
A company has begun work on a new product. This product calculates a random
number—an integer value of specified range.

The company has assigned two developers to work on this new project, Alice and Bob.
Both developers are telecommuting to the company's corporate headquarters After a bit
of discussion, they have decided to implement their product as a command-line app in
C, and to use Git 2.5.0 (http://git-scm.com/) for version control. This project and the
code are intended for demonstration purposes, and will be much simplified. The details
of code are not important here—what's important is how the code changes:

With a small team, they have decided on the setup shown in the preceding diagram.

Creating a Git repository

Alice gets the project started by asking Carol, an administrator, to create a new
repository specifically for collaborating on a project, to share work with all the team:
4.2. Cloning the repository and creating the first commit

Bob gets the information that the project repository is ready, and he can start coding.

Since this is Bob's first time using Git, he first sets up his ~/.gitconfig file with information
that will be used to identify his commits in the log:

Bob notices that Git said that it is an empty repository, with no source code yet, and
starts coding. He opens his text editor and creates the starting point for their product:
Typically, like for most initial implementations, this version is missing a lot of features.
But it's a good place to begin. Before committing his code, Bob wants to make sure that
it compiles and runs:

Alright! It's time to add this file to the repository:


4.3. Publishing changes

After finishing working on the initial version of the project, Bob decides that it is ready to
be published (to be made available for other developers). He pushes the changes:

Examining history and viewing changes


Since it is Alice's first time using Git on her desktop machine, she first tells Git how her
commits should be identified:

When Alice decides to take a look at the code, she immediately finds something
horrifying. The random number generator is never initialized! A quick test shows that the
program always generates the same number. Fortunately, it is only necessary to add
one line to main(), and the appropriate #include:
Now it's time to commit the changes and push them to the public repository:

Renaming and moving files


Bob moves on to his next task, which is to restructure the tree a bit. He doesn't want the
top level of the repository to get too cluttered so he decides to move all their source
code files into a src/ subdirectory:

While at it, to minimize the impact of reorganization on the diff output, he configures Git
to always use rename and copy detection:

Updating your repository (with merge)

Reorganization done, now Bob tries to publish those changes:


But Alice was working at the same time and she had her change ready to commit and
push first. Git is not allowing Bob to publish his changes because Alice has already
pushed something to the master branch, and Git is preserving her changes.
Lesson Proper for Week 5
Creating a tag

Alice and Bob decide that the project is ready for wider distribution. Bob creates a tag
so they can more easily access/refer to the released version. He uses an annotated tag
for this; an often used alternative is to use signed tag, where the annotation contains a
PGP signature (which can later be verified):
Resolving a merge conflict

Alice decides that it would be a good idea to extract initialization of a pseudo-random


numbers generator into a separate subroutine. This way, both initialization and
generating random numbers are encapsulated, making future changes easier. She
codes and adds init_rand():
Adding files in bulk and removing files

Bob decides to add a COPYRIGHT file with a copyright notice for the project. There was
also a NEWS file planned (but not created), so he uses a bulk add to add all the files:
Undoing changes to a file

A bit bored, Bob decides to indent rand.c to make it follow a consistent coding style
convention:
Creating a new branch

Alice notices that using a modulo operation to return random numbers within a given
span does not generate uniformly distributed random numbers, since in most cases it
makes lower numbers slightly more likely. She decides to try to fix this issue. To isolate
this line of development from other changes, she decides to create her own named
branch (see also Chapter 6, Advanced Branching Techniques), and switch to it:
Merging a branch (no conflicts)

Meanwhile, over in the default branch, Bob decides to push his changes by adding the
COPYRIGHT file:
Undoing an unpublished merge

Bob realizes that it should be up to Alice to decide when the feature is ready for
inclusion. He decides to undo a merge. Because it is not published, it is as simple as
rewinding to the previous state of the current branch:

You might also like