NetDevOps

Git for Network Engineers

Git for Network Engineers
In: NetDevOps

As Network Engineers, we work with various text files such as network device configurations, scripts, and text-based documentation. Managing these files can become complex as we make changes, collaborate with teammates, and need to maintain multiple versions. Git provides an efficient solution to keep our files organized and easily accessible. Think of Git as a powerful organizer and version control system for all your text files - network configurations included.

With Git, you can effortlessly track changes, share your work with others, and quickly revert to previous versions of your files without maintaining countless copies.

Audience

This blog post is tailored for absolute beginners who have never used Git before, specifically network engineers seeking to simplify their work with text files, including network device configurations or scripts. If you're new to Git and eager to learn how to harness its power to manage and collaborate on your files, you've come to the right place

💡
The examples provided in this blog don't require any third-party services such as Github, as all operations are performed locally on your computer. As you become more comfortable with Git and want to collaborate with others or share your repositories online, you can then consider using services like GitHub, GitLab, or Bitbucket to enhance your workflow.

Basic Git Fundamentals

Think of Git as a powerful tool that helps you manage and organize all your files, like essays, projects, and code. Whenever you make changes or updates to your work, Git can create a snapshot of your progress, similar to saving your progress in a video game. If you need to undo a change or revert to a previous version, Git allows you to do that quickly and easily.

Git enables you to work with multiple versions of your files simultaneously using branches. You can create separate branches for new ideas or experimental changes without affecting your main work, making it simple to switch between different versions.

Here are some basic Git concepts you should know:

  1. Repository - A place where your project files and their history are stored.
  2. Branch - A separate line of development within a repository. You can work on different features or configurations independently.
  3. Commit - A snapshot of your changes, similar to a save point in a video game.
  4. Merge - The process of combining changes from one branch into another.

Git Stages

The stages of Git refer to the different states your files can be in during the version control process. There are three main stages:

  1. Modified (Working Directory) - The modified stage represents files in your working directory that have been changed but not yet staged. This is where you edit, add, or delete files in your project.
  2. Staged (Staging Area) - The staged stage is an intermediate area where you add changes from the working directory before committing them to the repository. By staging changes, you can selectively group related modifications together into a single commit, ensuring a well-organized project history.
  3. Committed - The committed stage represents the changes that have been added to the repository's history after being staged and committed. Each commit has a unique identifier (hash), which allows Git to track the entire project's history and provides the ability to revert or compare changes between different commits.

Consider the three stages of Git files like building a LEGO model. The working directory represents selecting and sorting LEGO pieces, the staging area is like carefully positioning the pieces together, and the commit signifies securely snapping them into place to create the final structure.

Time for Action: Jump Into an Example

Learning by doing is the most effective approach, so let's put the theory aside and dive straight into a hands-on example. This will illustrate using Git to organize your files and easily navigate different versions. Ready? Let's get started!

Git Installation

Before we start, please note that installing Git is not covered in this post, as there are hundreds of helpful videos and articles available to guide you through the process. To learn how to install Git on your system, you can check out this comprehensive resource: Git Installation Guide. Once you have Git installed, come back here, and we'll continue our hands-on learning journey together.

After installing Git, configure your Git username and email, Git uses your username and email to associate your commits with your identity. Set them up using the following commands.

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"

To ensure your Git configuration is set up correctly, you can use git config--list command to view your settings.

Create Repo, Stage Changes, Commit

Throughout this example, we will be working with the following file. The ultimate goal for us is to use Git to track our changes and revert if required. For brevity, I'm just using a few lines of the config.

interface GigabitEthernet0/0
 nameif WAN
 security-level 0
 ip address 201.85.10.1 255.255.255.248 standby 201.85.10.2 
!
interface GigabitEthernet0/1
 nameif INSIDE
 security-level 100
 ip address 192.168.10.1 255.255.255.0 standby 192.168.10.2
 
 route WAN 0.0.0.0 0.0.0.0 201.85.10.6 1

tunnel-group 101.85.10.1 type ipsec-l2l
tunnel-group 101.85.10.1 general-attributes
 default-group-policy VPN-LAB-GP
 
tunnel-group 101.85.10.1 ipsec-attributes
 ikev2 remote-authentication pre-shared-key Cisco123
 ikev2 local-authentication pre-shared-key Cisco123

1. Directory and File

I've created a folder/directory called git_training for this example and added the above configuration file into it.

