Thursday, October 22, 2020

1.7 Version Control with Git

 Git, created by Linus Torvalds in 2005, is an example of a version control system. Torvalds also is the creator of the Linux operating system, so the history of Git is closely connected to Linux as well. In fact, when Linux was first being developed, Torvalds and his team struggled with managing large codebases maintained by many engineers.

The system is distributed, providing the capability for every team member to interact with each other. While a central repository can still be used, every team member has their own copy of the project files. This copy is a complete copy of the full project, not just the files being worked on. Changes made by one developer may be incompatible with changes made by some other developer. Git helps track every individual change by each contributor to prevent work from conflicting.

Moreover, you have full control of your local repository, so you may decide to commit and push only some parts of your work and leave some others on your local system. This practice may be the case of a file containing confidential data, credentials, and so on.

Git architecture is composed of several different components:

  • Remote repository: A remote repository is where the files of the project reside, and it is also from where all other local copies are pulled. It can be stored on an internal private server or hosted on a public repository such as GitHub, GitLab, or BitBucket.

  • Local repository: A local repository is where snapshots, or commits, are stored on the local machine of each individual.

  • Staging area: The staging area is where all the changes you actually want to perform are placed. You, as a project member, decide which files Git should track.

  • Working directory: A working directory is a directory that is controlled by Git. Git will track differences between your working directory and local repository, and between your local repository and the remote repository.

While GitHub is the leading platform for remote Git repositories, you should understand that others do exist. GitLab is a GitHub competitor that also offers an open source, on-premises version of their software. Another service is BitBucket. BitBucket supports both Git and Mercurial version control systems. Atlassian, a popular cloud service that offers many developer-friendly products, acquired BitBucket in 2010. In 2015, Atlassian changed the name of their enterprise Git platform from Stash to BitBucket Server, which competes with GitHub Enterprise.

Git Commands

One of the most important elements of Git is a repository. A repository is a directory that is initialized with Git.

A repository can contain anything such as code, images, and any other types of files. This understanding is the foundation of getting started with Git locally on your machine.

When you create a new project, the git init command must be used locally on your machine in order to initialize a project to work with Git. You must initialize a working directory with the git init command for Git to start tracking files. Make sure to initialize a working directory in the top directory that contains all the necessary files. Otherwise, Git will only track the subset of the files in the directory where you ran the command.

Git Command

Description

git init

Initialize a directory for a Git project.

git config <parameters>

Configure Git parameters such as username and email address.

git status

Check the status of your project.

git add <file/dir>

Start tracking files and add them to the staging area.

git rm <file/dir>

Stop tracking files.

git commit -m <message>

Create a local snapshot.

git remote <parameters>

Manage remote repositories.

git pull and git fetch <parameters>

Fetch changes from the remote repository.

git push <parameters>

Send committed changes to the remote repository.

Once you initialize a directory using the git init command, Git must be configured with a username and email address. This information is used in the Git history and during commits, making it possible to see who has made changes. Configurations for Git can be per project or for all projects on the system. When executing the git init command, Git also creates a subdirectory called .git that contains all the local snapshots (commits) and other metadata about the project.

To configure a Git username and email address, use the git config command. To see a list of all configurable options for a git config command, you can use the Linux man git config command.

You should also often use the git status command. This command allows you to see the status of your project. It shows you the files that need to be staged, the files that are staged, which branch you are on, and if a commit is required. Also, it will show the files that are not being tracked by Git.

$ git status
On branch master
Untracked files:
    (use "git add <file>..." To include in what will be committed)
        switch1.cfg
        switch2.cfg

nothing added to commit but untracked files present (use "git add" to track)

Once the project is created and initialized, you will use the git add command to add files into the Git project. The git add command performs two primary functions:

  • Starts tracking files

  • Adds files to the staging area

For example, if you want to add two new switch configuration files to a project, add them as follows:

$ git add switch1.cfg
$ git add switch2.cfg

If you want to remove file from Git project, use the git rm command.

$ git rm old-file1.cfg
$ git rm old-file2.cfg

Once you add files to the staging area, you can verify the status with the git status command.

$ git status
On branch master
 
Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
 
        new file:   switch1.cfg
        new file:   switch2.cfg

Use the git commit command to commit the staged changes. What the git commit command is really doing is creating a point-in-time local snapshot of the project. All incremental changes are stored in the .git directory that was automatically created when the git init command was executed.

$ git commit -m "Initial commit"
[master 073b339] Initial commit
2 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 switch1.cfg
create mode 100644 switch2.cfg

When you use the git commit command, you are required to include a commit message (using the -m flag). When you commit your changes, Git creates a commit object representing the complete state of the project, including all files in the project. At this point, after the git commit command is used, you have a local snapshot.

After you commit changes, you can use the git status command again to verify the changes.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
    (use "git push" to publish your local commits)
 
