Basic Git Guide

As a Network Engineer, my development workflows are not very disciplined or strong. I mainly use Git as a place to store my completed work, in the form of GitHub. This does work, however, I am missing out on many very useful features that Git version control has to offer and any collaboration with a team larger than just myself.

Here, I am going to outline basic Git usage and GitHub integration. Once these two things are completed, it is nice and easy to use Git in Visual Studio Code.

Quick Command Reference

nformational commands:

Change commands:

Note: Some commands, like git addgit commitgit merge, and git reset, require additional arguments or options to work properly.

Basic Git Commands

Git Status

git status is used to display the current git repository status. Nothing here.

Git Init

git init will initialise a new git repository in that current directory location.

Now that a new repository has been created, the git status command can be rerun to see the difference.

The git init command has created a hidden directory .git. This is what Git uses to store all the files that are being tracked. If deleted, all the version control performed has been lost, hence the reason it is hidden.

Do not run git init inside a repo that you have already created. Git will be then tracking changes of the original .git directory in the new .git directory. This will eventually cause issues. Use a single git repository per project.

Now that git has been initialised, there are no files for it to keep track of. This is the role of git add and git commit.

I’ll create a new file in my gitTest directory. Git has recognised a new file, but is warning that this is an untracked file and to use git add to track it.

When adding a file to Git, this is a staging area. This is where Git knows about a file or multiple files, but has not tracked any changes made in them yet. If there are ten files in my gitTest directory, I can add as many or a few as required. After they have been added I can use git commit which will start to track the changes made in the files.

I have added multiple new files to the directory, however only added a single file for Git to track.

Git Add

Multiple files can be added got git add in a single line. The remaining two files will be added to the staging area. Nothing has been committed yet, and therefore not tracked.

Git Commit

Before any files are committed, it is a good idea to write a message to describe the changes made for the group of files that are being committed. To do this, the command git commit -m "commit message goes here" is used.

The command git commit can be used without any flags, this will then open up the default text editor for the user to enter the commit message. It is easier to use the -m flag.

Committing the files shows the results, three files have changed. It is best practice to keep the commits focussed on specific changes. This can be handled by using git add for only a select number of files that are part of the change you want to commit. This way, the commit message relates to the actual changes that were made. This approach is useful when wanting to go back to earlier versions. Only the work that needs to be undone is undone. This practice is known as Atomic Commits.

git status now shows that there is nothing to do, the files are upto date and committed. The working tree is clean.

If any of the files were to be modified, then the working tree would not be clean as the file has been changed and Git will be aware. I have added a line to the bgp1.cfg file. git status is now reporting that this file has changed.

This is where the process starts to repeat itself. The changes need to be added to the staging environment, and then committed.

If there were multiple files that were changed and need to be added, a quick way is to use git add ., this will add all the files in the current directory. It is better to be specific, as maybe you only want to commit files with different messages. That is possible, by specifying the files with git add file1 and then committing them with git commit -m "message for specific files".

For larger projects, commit messages can be large and detailed. The -m flag makes it difficult to write a long and detailed commit message, or add any sort of formatting to it. This is where using just git commit is useful. git commit will open up the default text editor for Git and allow you to write a message.

By default, in MacOS the commit message that opens is vi. This can be difficult to use, however it can be changed from default. Git has a reference for multiple different text editors. I will modify this to use Sublime.

Git Log

There is a way to view the committed files to Git using git log. This will display the details of the commit such as; the commit hash, author, date, and commit message.

The git log output is not exactly user-friendly, and if there is a very large commit message, then it will display a large section of it. This reduces the readability of the log even further. A good way to improve this is to use the --oneline flag.

Amending Commits

If any mistakes were made in the git commit message or files were not added using git add and then committed, this can be fixed using git amend.

Below I have made changes to all three .cfg files, however only added and then committed two of them. But I want to add the third file anyconnectvpn1.cfg using the same commit.

This method will only work for the last commit. If nothing else has been committed, then it’s OK.
The forgotten file anyconnectvpn1.cfg