suresh@mac:~/git_training|⇒  ls
asa_config.cfg

2. Create a Git Repository

Creating a Git repository is the initial step in using Git for managing your files and version control. A Git repository, or repo, is a storage space that contains all the files, their history, and the changes made to them.

To Initialize a new Git repository, navigate to your project folder git_training and run git init command. This command creates a hidden .git folder in the project directory, which will store all the information related to the repository, including the commit history, branches, and configuration settings.

suresh@mac:~/git_training|⇒  git init
Initialized empty Git repository in /git_training/.git/

After running this command, you should see a message saying "Initialized empty Git repository" followed by the path to the .git folder.

And that's it! You have successfully created a Git repository in your project folder. Now you can start adding files, making commits, and tracking changes using various Git commands.

3. Staging Files

The git add command is used to stage changes you've made to files in your project, preparing them for a commit. In this case, you want to stage the new asa_config.cfg file, which means you are telling Git to track the changes made to this file and include them in your next commit.

As we already created the asa_config.cfg file with the necessary content, we can stage it using the git add command followed by the file name.

git add asa_config.cfg

To check if your file has been staged correctly, you can use the git status command. It will show you the current state of your repository and the changes that have been staged.

suresh@mac:~/git_training|master⚡ ⇒  git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   asa_config.cfg

4. Git commit

The git commit command is used to create a snapshot of the changes you've made to files in your Git repository. These snapshots, called commits, represent different versions of your project and become part of the repository's history, allowing you to track changes and revert to previous versions if necessary.

After staging the changes, you can create a commit with the git commit command. A commit represents a snapshot of the staged changes and includes a unique identifier called a commit hash. It's a good practice to provide a descriptive commit message that briefly explains the changes you've made. To create a commit with a message, use the -m flag followed by your message in quotes.

suresh@mac:~/git_training|master⚡ ⇒  git commit -m "Add initial asa_config.cfg file"

[master (root-commit) 74b19ad] Add initial asa_config.cfg file
 1 file changed, 19 insertions(+)
 create mode 100644 asa_config.cfg

Now you've successfully created your first commit after staging a file! As a beginner, it's essential to understand the commit process, as it forms the foundation of Git's version control capabilities. As you work on your project, remember to commit your changes regularly to keep an accurate and organized history of your progress.

Making Changes

1. Git Branches

In Git, a branch is like a parallel workspace that allows you to work on different features or tasks without affecting the main codebase. Think of branches as separate lanes in a highway, where each lane represents a different version of your project. Branches are incredibly useful for isolating changes and ensuring that the main code remains stable and functional. Once the work on the branch is complete and tested, you can merge it back into the main codebase, effectively integrating your changes.

For this example, let's say we want to change the PSK (pre-shared-key) of the VPN config. Please note that in the examples provided throughout this post, we're just changing a single word or a few lines of the file for simplicity. However, in real-life scenarios, you would typically be editing multiple lines across multiple files in your project. Git is designed to handle these more complex situations efficiently, helping you manage changes and collaborate effectively with your team.

2. Make the first change

The git checkout -b command is used to create a new branch and switch to it in one step. Let's create a new branch called psk and make the changes (Lines #18-19)

suresh@mac:~/git_training|master ⇒  git checkout -b psk
Switched to a new branch 'psk'
interface GigabitEthernet0/0
 nameif WAN
 security-level 0
 ip address 201.85.10.1 255.255.255.248 standby 201.85.10.2 
!
interface GigabitEthernet0/1
 nameif INSIDE
 security-level 100
 ip address 192.168.10.1 255.255.255.0 standby 192.168.10.2
 
 route WAN 0.0.0.0 0.0.0.0 201.85.10.6 1

tunnel-group 101.85.10.1 type ipsec-l2l
tunnel-group 101.85.10.1 general-attributes
 default-group-policy VPN-LAB-GP
 
tunnel-group 101.85.10.1 ipsec-attributes
 ikev2 remote-authentication pre-shared-key newpsk
 ikev2 local-authentication pre-shared-key newpsk

If you check the git status now, you see that git says that a file has been modified but not staged.

suresh@mac:~/git_training|psk ⇒  git status
On branch psk
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   asa_config.cfg

no changes added to commit (use "git add" and/or "git commit -a")

4. Git diff

By using git diff, you can review the changes you've made before staging or committing them, ensuring you only include the intended changes. This command helps you keep track of your work and maintain a clean project history by providing a clear, line-by-line comparison of the changes made.