nothing to commit, working tree clean

Once changes are stored in the local repository, you need to specify the centralized remote repository that will be used to store your changes and changes of other participants of the project. Remote repositories in general are repositories that are hosted in your private network or on the Internet. You can specify multiple remote repositories for a specific project.

You can add remote repository using the git remote add command. To check which remote repositories are configured for a specific project, you can use the git remote command.

Once the remote repository is specified, you can use the git push command to send your snapshots (commits) to a remote repository. Similarly, you can use the git pull command to get commits of other participants on the project from a remote repository.

$ git push origin master
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 200 bytes | 200.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To github.com:<userid>/<project>.git
     a255d8a..073b339  master -> master

The git pull command is similar to the git fetch command; however, understanding the difference between these two commands is essential. While the git fetch command fetches changes from the remote repository and stores them to the local repository, the git pull command also merges changes to your current branch.

Git Command

Description

git stash <parameters>

Temporarily store all modified tracked files.

git reset <parameters>

Undo changes.

git clone <parameters>

Clone a local or remote repository.

Suppose that you are in the middle of development, and you have not staged any changes yet because your code is not ready to be committed. You are assigned to a more urgent request, so you have to focus on other files, but you do not want to lose changes that you have done so far. You can use the git stash command to temporarily save your current changes. Once you finish with other work, you can then use the git stash pop command to retrieve your previously saved changes.

$ git status
On branch master
Your branch is up to date with 'origin/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:   switch1.cfg
 
no changes added to commit (use "git add" and/or "git commit -a")
$
$ git stash
Saved working directory and index state WIP on master: 073b339 Initial commit
$
$ git stash list
stash@{0}: WIP on master: 073b339 Initial commit
$
$ git status
On branch master
Your branch is up to date with 'origin/master'.
 
nothing to commit, working tree clean
$
$ git stash pop
On branch master
Your branch is up to date with 'origin/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:   switch1.cfg
 
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (fce12d2f83c961ca27a4889298603ac52f588baf)

Now assume a similar scenario, but instead of using the git stash command to save your changes to temporary storage, you execute the git commit command and save your changes to your local repository. If you want to revert this commit, you can use the git reset HEAD~1 command. This command will remove commit from your local repository and move the changes done in that commit to your working directory.

It is also possible that you do not want to create a new project but rather copy a pre-existing project. For example, you want to test an open source project or just some code you found on GitHub. You can run this test by using this command:

$ git clone https://github.com/<userid>/<project>

The project has been cloned into a new directory. The project is a clone, so there is no need to use the git init command because the project was already initialized for Git.

Git Workflow

A Git workflow usually consists of the following actions:

  • Directory initialization for Git

  • Adding a file

  • Committing a file to a local repository

  • Pushing a file to a remote repository

  • Updating a local repository by pulling changes from a remote repository

$ git init
$ git config -global user.name "John Smith"
$ git config -global user.email john.smith@cisco.com
$ git add switch.cfg
$ git commit -m "Initial commit"

$ git remote add origin https://github.com/<user>/<repo>
$ git remote -v

$ git push local master

$ git pull

One of the Git functionalities is also reverting changes that you already committed. With the git revert command, you can revert any commit, not just the last one.

Assuming that you already created two commits, in the first commit, you configured an interface Loopback0 on switch1, and in the second commit, you configured interface Loopback0 on switch2. After deploying configuration to the switches, you decide to revert the configuration change on switch1.

Use the git log --oneline command to view commit hashes. By observing the command output, you realize that you want to revert changes of the commit with commit hash e871a41.

Use the git revert e871a41 command to revert changes on switch1. By executing the git revert command, Git will create new commit and prepend the "Revert" word to the original commit message. Use the git log command again to verify the commits.

$ git add switch1.cfg
$ git commit -m "Configure interface Loopback0 on switch1"
$ git add switch2.cfg
$ git commit -m "Configure interface Loopback0 on switch2"

$ git log --oneline
11123ce (HEAD -> master) Configure interface Loopback0 on switch2
e871a41 Configure interface Loopback0 on switch1

$ git revert e871a41
$ git log --oneline
295922e (HEAD -> master) Revert "Configure interface Loopback0 on switch1"
11123ce Configure interface Loopback0 on switch2
e871a41 Configure interface Loopback0 on switch1

Git GUI Workflow

Popular code editors have the ability to interact with Git using the editor GUI itself. Some editors already have built-in support for Git; in other editors, Git extension must be installed manually. Git extensions in code editors usually offer limited functionality compared with the Git command-line tool.



Here are some code editors that support Git integration:

  • Visual Studio Code

  • PyCharm

  • Atom

  • Notepad++

Content Review Question

Where is the central location of the files of the project, from which all the developers can pull?

Content Review Question

Which command is used to initialize a Git project?

Was this helpful?

No comments:

Post a Comment