Using git commit --amend has opened the last commit file in the text editor, which is Sublime for me. Here is where any mistakes made in the last commit message can be fixed and for this example the file anyconnectvpn1.cfg will be committed.

After saving the commit file, Git has added in the file to the same commit it was missed off before. This can be reviewed in the log using git log -oneline to view the commit messages.

Git Ignore

This is a hidden file created by the user and added to the repository root, it will contain a list of files that are not to be tracked by Git. The list of files could be sensitive files such as API keys, credentials, or it could be output files such as logs from the application or script, or it could even be dependencies or packages that the application created is using. Anything that is either sensitive, not applicable or can easily be recreated. Even entire directories can be ignored and not just specific files.

Branches

Every Git repository has a master branch by default. A new branch can be added as an alternative timeline without impacting other branches. Branches are used to work on an aspect of the project without impacting the current code base. This could be to add a new feature or a fix a bug. The separate branches can be merged back into the master branch. So a bug can be fixed in a separate branch and then merged back in to the master branch.
There can be multiple branches of work going on at the same time without any impacting the other.

In git log there is a line specifying (HEAD -> master). Head is always referring to the latest commit on the branch that you are looking at. So switching from the master branch to a different user’s branch, HEAD would be pointing to that user’s branches latest commit.

To view the branches, use the command git branches. If there were more branches, the * would point tot the one currently in use.

I have created a new branch with the git branch command. This will only create the branch and not switch to it.

Right now both branches, the master and the bugfix branch are pointing to the same last commit, this can be seen in git log --oneline.

To switch into the new branch git switch <branch-name> is used. Here it shows that the commits are the same for each branch.

Next I will add some more lines to the networkconfig1.cfg file and commit this file. This new change that has added in a default route will only be available for the bugfix branch.

The git log --oneline shows the commits where the bugfix and the master branches are upto. If a new branch was to be created, from either the master or the bugfix the log would show another branch and that would be shown as commits were made.

When switching from branch to branch, the file will be updated with those changes made in the branch.

git switch can will only create the new branch, but not switch into it. To switch into the new branch when creating use git switch -c

Switching branches with changes that have not yet been committed will result in an error message. There is an option to use git stash that will save what is half completed work. Documentation can be found here.

Git Checkout vs Git Switch

git switch is the newer way to switch between branches, the older method was git checkout. The checkout command does more than just switch between branches, hence the reason to create a new command only for switching between branches. Any documentation that references git checkout the new command git switch can be used.

Deleting and Renaming Branches

Deleting a branch. In this example, I have created a new branch called deleteMe, git switch -c deleteMe.
Unable to delete when on the branch deleteMe

Move to the Master branch, and delete again. However, this time it complains that the deleteMe branch is not fully merged. This is because for the new branch deleteMe, nothing has been committed. To delete, the uppercase D flag must be used, as the error message advises.

To rename a branch, the flag is similar to the Linux command to rename something using the move mv command. In Git, the -m flag is used. To rename you must be on the branch, unlike to delete where you cannot be on the branch.

Merging Branches

Before going into the specifics of how to merge a branch, I think it is important to understand how it is used. The Master branch should be the branch with the working and most upto date version on it. Any new features or fixes should be separate branches. When these new features are complete or the bugs fixed, these branches are merged back to the Master branch, adding new completed work to it. This is a simplified version, but it helps get things straight as to how branches can be used. This is knows as a fast-forward merge.

To perform a merge from newfeature to Master switch into Master and run git merge newfeature. This will move the latest Master commit to reference the latest newfeature commit.

There are issues with merging when work has continued on the Master branch while the newfeature branch was being worked on. So in this case, say a bug was found in the Master just after the newfeature branch had been added. A third branch was created called bugfix, this work was completed and merged back to Master before the newfeature was completed. Leaving the original bug still inside the newfeature branches code.

Merge Types – Fast Forward

A fast-forward merge is the most common type of merge and very simple. This occurs when both the master and feature branch has the same commit history.