diff --git a/asa_config.cfg b/asa_config.cfg
index b53b10e..1fbeb12 100644
--- a/asa_config.cfg
+++ b/asa_config.cfg
@@ -15,5 +15,5 @@ tunnel-group 101.85.10.1 general-attributes
  default-group-policy VPN-LAB-GP
  
 tunnel-group 101.85.10.1 ipsec-attributes
- ikev2 remote-authentication pre-shared-key Cisco123
- ikev2 local-authentication pre-shared-key Cisco123
\ No newline at end of file
+ ikev2 remote-authentication pre-shared-key newpsk
+ ikev2 local-authentication pre-shared-key newpsk
\ No newline at end of file

5. Git add / Git commit

Just like we previously did, stage the change and commit the changes.

suresh@mac:~/git_training|psk⚡ ⇒  git add asa_config.cfg

suresh@mac:~/git_training|psk⚡ ⇒  git commit -m "changed psk"
[psk 1b49f91] changed psk
 1 file changed, 2 insertions(+), 2 deletions(-)

6. Switching between branches

To switch between the master branch and your branch, use the git checkout command followed by the branch name. For example, to switch back to the master branch, you can use the following.

git checkout master #switch to 'master' branch
git checkout psk #switch to your own branch 'psk'

When you switch to master, the PSKs will change back to how it was before - Cisco123

When you switch back to your feature-branch psk, the PSK will change to newpsk. How cool is it?

Switching between branches using git checkout does not result in data loss as long as you have committed your changes before switching. Git keeps track of each branch's history and updates your working directory to match the selected branch. This ensures that your work on different branches remains separate and safe, allowing you to switch between branches without losing any data.

Merging your Changes

The git merge command is used to combine the changes made in one branch into another branch. When you're satisfied with the changes you've made in your branch and have tested them thoroughly, you can merge them into the master branch to integrate your work into the main codebase.

To merge your branch psk into the master branch, follow these steps.

Switch to the master branch

suresh@mac:~/git_training|psk ⇒  git checkout master
Switched to branch 'master'

Merge the psk branch into the master branch

suresh@mac:~/git_training|master ⇒  git merge psk
Updating 74b19ad..1b49f91
Fast-forward
 asa_config.cfg | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Git will attempt to automatically merge the changes from psk into master. If there are no conflicts between the branches, the merge will be successful, and your changes will be integrated into the master branch.

Once your branch has been successfully merged into the master branch, and you're certain that you no longer need it, you can delete the branch to keep your repository clean and organized. To delete a local branch, use the git branch command with the -d option.

suresh@mac:~/git_training|master ⇒  git branch -d psk
Deleted branch psk (was 1b49f91)
💡
Remember to only delete branches that you're sure you no longer need, as this action is irreversible.

Discarding and Reverting Git Changes - Undo with Ease

One of the great advantages of using Git is its ability to help you manage your project's history and easily undo changes when needed. With Git, you can discard or revert changes at various stages, be it in the working directory, the staging area, or even after committing. This flexibility allows you to experiment, make mistakes, and learn without fear of losing your work or damaging the main codebase.

Git provides commands such as git restore, git reset, and git revert to help you navigate your project history, making it simple to undo changes and maintain a clean, organized repository.

1. Discarding unstaged changes

Please note that an unstaged change refers to modifications made to a file in the working directory that has not been added to the staging area for the next commit. (aka, the file is in modified stage)

For the subsequent examples, let's create a new branch called vpn

suresh@mac:~/git_training|master ⇒  git checkout -b vpn
Switched to a new branch 'vpn'

Let's go ahead and make a mess of that config file and see how easily you can revert the changes.

diff --git a/asa_config.cfg b/asa_config.cfg
index 1fbeb12..b19743f 100644
--- a/asa_config.cfg
+++ b/asa_config.cfg
@@ -4,16 +4,17 @@ interface GigabitEthernet0/0
  ip address 201.85.10.1 255.255.255.248 standby 201.85.10.2 
 !
 interface GigabitEthernet0/1
- nameif INSIDE
  security-level 100
  ip address 192.168.10.1 255.255.255.0 standby 192.168.10.2
  
- route WAN 0.0.0.0 0.0.0.0 201.85.10.6 1
+route WAN 2.2.2.2 0.0.0.0 201.85.10.6 1
 
 tunnel-group 101.85.10.1 type ipsec-l2l
 tunnel-group 101.85.10.1 general-attributes
