CODINGTHOUGHTS

A blog about C#, Python, Azure and full stack development

Git for Beginners – Part 1

History

Many version control systems have come and gone over the years, but it is Git that has dominated the last 10 years and show no sign of stopping any time soon. Beginners to Git can find it somewhat jarring coming from other version control systems. This guide hopes to make the path a little easier.

Git was first devised by Linus Torvalds in 2005 while developing the Linux kernel. It presented a different approach to source control compared to other systems. It uses a distributed as opposed to a client/server approach. Instead of having a single central ‘source of truth’ that tracks changes (which could conceivably go offline and leave all developers without access to their code), the full repository is downloaded to developers’ machines. Full version tracking occurs locally whether or not it is connected to any remote repositories.

What is it?

In case you don’t exactly know what a version control system is, a VCS allows a repository containing source code (or other types of content) to:

  • Track and mainain the code’s history
  • Allow multiple developers to work concurrently on the code base
  • Manage multiple changes to the same piece of code

Many times over the years, I have come across developers, who come from a background with a non-distributed version control system, who struggle with Git’s basic concepts. If you approach using Git with a client/server, centralised model in mind things will become very confusing very quickly.

Put simply, when you pull from the remote repository, you are pulling down not only the main branch and your own branches, but the checked in branches of every other user as well. When you make changes locally to your repo, this will not automatically affect the remote repository or those of other users. You have to explicitly push your changes to the remote repo, potentially triggering CI/CD pipelines.

Setting up

Starting Git is easy. Simply head to this page to download Git for your operating system. You are now ready to apply version control to your local content.

Given a folder where your project’s content resides, Git needs to initialise a repository, or ‘repo’. This involves creating a special folder in the root of your project named ‘.git’ and a .gitconfig file. These will contain configuration and metadata for your local repository.

To do this, issue the following commands in your project root folder:

git init
git add .

These commands initialise the repo and recursively add all existing files and folders. You may then check the status of the repo using:

git status

That’s it – you are ready to go, you now have a version controlled project.

Basic operations

Once you have a local repo initialised using the commands above, you are ready to make changes. As you edit code or alter other assets within the tracked folder, you are able commit or optionally stage and commit them.

Committing changes

Once you are happy with your changes it is time to commit them. This means that details of your change will be registered by Git and stored in the repo along with comments that you provide. In this way a detailed history of your code can be maintained.

Use the ‘git commit’ command to commit your changes:

git commit -a # using the -a switch adds any untracked changes before committing
git commit -m "Fixed buffer overflow bug" # the -m switch lets you provide a message
git commit -am "Fixed buffer overflow bug" # you may combine the -a and -m switches

Once you have committed, your working directory will show as being ‘clean’ when you issue the ‘git status’ command.

Staging changes

As you make changes to your code, remove or add files or make any other alterations, you have the option to ‘stage’ untracked changes. You are effectively placing changes in a ‘staging area’ where they can be committed together at a time of your choosing.

Staging and committing changes

This is a handy mechanism to help you organise or ‘batch up’ your changes before committing, it can also be helpful when you are deciding what changes to include and exclude from a commit. For example, if your intention is to create two commits based upon your outstanding changes, you may decide to stage the changes for the first commit, commit these and then commit the remainder. This is useful for breaking down larger changes, to make the changelog readable and logical.

You can view your untracked and staged changes using the ‘git status’ command. Don’t worry about pushing your changes to the remote repo yet, we will cover this in part two.

Branching and merging

Branching basics

‘git status’ displays your current branch (usually called ‘main’, or perhaps ‘master’ or ‘origin’ depending on configuration). You can ‘branch’ your local repo as many times as you like, each branch retaining its own set of changes – and you can switch back to the main branch and discard any branches you like. This gives you great freedom to experiment with your code in the knowledge that you can quickly revert back to the original. All the time you are experimenting, nothing is being pushed up to any remote server for other developers to pull down unless you specifically want to.

It is a common workflow to create a branch for a discrete piece of work such as a user story, task or bug. This makes it easy to associate work items in Jira, Azure Devops or GitHub to your changes. Some work items may necessitate multiple commits but this may actually be an indication that the work item is not defined or sized appropriately.

Manage branches with the ‘git branch’ and ‘git checkout’ commands:

git branch --list                               # lists all local branches (same as -l)
git branch --list --remotes                     # lists all remote branches (same as -lr or -a)
git branch <branchname>                         # create a new branch with name <branchname>
git checkout <branchname>                       # switches to an existing branch
git branch -m <oldbranchname> <newbranchname>   # renames a branch
git branch -c <oldbranchname> <newbranchname>   # copies a branch
git branch -d <branchname>                      # deletes a branch

Merging

At some point after working on your code branch, you will want to merge that down to the main branch. For example, imagine you have been working on a bug fix. You created a new branch called ‘bug-1234-FixSortOrderIssue’ and completed the remediation work on this. At this point you are happy with the fix, have committed your changes and now want to merge this down onto your main branch. The following command will perform this operation:

git checkout main
git merge bug-1234-FixSortOrderIssue

This effectively pulls the differences between the bug-1234-FixSortOrderIssue branch and main and applies them to main. If no further work is going to be done on bug-1234-FixSortOrderIssue, it is good practice to delete this branch.

Coming next – remote repo’s, GitHub and pushing your changes

The next post starts to look at how to interact with remote repos, which is essential if you are collaborating with other developers and content creators.

Don’t forget to check out our Git crib sheet for quick reference here.


Posted

in

by

Tags:

Comments

Leave a Reply