For example, say the master branch has had 7 commits. A new feature branch has been created, this branch has had some changes. The new feature branch is then to be merged into the master branch. The commit history of both the master and feature branches are the same, except for the new commit on the feature branch. All that will happen is the marker for the master branch is moved upto include the feature branch. The marker moves forward, hence fast-forward.

Merge Types – Merge Commit No Conflicts

This type of merge has two or more parent commits from different branches. There won’t be any merge conflicts and Git can still automatically merge the branches.

In the diagram below, there are two branches, Master and Feature. Feature is a branch from Master, but since the Feature branch was created, there have been other commits to the Master branch. In this example, there won’t be any conflicts which would mean changes to the same line. This will be additional lines or files.

Merge Types – Merge Commit Conflicts

Git will try to automatically merge branches, and in the previous examples it has been able to do that. If there is a conflict, Git won’t know what to and won’t merge automatically. A conflict will be something like changes to the same line of the same file in the branches being merged. Or the deletion of a file on one branch but additional changes to that same file on another.
Git will recognise the conflict and will ask the user what to do.

Git will have a file containing conflict markers that show where the conflicts are and in which branches. All the user needs to do is delete what they don’t want and delete the conflict markers and save. The tree of the commits/merges will look the same as the previous diagram.

In VSCode the merge conflict message has been displayed and the file to manually amend are shown.

To amend, all I do is select what needs to stay and what can be deleted. This is the file bgp1.cfg. I will keep the change from master and not from the newfeature branch.

Commit the result of the manual merge.

Rebase Before Merging

Rebasing is generally used to keep a feature branch upto date with any new commits to the master branch. Rebasing the feature branch adds in any changes to the master to the feature branch. This should be done before merging the feature to the master branch. If this isn’t done, we will be merging in the new feature and also old files.

The process is straightforward

  • Switch to the master branch
  • Pull the latest changes to the repo
  • Switch back to the feature branch
  • Rebase the master branch onto the feature branch

Git Diff

Used to show the differences or changes between;

  • Viewing changes between commits
  • Inspecting changes in the working directory
  • Comparing branches
  • Viewing changes within a specific file
  • Showing changes introduced by a commit

Viewing Changes Between Commits

You can compare different commits to see what changes were made.

Make some changes and commit them.

Git log to show the commits.

Use git diff commitA commitB to see the differences.

Inspecting Changes in the Working Directory

Git will display the modifications that have been made to tracked files in your working directory compared to the most recent commit.
To do this, use git diff.

Comparing Branches

You can use git diff branchA branchB to compare the differences between two branches.

Viewing Changes Within a Specific File

Showing Changes Introduced by a Commit

Allows you to examine the changes made in a particular commit compared to its parent commit.

Git Revert, Git Reset

There are two Git commands to undo changes made after a commit Git Revert and Git Reset.

Git Revert will revert the changes, keeping the history in the git log. The command creates a new commit that undoes the changes made in a previous commit. This approach is recommended when you want to keep a record of the rollback in the commit history.

Git reset allows you to move the branch pointer to a specific commit, discarding the commits that come after it. This approach is more aggressive as it removes commits from the commit history, use carefully.

Git Command Reference

nformational commands:

Change commands:

Note: Some commands, like git addgit commitgit merge, and git reset, require additional arguments or options to work properly.

GitHub

Generate an SSH Key for GitHub & Clone Private Repo

I have used this as the repo I was using at the time was private. Another good learning exercise.

Generate an SSH key pair

The email must be your GitHub email.

Add your SSH key to your GitHub account, copy the key first.

Open your GitHub account settings in a web browser, go to “SSH and GPG keys”, and click on “New SSH key”. Paste the copied public key into the “Key” field and give it a descriptive title.

Install Git

Clone Private Repo

Creating a Repo in GitHub and Adding Files

To create a new or push and existing repo to GitHub, it all starts with creating a repo in GitHub.

If you need to initialise the local repo

Setup GitHub account and add the remote repository. An SSH key needs to be setup for this to work. Username and password will no longer work.

Check it is all correct

I’m going to push a new new branch called uploadbranch

Leave a Comment

Your email address will not be published. Required fields are marked *