- default-group-policy VPN-LAB-GP
+ default-group-policy changedit
  
 tunnel-group 101.85.10.1 ipsec-attributes
- ikev2 remote-authentication pre-shared-key newpsk
- ikev2 local-authentication pre-shared-key newpsk
\ No newline at end of file
+ ikev2 remote-authentication pre-shared-key wrong-psk
+ ikev2 local-authentication pre-shared-key newpsk
+
+aaa authentication
\ No newline at end of file

I made a few changes, saved the file, went on a break, come back and realised that I messed up the changes and want to revert back. Traditionally, you will need to CTRL+Z a few times to go back in time but with git, you only need a single command.

$ git restore asa_config.cfg

This will revert the file to the state of the last commit, effectively discarding any unstaged changes made to it.

2. Discarding staged changes

Let's look at an example where you've staged your changes (aka, the file is in the staged stage)

To discard staged changes that haven't been committed yet, you can use the git restore command with the --staged option. This command will unstage the changes, effectively moving them back to your working directory without actually discarding the modifications themselves.

$ git restore --staged asa_config.cfg

3. Discarding committed changes with Git revert

In this example, we will demonstrate how to discard committed changes that have not yet been merged with the master branch. Let's say we made some changes to the vpn branch and committed them, but later realized that there was a mistake. Now, you want to undo that commit to correct the error before merging the changes with the master branch.

