13
Working with Git
We have already dealt with various aspects of network
automation using Python, Ansible, and many other tools. For
the exercises in the first 12 chapters, more than 150 files containing
more than 5,300 lines of code were used. This is not
bad for network engineers who have mostly worked with the
command-line interface before reading this book! Armed with
these new scenarios and tools, we're ready to jump in and
automate our routine network tasks, right? Not quite. Let's
cool down a little. There are some points that need to be taken
into account when solving real-world problems. Let's go
through them and talk about how the Git version control
system can help. This chapter covers the following topics::
z Git and various aspects of
z content management;
z introduction to Git; getting Git
z ready; examples with Git;
z Git combined with Python;
z
automation of backup of configuration data;
z
collaboration using Git. So, let's see what
aspects we are talking about and how Git can help.
Git and various aspects of content management 447
Git and various aspects
of content management
First of all, when creating code files, you should think about the storage
location where we and our colleagues can extract them. Ideally, this
should be a single central file storage facility that can
provide backups if necessary. After the first release of the code,we will
probably need to add new features and fix bugs, so
we need to somehow track these changes and make
the latest versions available for download. If the new version of the
code doesn't work, it doesn't hurt to roll it back and see differences in
the file's change history. This will allow us to find out how the to was
updated.t or another code. The second aspect is the collaboration of
team members. Working in collaboration with other network
engineers, we will most likely have to edit the same files: Python and
Ansible scripts, Jinja2 templates, INI configuration files, and so [Link]
made to any text files by different people should be visible to all team
members. The third aspect is accounting. A system that allows different
people to edit the same files should have a history of edits with an
indication of the author of each change and a brief description of the
reason why the change was made, so that the person viewing the
history can understand why this or that edit was made. These
are the main tasks that version control systems, such as Git, solve.
In fairness, it should be noted that the version management process
can be implemented not only as a separate software system. For
example, in Microsoft Word, a document is permanently automatically
saved , and I can go back in time to view changes, or
roll back to a previous version. This is also a form of version control;
however, a Word document is usually limited to my laptop. The
version control system to which this chapter is devoted is a separate
software tool whose main purpose is to track changes
made to the code. There is no shortage of source code management
tools in the programming world . There are both commercial and open
source versions. The most popular open source version control systems
are CVS, SVN, Mercurial, and Git. In this chapter, we will focus on Git.
Many of the examples presented in this book are stored in the same
version control system, which allows you to keep track of the following:
448 Chapter 13: Working with Git
changes, work together on them and exchange views
with users. We chose Git because it is actually the
standard version control system for many large open
source projects, including Python and the Linux kernel.
In February 2017, the development of the CPython project
completely moved to GitHub. The transition to this
system began in January 2015. Read more about this in PEP
512 at [Link] /.
Before moving on to examples of working with Git, let's
talk about the history and advantages of this system.
Introduction to Git
The Git project was created in April 2005 by Linus Torvalds, the author
of the Linux kernel. In a witty way, Linus affectionately called
him " the information dispatcher from hell." In an interview with the
Linux Foundation, he mentioned that, in his opinion, source code
management was the least interesting thing in the computer world (
[Link]
interview-with-git-creator-linus-torvalds/ ). However, when between a community
When the Linux kernel developers and the
BitKeeper project (a commercial system they used at the
time) were at odds,Linus decided to create Git.
What does the name Git mean? In British English slang, git is a
derogatory term used to refer to unpleasant, annoying,
immature people. In a deadpan manner, Linus declared
that he was an egotist and named all his projects after himself.
First Linux, now Git. But there is an opinion that this is an
abbreviation for Global Information Tracker (global information
tracking system). Choose the option that you prefer.
The project was implemented in a very short time. Approximately ten days
after the foundation (exactly so, didn't you think) Linus developed the basic
ideas of the Git system and started saving the Linux kernel code to it. The
rest, as they say, is history. More than a decade after its creation, Git
continues to meet all the expectations of Linux developers. This version control system
has started to be used in many other open source projects, although, like
Introduction to Git 449
as a rule, developers are reluctant to make such changes. In
) Python project
February 2017 , after many years of using Mercurial ( [Link]
switched to Git and GitHub.
So, we discussed the history of creating the Git system. Now
consider its advantages.
Advantages of Git
Successful hosting of large and distributed open source projects
such as the Linux kernel and Python demonstrates the benefits of
Git. In other words, if this tool is good enough for developers of
the most popular operating system (in my opinion) and the most
popular programming language (again in my opinion) in the
world, it will most likely be enough for my home project. It's also a
relatively new version control system, and people are reluctant to
upgrade to new tools if they don't offer significant improvements
over the old ones. Let's take a look at some of the benefits of Git.
z
Distributed development. Git supports parallel,
independent, and concurrent development in private local repositories.
Many other version control systems require
constant synchronization with a central repository.
Git's distributed nature and locality give developers more flexibility.
z Scaling up to support thousands of developers.
Thousands of developers work on other open projects, and Git
provides reliable integration of their work results.
Efficiency. Linus tried to make the Git system fast
z
and efficient. To save space for storing huge code
updates in the Linux kernel and time for transferring them, Git uses
compression and checks for differences between different versions.
Accounting and immutability. Git logs every commit that changes files,
z
creating a history of updates with a description of their causes. Data objects
in Git cannot be changed after they are created and saved to the
database, which makes them immutable. This improves and simplifies
accounting. Atomic transactions. To ensure the integrity of the repository,
z
different but related changes are made either all together,
or none of them are made. This means that the repository can't
end up in a partially modified or corrupted state.
450 Chapter 13: Working with Git
z
Self-contained repositories. Each repository stores a complete
copy of all edits made to each file.
z Freedom. The Git project emerged as a result of disagreements
between Linux developers and BitKeeper VCS regarding whether the software
should be free and whether commercial software should be rejected
in principle . So it makes sense that Git has a very liberal license.
Before getting familiar with Git, let's look at the terms of this system.
Git Terminology
Git Terms you should know:
z
Link (ref). A name that starts with refs and points to the object.
z
The repository. This is a database with all the information, files
, metadata, and project history. It contains references to all
collections of objects.
z
The branch. This is an active area of development. The last feature is
) or head (
called top of it (tip )headbranches. There may be several
branches in the repository, but your working tree, or working kata
log, can only be associated with one of them. Such a branch is
sometimes called the current one extracted information (checked out).
z Switching (checkout). This is an operation that completely or partially
updates the working tree to a certain point.
z Commit. This is a specific point in time in
the Git repository; it can also mean the process of saving a new snapshot
to the repository.
z Merge. This is an operation to move the contents of another branch to
the current branch . For example, I merge branches
development and master.
Getting (fetch). Retrieving the contents of a remote repository.
z
Extract (pull). Getting and merging a repository.
z
Tag. A placemark assigned to an important point in time saved
z
in the repository. In chapter 4, we saw how labels were used to identify
issues (for example,
v2.5.0a1).
This is not a complete list. For more terms
with descriptions, see the Git glossary at
[Link] .
Getting Git up and running 451
Finally, before moving on to configuring and using Git, let
's talk about an important difference between Git and
GitHub that people unfamiliar with the two systems may miss.
Git and GitHub
Git and GitHub are not the same thing. Sometimes this creates
confusion among engineers who are just getting familiar with the field. Git is
) - centralized hosting service
a version management system, and GitHub ( [Link]
Git repositories. GitHub was founded in 2008 and still maintains
its independence, although it was acquired by Microsoft in 2018.
Since Git is a decentralized system, GitHub stores only one of
the local copies of our project repository. Often, the GitHub repository
is made central, and all developers save their changes to it.
After the acquisition of GitHub by Microsoft
([Link] com / blog/2018/10/26/microsoft-completes-github-acquisition/)
many in the developer community were worried about the
independence of this project. But, as stated in the press release,
"GitHub will maintain its ideals of putting developers first, continue
to operate independently, and remain an open platform."
GitHub develops the idea of a central repository in a distributed system
through mechanisms such as fork (fork - "creating a copy") and request to
include the changes made (pull request). Developers who maintain a
project on GitHub usually encourage you to create a copy of it (fork)
and work with it as a central repository. After making changes, you
can submit a request to include the changes in the main project,
where they will be checked and recorded if they meet all the criteria. GitHub
also provides a web-based interface for repositories that can be
used in addition to the command line; this makes Git easier to work
with. So, having decided on the differences between Git and GitHub,
we can proceed to the main topic! First, let's get Git ready for use.
Getting Git up and running
So far, we've only used Git to download files from GitHub. In this
section, we'll go a little further and set up a local Git repository,
452 Chapter 13: Working with Git
to be able to save our files in it. In this example, I will
use a familiar management host with Ubuntu 18.04. If you are
using a different version of Linux or a different operating
system, just search the Internet for the appropriate installation
instructions. Install Git using the Package Manager ,aptif you haven't already done so:
(venv) $ sudo apt update
(venv) $ sudo apt install
-y git (venv) $ git --version
git version 2.17.1
After installation git let's make some settings, to send fic messages-
the documents contained the correct information:
$ git config --global [Link]
"Ваше имя" $ git config --global
[Link] "email@[Link]" $ git
config --list [Link]=Your name
[Link]=email@[Link]
You can go the other way and edit the file ~/.gitconfig:
$ cat ~/.gitconfig
[user] name =
Your name email =
email@[Link]
Git supports many parameters that can be changed, but
the name and email address allow you to commit
changes without receiving warnings. By default, you can enter
messages that accompany commits using the Emacs text
editor, but I personally prefer to use VIM for this purpose:
(optional) $ git config
--global [Link] "vim"
$ git config --list [Link]=Your
name
[Link]=email@[Link] core. editor=vim
Before you start working with Git, let's discuss the file .gitignore.
Gitignore
There are files that should not be saved in GitHub or other repositories;
these are files with passwords, API keys, and other confidential information.
Getting Git up and running 453
information. To prevent them from being saved, the easiest way is
to create a file in the repository's root folder .gitignore . Git will use
.gitignore, to determine which file
and
directories should be ignored before committing. The file must be sent and distributed.- .gitignore
exchange information between other users as early as possible.
Imagine the panic you might experience if you accidentally
save your group API key to a public repository. File. it makes
sense to create gitignore together with the new repository.
In fact, this feature is provided on the GitHub platform.
you can specify files that relate to a specific language. .gitignore
Excluding files with Python bytecode:
# Byte-compiled /
optimized / DLL
files __pycache__/ *.py[cod]
*$[Link]
You can also specify files related to our operating system:
# OSX # =========================
.DS_Store
.AppleDouble
.LSOverride
More about .gitignore you can find out on the GitHub help page: [Link]
[Link]/articles/ignoring-files/ . Here are some more links:
.
z How to use Gitignore: [Link]
z
A set of templates for .gitignore from GitHub: [Link]
gitignore .
z Python example: .gitignore [Link]
.
blob/master/[Link]
z File .gitignore for the repository of this book: [Link]
PacktPublishing/Mastering-Python-Networking-Third-Edition/blob/master/.gitignore .
In my opinion, the file .gitignore it should be created simultaneously with any
a new repository. This will allow you to implement
this concept as early as possible. In the next
section, we'll look at some examples of using Git.
454 Chapter 13: Working with Git
Examples of working with Git
In my experience, working with Git mostly uses the
command line and various parameters. Graphical tools can be useful
for tracking changes, viewing history, and comparing
different versions, but they are rarely used for routine
operations such as branching and committing. You can get
help for Git command-line
git --help: options by using the command
(venv) $ git --help usage: git [--version] [--help]
[-C <path>] [-c <name>=<value>]
[--exec-path[=<path>]] [--html-path] [--man-path] [--info-path] [-p
| --paginate | --no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>]
[--namespace=<name>] <command> [<args>]
Creating a repository and a file inside it:
(venv) $ mkdir TestRepo-1 (venv) $ cd TestRepo-1/
(venv) $ git init Initialized empty Git repository in
/home/echou/Mastering_Python_
Networking_third_edition/Chapter13/TestRepo-1/.git/ (venv) $ echo "this is my test file" > [Link]
When the repository was initialized with
Git, a new. hidden folder files
It contains was created
related to Git:
.git
(venv) $ ls -a . .. .git
[Link] (venv) $ ls .git/ branches
config description HEAD
hooks info objects refs
Git has a hierarchical configuration that is stored in different
locations. By default, it consists of files system level and global levels, as well as
the same level repositories. The lower the level, the higher its priority. For
example, the repository configuration takes precedence over the global
configuration. To view the aggregated configuration, use the command git
config -l :
$ ls .git/config
.git/config $ ls
~/.gitconfig
/home/echou/.gitconfig $ git config -l
Examples of working with Git 455
[Link]=Eric Chou
[Link]=<email>
[Link]=vim
[Link]=0
[Link]=true [Link]=false
[Link]=true
The file that we created in the repository is not tracked automatically.
You need to add it to the Git system to let it know about it:
$ git status On
branch master
Initial commit Untracked
files:
(use "git add <file>..." to include
in what will be committed)
[Link] nothing added to
commit but untracked files
present (use "git add" to track) $
git add [Link] $ git status On
branch master Initial commit
Changes to be committed: (use
"git rm --cached <file>..." to
unstage) new file: [Link]
The added file is in the intermediate (staged)
state. To make changes final, you need to commit them:
$ git commit -m "adding
[Link]" [master (root-commit) 5f579ab]
adding [Link] 1 file changed,
1 insertion(+) create mode
100644 [Link] $ git status
On branch master nothing
to commit, working directory clean
In the last example, when executing the commit command,
we specified the message accompanying the commit
using the-m parameter. If we omitted this parameter, we
would still have to enter this message, but already in a text
editor. We use the Vim editor to enter the message .
456 Chapter 13: Working with Git
Edit the file and commit it again.
Please note: Git noticed changes in the file:
$ vim [Link] $ cat [Link]
this is the second iteration of my
test file $ git status On branch master
Changes not staged for commit:
(use "git add <file>..." to update
what will be committed) (use "git
checkout -- <file>..." to discard
changes in working directory)
modified: [Link] $ git add [Link]
$ git commit -m "made modifications
to [Link]" [master a3dd3ea]
made modifications to [Link] 1 file
changed, 1 insertion(+), 1 deletion(-)
The commit number in Git is a SHA-1m hash, which is an important
feature. If you perform the same step on another computer, the hash
value will be the same. This means that Git knows that two repositories
are identical, even if they are being worked on in parallel.
If you're wondering if it's possible to change the SHA-1 value accidentally
or intentionally so that it matches a different hash, read an interesting
article about such collisions on the GitHub blog.
[Link] /.
The commit history can be displayed using the command git log .
Entries are displayed in reverse chronological order;
each entry contains the author's name and email
address, date, message, and internal identification number:
(venv) $ git log commit
ff7dc1a40e5603fed552a3403be97addefddc4e9 (HEAD
-> master) Author: Eric Chou <echou@[Link]>
Date: Fri Nov 8 08:49:02 2019 -0800
made modifications to [Link]
commit
5d7c1c8543c8342b689c66f1ac1fa888090ffa34 Author: Eric Chou <echou@[Link]>
Date: Fri Nov 8 08:46:32 2019 -0800
adding [Link]
View details about the change by specifying the commit ID:
(venv) $ git show ff7dc1a40e5603fed552a3403be97addefddc4e9
commit ff7dc1a40e5603fed552a3403be97addefddc4e9 (HEAD -> master)
Examples of working with Git 457
Author: Eric Chou <echou@[Link]>
Date: Fri Nov
8 08:49:02 2019 -0800 made
modifications to [Link] diff
--git a/[Link] b/[Link]
index 6ccb42e..69e7d47
100644 --- a/[Link] +++
b/[Link] @@ -1 +1 @@
-this is my test file +this is the
second iteration of my test file
If you need to undo your changes, you can use one of two
or files to the state, revert
commands:: . The first one brings all
reset in which they were located before a certain commit:
(venv) $ git revert
ff7dc1a40e5603fed552a3403be97addefddc4e9 [master 75921be]
Revert "made modifications to [Link]" 1 file
changed, 1 insertion(+), 1 deletion(-) (venv) $ cat
[Link] this is my test file
performs a new commit without deleting the old one. You will see all of them. revert
changes made so far, including cancellations:
(venv) $ git log commit
75921bedc83039ebaf70c90a3e8d97d65a2ee21d (HEAD -> master)
Author: Eric Chou <echou@[Link]>
Date: Fri Nov 8 09:00:23 2019 -0800
Revert "made modifications to [Link]"
This reverts commit
ff7dc1a40e5603fed552a3403be97addefddc4e9. On branch master
Changes to be committed:
modified: [Link]
rolls back the repository state to an older version and the uda command reset
makes more and more new changes:
(venv) $ git reset --hard ff7dc1a40e5603fed552a3403be97addefddc4e9
HEAD is now at ff7dc1a made modifications to
[Link] (venv) $ git log commit
ff7dc1a40e5603fed552a3403be97addefddc4e9 (HEAD -> master)
Author: Eric Chou <echou@[Link]>
Date: Fri Nov 8 08:49:02 2019 -0800
made modifications to [Link]
458 Chapter 13: Working with Git
commit 5d7c1c8543c8342b689c66f1ac1fa888090ffa34
Author: Eric Chou <echou@[Link]>
Date: Fri Nov 8 08:46:32 2019 -0800
adding [Link]
Personally, I prefer to keep a history of all changes, including
rollbacks. And when I need to undo a change, I usually choose revert Instead of
reset . In this section, you will learn how to work with individual files. Now
let's discuss sets of files grouped
into a package called a branch.
Branches in Git
A branch in Git is a direction of development within a repository.
Git allows you to have many branches and, therefore, develop in
different directions . By default, we have a master branch, master . To create branches
there are many reasons, but there are strict rules when to create
a new branch or when to work only with the main branch, master
does not exist. In most cases-
this branch is created to fix a bug, release a public version of the
software, or start a new development phase. Create a branch that
represents the development process and name it accordingly -
dev:
(venv) $ git
branch dev (venv)
$ git branch
dev * master
Please note: after creating a branch dev we must explicitly switch to it.
There is a command for this :checkout
(venv) $ git
checkout dev Switched
to branch 'dev'
(venv) $ git branch *
dev master
Adding it to the branch dev second file:
(venv) $ echo "my second file" >
[Link] (venv) $ git add [Link] (venv)
$ git commit -m "added [Link] to dev
branch" [dev a537bdc] added [Link]
to dev branch 1 file changed, 1 insertion(+)
create mode 100644 [Link]
Branches in Git 459
We can go back to the branch master and make sure that we now have two on-
development boards. After switching to the branch master it remains in the catalog
one file:
(venv) $ git branch
* dev master (venv)
$ git checkout
master Switched to
branch 'master'
(venv) $ ls
[Link] (venv) $ git checkout
dev Switched
to branch 'dev'
(venv) $ ls [Link]
[Link]
To transfer the contents dev
to the branch , you need to produce with:-master
of the merge branch:
(venv) $ git branch
* dev master (venv)
$ git checkout master
Switched to branch
'master' (venv) $ git
merge dev master
Updating ff7dc1a..a537bdc
Fast-forward
[Link]
| 1 + 1 file changed,
1 insertion(+) create mode
100644 [Link]
(venv) $ git branch
dev * master
(venv) $ ls [Link]
[Link]
You can delete a file using the command git . Let's create a third file and try it out
rm delete:
(venv) $ touch [Link]
(venv) $ git add [Link]
(venv) $ git commit -m "adding
[Link]" [master 169a203]
adding [Link] 1 file
changed, 0 insertions(+), 0
deletions(-) create mode 100644
[Link] (venv) $ ls [Link]
[Link] [Link]
(venv) $ git rm [Link]
rm '[Link]' (venv) $
git status On branch master
460 Chapter 13: Working with Git
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: [Link] (venv) $ git
commit -m "deleted [Link]"
[master 1b24b4e] deleted [Link] 1
file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 [Link]
The last two changes can be seen in the log:
(venv) $ git log commit 1b24b4e95eb0c01cc9a7124dc6ac1ea37d44d51a
(HEAD -> master)
Author: Eric Chou <echou@[Link]>
Date: Fri Nov 8 10:02:45 2019 -0800
deleted [Link]
commit 169a2034fb9844889f5130f0e42bf9c9b7c08b05
Author: Eric Chou <echou@[Link]>
Date: Fri Nov 8 10:00:56 2019 -0800
adding [Link]
We've gone through the basic operations with Git, and
now we'll see how to publish a repository on GitHub.
Example of working with GitHub
In this example, we use GitHub as the center for
syncing our repository and allowing other users to access
[Link]. Create a repository on the GitHub site. For public and
open source projects, this operation has always been free. And
since January 2019 , it has been possible to create an unlimited
number of free private repositories. We will create a private
(Figure 13.1).
repository and add the license and file to it .gitignore
After creating the repository, we will get its URL (Figure 13.2).
Let's use this URL to create a remote goal that will serve
as a" source of truth " for our project. Let's call this goal
gitHubRepo:
(venv) $ git remote add gitHubRepo
[Link] git
(venv) $ git remote -v gitHubRepo [Link]
(fetch) gitHubRepo
[Link] (push)
Branches in Git 461
Figure 13.1. Creating a private GitHub repository
Figure 13.2. URL of the GitHub repository
462 Chapter 13: Working with Git
When creating it, we added the following files: [Link] and , so deletedLICENSE
and the local repositories will be different.
When you try to save changes to the repository, GitHub will report an error:
(venv) $ git push gitHubRepo master
Username for '[Link] <omitted>
Password for '[Link] <omitted>
To [Link]
! [rejected] master -> master (fetch first)
error: failed to push some refs to
'[Link] [Link]'
To prevent this from happening, we will upload new files from GitHub with the command git pull:
(venv) $ git pull gitHubRepo master
Username for '[Link] <omitted>
Password for '[Link] <omitted>
From [Link]
* branch master -> FETCH_HEAD
Merge made by the 'recursive' strategy.
.gitignore | 104
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE |
21 +++++++++++++
[Link] | 2 ++
3 files changed, 127 insertions(+)
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 [Link]
Now you can save our content to GitHub with the command :push
$ git push gitHubRepo master
Username for '[Link] <username>
Password for
'[Link] Counting objects: 15, done. Compressing
objects: 100% (9/9), done. Writing objects:
100% (15/15), 1.51 KiB | 0 bytes/s, done. Total
15 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To [Link]
a001b81..0aa362a master -> master
The current contents of the GitHub
repository can be viewed on the web
page (Figure 13.3). Another user can
simply copy or clone this repository:
[The following actions are performed
on a different host] $ cd /tmp
Branches in Git 463
$ git clone
[Link] Cloning
into 'TestRepo'... remote: Counting objects:
20, done. remote: Compressing objects:
100% (13/13), done. remote: Total 20
(delta 2), reused 15 (delta 1), pack-reused 0
Unpacking objects: 100% (20/20), done. $ cd
TestRepo/ $ ls
LICENSE [Link]
[Link] [Link]
Figure 13.3. GitHub Repository
This copied repository will be identical to the
original, including the history of all commits.:
$ git log commit 0aa362a47782e7714ca946ba852f395083116ce5
(HEAD -> master,
origin/master, origin/HEAD)
Merge: bc078a9 a001b81
Author: Eric Chou <omitted>
Date: Fri Jul 20 14:18:58 2018 -0700
Merge branch 'master' of [Link]
commit a001b816bb75c63237cbc93067dffcc573c05aa2
Author: Eric Chou <omitted>
464 Chapter 13: Working with Git
Date: Fri Jul 20 14:16:30
2018 -0700
Initial commit ...
In the repository settings, you can invite another
person to work together on the project (Figure 13.4).
Figure 13.4. Invitation to the repository
In the following example, you will see how to create a fork and
execute a request to make changes to someone else's repository.
Collaboration using
change requests
As already mentioned, Git supports multiple developers
working together on a single project. Let's see how
this is done when the code is posted on GitHub. We
will use the public GitHub repository for the second
edition of this book. I will be logged in as a different user,
so I won't have administrative privileges. I will click ,Forkto copy a repo-
the log in to your account button (Figure 13.5). It will take
a few seconds to create a copy (Figure 13.6). When
finished, in my account:it contains a copy of the repository (Figure
13.7). You can change the files in the copy by following the
steps we are already familiar with. I'll edit the file
[Link]
. After making changes, you can click New
(New request for changes) (Figure 13.8).
pull request
Branches in Git 465
Figure 13.5. Fork button in GitHub
Figure 13.6. Copy creation process
Figure 13.7. Copy to GitHub
466 Chapter 13: Working with Git
Figure 13.8. Request for changes
Figure 13.9. Details about the change request
When creating a request for changes, you must provide as
much information as possible to justify our changes (Figure 13.9).
Git and Python 467
The repository owner will receive a notification about the request for changes;
if they accept it, the changes will go to the original repository (Figure 13.10).
Figure 13.10. Record of changes made
GitHub provides an excellent platform for
interacting with other developers; it is fast becoming the most
popular choice for large open source projects. Since
Git and GitHub are very widely used, the next logical
step is to automate the processes that we saw in this
section. Let's see how to use Git together with Python.
Git and Python
There are several Python packages that are used
to work with Git and GitHub. In this section, we'll
talk about the GitPython and PyGithub libraries.
GitPython
) We'll take the GitPy
to work with our Git repository. Let's install it and create an
object
Repo in the interactive Python shell. In the same place, we will display a list of all of them
commits to the repository:
468 Chapter 13: Working with Git
(venv) $ pip install gitpython
(venv) $ python >>>
from git import Repo >>> repo =
Repo('/home/echou/Mastering_Python_Networking_
third_edition/Chapter13/TestRepo-1') >>> for commits in
list(repo.iter_commits('master')): ... print(commits) ...
1b24b4e95eb0c01cc9a7124dc6ac1ea37d44d51a
169a2034fb9844889f5130f0e42bf9c9b7c08b05
a537bdcc1648458ce88120ae607b4ddea7fa9637
ff7dc1a40e5603fed552a3403be97addefddc4e9
5d7c1c8543c8342b689c66f1ac1fa888090ffa34
We can also view indexes in the object repo:
>>> for (path, stage), entry in [Link]():
... print(path, stage, entry)
... [Link] 0 100644
69e7d4728965c885180315c0d4c206637b3f6bad 0 [Link]
[Link] 0 100644 75d6370ae31008f683cf18ed086098d05bf0e4dc
0 [Link]
GitPython provides good integration with all Git features,
although it may not be the easiest library for beginners. To work with it
fully, you need to understand the terminology and structure of Git.
But you should keep it in mind: you may need it in other projects.
PyGitHub
Let's see how to use the PyGithub library ( [Link]
io/en/latest/ ) for working with GitHub repositories. This package is a wrapper-
coy around GitHub APIv3, [Link] :
(venv) $ pip install PyGithub
Let's use the interactive Python shell to
display the current user's repository:
(venv) $ python >>> from github import Github
>>> g = Github("<username>", "<password>") >>>
for repo in g.get_user().get_repos(): ...
print([Link]) ... Mastering-Python-Networking-Second-Edition
Mastering-Python-Networking-Third-Edition
Git and Python 469
We can also flexibly manage access to the repository using a special
token. GitHub allows you to assign a set of rights to a token (Figure 13.11).
Figure 13.11. Generating a token in GitHub
If you use an access token as an authentication mechanism,
the output will be slightly different:
>>> from github import Github
>>> g = Github("<token>")
>>> for repo in g.get_user().get_repos():
... print(repo)
... Repository(full_name="oreillymedia/distributed_denial_of_service_ddos")
Repository(full_name="PacktPublishing/-Hands-on-Network-
Programming-with-
Python") Repository(full_name="PacktPublishing/Mastering-Python-Networking")
Repository(full_name="PacktPublishing/Mastering-Python-Networking-Second-
Edition") ...
So, we got acquainted with Git, GitHub, and some
Python packages. Now we can use them for
automation. In the next sectione ras- see examples.
470 Chapter 13: Working with Git
Automating the backup
of configuration files
In this example, we use PyGithub to back up the catalog
that contains the configuration of our router. We already
know how to extract information from our devices
using Python and Ansible; now this information can be
uploaded to GitHub. We have a subdirectory
, which
configs
contains the text configurationsedit-
internal files of our router:
$ ls configs/
iosv-1 iosv-2 $ cat configs/iosv-1
Building
configuration...
Current configuration :
4573 bytes ! ! Last
configuration change at
02:50:05 UTC Sat Jun 2
2018 by cisco ! version
15.6 service timestamps
debug datetime msec ...
Using the script to extract the last index from on-Chapter13_1.py
from our GitHub repository, generate the data that needs
to be recorded, and automatically save the configuration:
#!/usr/bin/env python3
# reference: [Link]
new-files-to-github from github import Github,
InputGitTreeElement import os
github_token = '<token>'
configs_dir = 'configs'
github_repo = 'TestRepo'
# Getting a list of files in
the configs directory file_list = []
for dirpath, dirname, filenames in os. walk(configs_dir):
for f in filenames:
file_list.append(configs_dir + "/" + f)
g = Github(github_token)
repo = g.get_user().get_repo(github_repo)
Automating the backup of configuration files 471
commit_message = 'add configs'
master_ref = repo.get_git_ref('heads/master')
master_sha = master_ref.[Link]
base_tree = repo.get_git_tree(master_sha)
element_list = list()
for entry in file_list:
with open(entry, 'r') as input_file:
data = input_file.read() element
= InputGitTreeElement(entry, '100644', 'blob', data) element_list.append(element)
# Creating a repository
tree and committing changes tree = repo.
create_git_tree(element_list, base_tree) parent
= repo. get_git_commit(master_sha) commit
= repo.create_git_commit(commit_message, tree,
[parent]) master_ref. edit(commit. sha)
A directory has been added to the GitHub repository configs (Figure 13.12).
Figure 13.12. The configs directory
In the change history, you can see the commit that
our script made(Figure 13.13). In the GitHub example
in the previous section, you saw how you can
organize collaboration by creating a copy (fork) of the
repository and executing change requests. Let's talk
about working together using Git in more detail.
472 Chapter 13: Working with Git
Figure 13.13. Change history
Working together using Git
Git is great for collaboration, and GitHub allows
developers to work effectively on shared projects. Anyone
with internet access can share their thoughts and code.
We already know how to use Git and organize simple
interaction on GitHub, but how do we join an existing
project? We certainly want to reciprocate the open
projects that have been so useful to us. But where to
start? In this section, we'll look at some aspects of
collaborative development using Git and GitHub.
z Start small. The first and most important thing is to understand
your role in the code. You may be an amazing network engineer,
but you're only a mediocre Python programmer. There are many
cases that do not require special programming skills. Don't be
afraid to start small; documentation and testing are the areas
that will allow you to make your first contribution to the project.
Explore the ecosystem. Any project, large or small, has a set
z of generally accepted norms and a well-established culture.
The Python language attracts us with its clear syntax and
beginner-friendliness; there is even a developer's guide
based on this idea on its website (
[Link]
). The Ansible project also has a manual
for potential community members (
latest/community/[Link] [Link]
). It describes the code of conduct, the process of
Rezyume 473
submission of change requests, the procedure for creating bug
reports, and how new versions are released. Check out these guides
and explore the ecosystem of the project you are interested in.
z Create branches. I once created a fork of a project by mistake
and submitted a request for changes to the master branch. The
main branch is intended for making changes by the main project
participants. We need to create separate branches for our edits
so that they can be merged into the main one later.
Sync your copy of the repository. There is no rule that forces us
z
to synchronize the cloned repository with the original one. But
to ensure that we always have the most up-to-date copy of the
main repository, we must regularly perform the following tasks: git
pull (to get
the code and merge it with the local copy) or git fetch (to get a lo-
copy with all changes).
z Be friendly. In the virtual world, as in the real world, there is no
place for hostility. When discussing a problem, be polite and
friendly, even if you have disagreements.
Git and GitHub allow anyone who cares to contribute,
making it easier to collaborate on projects. We can participate in the
development of any open and closed projects that interest us.
Resume
In this chapter, we looked at a version control system called Git
and its close relative GitHub. The Git project was created in 2005 by
Linus Torvalds to facilitate the development of the Linux kernel;
many other open source projects later adopted it. Git is very fast,
distributed, and scalable. GitHub provides a centralized location for
hosting Git repositories and allows you to collaborate with
[Link] you to everyone who has an internet connection. You've seen
how Git can be used on the command line, and you've learned about
various operations and how they are applied on GitHub. You also
got acquainted with two popular Python libraries for working with
Git: GitPython and PyGithub. At the end of the chapter, we looked
at an example of backing up a configuration and some notes about
working together. Chapter 14 discusses Jenkins , another popular
open source tool for continuous integration and deployment.