For this example, I modified the next-hop with the wrong IP and committed the changes. (Please note that we haven't merged these changes to the master)

diff --git a/asa_config.cfg b/asa_config.cfg
index 1fbeb12..168f79f 100644
--- a/asa_config.cfg
+++ b/asa_config.cfg
@@ -8,7 +8,7 @@ interface GigabitEthernet0/1
  security-level 100
  ip address 192.168.10.1 255.255.255.0 standby 192.168.10.2
  
- route WAN 0.0.0.0 0.0.0.0 201.85.10.6 1
+ route WAN 0.0.0.0 0.0.0.0 201.85.10.10 1
 
 tunnel-group 101.85.10.1 type ipsec-l2l
 tunnel-group 101.85.10.1 general-attributes

git revert is a command in Git that allows you to undo the changes made in a specific commit by creating a new commit with the exact opposite changes. Instead of modifying the existing commit history, git revert adds a new commit that reverses the effects of the target commit.

First, make sure we are on the vpn branch. Now, we need to find the commit hash of the commit you want to undo. You can use the git log command to view the commit history.

commit 7eef73f2bfa1c828ded67d96ee091e69becd7502 (HEAD -> vpn)
Author: suresh <suresh@example.com>
Date:   Sun Apr 9 10:54:00 2023 +0100

    changed next-hop

commit 1b49f9127b7f4c2b4d300245f866fb903288fe5c (master)
Author: suresh <suresh@example.com>
Date:   Sun Apr 9 10:13:59 2023 +0100

    changed psk

commit 74b19adcf697f896cf5e3b216a173fcda1f2e9e8
Author: suresh <suresh@example.com>
Date:   Sat Apr 8 21:20:13 2023 +0100

    Add initial asa_config.cfg file

Locate the commit we want to revert and note its hash (The commit you want to discard) 7eef73f2bfa1c828ded67d96ee091e69becd7502

suresh@mac:~/git_training|vpn ⇒  git revert 7eef73f2bfa1c828ded67d96ee091e69becd7502
[vpn 243b9d8] Revert "changed next-hop"
 1 file changed, 1 insertion(+), 1 deletion(-)

Git will prompt you to enter a commit message for the new commit. Save and exit the text editor. Git will then create a new commit that reverses the changes made in the specified commit.

Revert "changed next-hop"

This reverts commit 7eef73f2bfa1c828ded67d96ee091e69becd7502.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch vpn
# Changes to be committed:
#       modified:   asa_config.cfg
#
reverting_next-hop

After using git revert, the commit history remains intact, and a new commit is added on top of the existing history as shown below.

commit 243b9d8621b6343c1aea1d1c505d4f78f9f531f2 (HEAD -> vpn)
Author: suresh <suresh@example.com>
Date:   Sun Apr 9 12:13:22 2023 +0100

    Revert "changed next-hop"
    
    This reverts commit 7eef73f2bfa1c828ded67d96ee091e69becd7502.
    
    reverting_next-hop

commit 7eef73f2bfa1c828ded67d96ee091e69becd7502
Author: suresh <suresh@example.com>
Date:   Sun Apr 9 10:54:00 2023 +0100

    changed next-hop

commit 1b49f9127b7f4c2b4d300245f866fb903288fe5c (master)
Author: suresh <suresh@example.com>
Date:   Sun Apr 9 10:13:59 2023 +0100

    changed psk

commit 74b19adcf697f896cf5e3b216a173fcda1f2e9e8
Author: suresh <suresh@example.com>
Date:   Sat Apr 8 21:20:13 2023 +0100

    Add initial asa_config.cfg file

4. Git reset

To discard the committed changes, you can also use (very carefully) the git reset command. This command moves the current branch pointer to the specified commit, essentially "going back in time."

With Git reset we need to provide the commit hash of the commit you want to go back to, and all the commits after the specified commit will be removed from the branch history.

Please note you don't need to pass the full commit hash, you can find the shorter version of the hash commit using git log --oneline

Please remember we've changed the next-hop as part of the commit 7eef73f and now we want to discard that changes and go back to the commit 1b49f91

suresh@mac:~/git_training|vpn ⇒  git log --oneline

7eef73f changed next-hop
1b49f91 (master) changed psk   << WE WANT TO GO BACK HERE
74b19ad Add initial asa_config.cfg file

You have a few options here, depending on how you want to proceed.

1. To uncommit the changes and move them back to the staging area, use the --soft option

$ git reset --soft 1b49f91^

2. To uncommit the changes and move them back to the working directory, use the --mixed option (this is the default behaviour when no option is specified)

$ git reset --mixed 1b49f91^

3. To discard the changes completely, use the --hard option

$ git reset --hard 1b49f91^

The ^ symbol indicates the parent of the specified commit, effectively moving the branch pointer one step back in history.

Let's go with option-3 and see what happens to the commit history.

suresh@mac:~/git_training|vpn ⇒  git reset --hard 1b49f91
HEAD is now at 1b49f91 changed psk
$ git log --oneline

1b49f91 (HEAD -> vpn, master) changed psk
74b19ad Add initial asa_config.cfg file

Just like that, the commit disappeared from history - like it never happened.

5. Git reset vs Git revert

Choosing between git reset and git revert depends on your specific use case, the nature of the changes, and the context of the repository. Generally, use git reset for local, private changes where rewriting commit history is not an issue and use git revert when dealing with shared repositories or situations where maintaining the commit history is important.

Git Command Summary

Here's a short summary of the Git commands we covered in this blog post:

  1. git init - Initializes an empty Git repository in the current directory.
  2. git add FILE - Adds a file (or changes within a file) to the staging area, preparing it for the next commit.
  3. git commit -m "MESSAGE" - Commits the staged changes, creating a new snapshot of the repository with a descriptive message.
  4. git checkout -b BRANCH_NAME - Creates a new branch and switches to it.
  5. git checkout BRANCH_NAME - Switches to an existing branch.
  6. git diff - Shows the differences between the working directory and the last commit.
  7. git status - Displays the status of your working directory, showing staged, unstaged, and untracked files.
  8. git restore --staged FILE - Unstages a staged file but keeps the changes in the working directory.
  9. git restore FILE - Discards unstaged changes in a file.
  10. git log - Displays the commit history in the current branch.
  11. git revert COMMIT_HASH - Reverts the changes made in a specific commit by creating a new commit with the opposite changes, without modifying the existing commit history.
  12. git reset FILE - Unstages a staged file, moving it back to the working directory.
  13. git merge BRANCH_NAME - Merges the changes from the specified branch into the current branch.

Conclusion

In conclusion, this post on Git for Network Engineers has provided you with the essential knowledge to start using Git in your day-to-day work. As a network engineer, you now have the foundation to confidently begin integrating Git into your projects, allowing you to track changes and collaborate more efficiently.

Remember, the best way to learn is to practice, so start using Git with your own projects and continue expanding your understanding as you go. If you have any comments or feedback, please feel free to share your thoughts in the comments section below. Happy coding!

Written by
Suresh Vina
Tech enthusiast sharing Networking, Cloud & Automation insights. Join me in a welcoming space to learn & grow with simplicity and practicality.
Comments
More from Packetswitch
Table of Contents
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Packetswitch.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.