Git: A practical guide

An overview of Git commands

Git: A practical guide

In the previous posts of this series, we covered the basics of version control systems and Git fundamentals. We introduced the advantages of using Git and provided installation guides for Linux, Windows, and macOS. Now, it's time to start using Git and create your first repository. This tutorial will guide you through the process of creating a Git repository and illustrate how to use various Git commands along the way. Whether you're a beginner or you just need a refresher, this tutorial is for you. Let's dive in!

Creating a Repository

While it's possible to create a repository at any point during the development process, it's always a good practice to create one early on. This is especially true if you're working with a team. By creating a repository early, you'll be able to keep your code organized from the beginning and avoid potential headaches down the line.

To get started, let's go ahead and create a new folder on the desktop, I'll call it git-demo.

To create a git repository, open up a terminal window (CMD or Powershell on Windows) and navigate to the directory where you'd like to create your repository. You can do that either with the cd command, which means Change Directory, like the following:

cd desktop/git-demo

or if you're on Windows, you can also right-click anywhere inside the folder and choose Git Bash Here.

Once you're there, run the following command to initialize a new Git repository:

git init

This will create a new (hidden) directory named .git in your current directory, which will serve as the backbone of your repository. You can think of this directory as a hidden database that tracks all changes made to your code.

Track Your Code: Staging

Let's write some code, shall we?

Create a new Python file called hello.py using your favourite code editor. This file will contain the shortest program in history:

print('Hello World!')

Right now, our file is not tracked by Git, meaning any changes we make to it won't be saved in Git's history. To track changes to our file, we need to stage it using the following command in the terminal:

git add hello.py

The git add command adds our file to Git's staging area, which means Git will start tracking changes to the file. The git add command can take arguments like file names, directory names, or wildcards to add multiple files at once. If we want to track all the files in our directory, we can write

git add .

Committing Changes

Once you've staged your changes, you're ready to commit them to your repository using the git commit command.

git commit -m "Initial commit"

The git commit command creates a new commit with the changes we've staged. The -m flag allows us to add a commit message describing the changes we've made. Commit messages should be clear and concise and describe the changes made in the commit.

Good Practices for Git Commits

To ensure that commits are effective and easy to manage, there are several good practices to follow:

  1. Keep commits small and focused: A commit should contain a single logical change or feature. This makes it easier to review and understand the changes made to the codebase.

  2. Write clear commit messages: A commit message should be descriptive and explain the changes made in the commit. This helps other developers understand what has been changed and why.

  3. Use the present tense and imperative mood in commit messages: Commit messages should start with a verb in the present tense, such as "Add," "Fix," or "Update." This makes it clear what action was taken in the commit.

  4. Commit frequently: Committing frequently allows for better tracking of changes and makes it easier to revert to previous versions if necessary.

The Status command

The git status command is a useful tool in Git that shows the current status of your repository. It displays the state of the working directory and the staging area. When you run this command, Git will tell you which files have been modified, which files are staged, and which files are not tracked.

The git status command allows you to keep track of your changes and see which files are ready to be committed. It will tell you if the file is modified but not yet staged, or if it has been staged and is ready to be committed.

In addition, git status also provides information about untracked files. Untracked files are files that are not yet added to the repository and are not being tracked by Git. This can help you keep track of changes to your code and ensure that everything is properly tracked. Let's run it in the terminal:

git status

Branches

Let's dive into branches and the git checkout command.

git branch

Git Branches: In Git, branches are like parallel timelines that allow you to work on different features, fixes, or experiments without affecting the main codebase. You can think of branches as separate workspaces where you can freely create, modify, and delete code.

  • Renaming a branch: If you want to rename an existing branch, you can use git branch -M new_name.

  • Creating a new branch: To create a new branch, use the git branch command followed by the branch name. For example, git branch new_feature will create a new branch called "new_feature."

  • Listing branches: To see a list of all branches in your repository, you can use git branch -v. It will show you all the branches along with their latest commits.

  • Viewing all branches: To see both local and remote branches, you can use git branch -a. This will display a list of all branches available in your local repository as well as the remote repository.

  • Deleting a branch: To delete a branch that you no longer need, use git branch -d branch_name. If the branch has unmerged changes, you can use git branch -D branch_name to force delete it.

git checkout

Git Checkout: The git checkout command allows you to switch between different branches in your repository. It's like teleporting between different timelines, letting you work on specific branches at different times.

  • Creating and switching to a new branch: To create and switch to a new branch at the same time, use git checkout -b new_branch_name. For example, git checkout -b feature_branch will create a new branch called "feature_branch" and switch to it.

  • Switching to an existing branch: If you want to move to an existing branch, use git checkout existing_branch_name. For example, git checkout main will switch you to the "main" branch.

git merge

Git Merge: Branches are often used to work on separate features, and once those features are ready, you can merge them back into the main codebase using the git merge command. It brings changes from one branch into another, creating a cohesive and up-to-date project.

Let's walk through some examples of using the git merge command.

Fast-forward merge

Let's say we have two branches: "main" and "feature_branch." The "feature_branch" has completed its development, and now we want to bring those changes into the "main" branch.

  1. First, switch to the "main" branch:
git checkout main
  1. Then, merge the changes from "feature_branch" into "main":
git merge feature_branch

In this scenario, if there are no conflicting changes between the two branches, Git performs a fast-forward merge. It moves the "main" branch pointer forward to the latest commit of "feature_branch," incorporating all the changes smoothly.

Merge with conflicts

Let's consider a situation where both the "main" and "bug_fix" branches have made changes to the same file, resulting in a conflict.

  1. First, switch to the "main" branch:
git checkout main
  1. Now, merge the changes from "bug_fix" into "main":
git merge bug_fix

If Git detects conflicts between the changes, it will pause the merge process and prompt you to resolve the conflicts manually. You'll need to open the conflicting file, identify and choose which changes to keep, save the file, and then commit the resolution.

Merge with a commit message

You can provide a custom commit message while merging to provide more context about the changes being merged.

  1. First, switch to the branch you want to merge into, for example, "main":
git checkout main
  1. Merge the changes from the other branch, say "feature_branch," with a custom commit message:
git merge feature_branch -m "Merge feature_branch into main: Add new feature XYZ"

This way, you can add a descriptive commit message that helps others understand the reason for the merge and what changes were introduced.

Try it out

Rename a branch

It's common practice to have your default branch called "main", so let's rename the current branch to "main". In your terminal, write:

git branch -M main

Add a new feature

Now, let's create a new branch to implement the feature "greeting".

git branch greeting-feature

then switch to the newly created branch:

git checkout greeting-feature

Or we can combine both of the previous commands in one command

git checkout -b greeting-feature

Then we'll make some changes in the hello.py file:

print('Hello World!')

name = input('Enter your name: ')
print(f'Hello, {name}! Nice to meet you.')

We can now add and commit the changes

git commit -am "add greeting by name"

git commit -am <message> is a shortcut to stage and commit changes to tracked files in one step. The -a flag automatically stages modified or deleted files. The -m <message> flag lets you add a commit message directly in the command. Note that it doesn't stage new or untracked files.

Merge changes

We can now merge the new feature into the main branch.

git checkout main
git merge greeting-feature

We see the following output, informing us that a fast-forward merge was performed.

Fast-forward
 hello.py | 3 +++
 1 file changed, 3 insertions(+)

We can now safely delete the greeting-feature branch:

git branch -d greeting-feature

Recap

In this tutorial, we've covered the essential local commands of Git, giving you a solid foundation to start using version control in your development workflow. We learned how to create a repository, track changes using staging, commit changes with informative messages, and manage branches using git branch and git checkout.

We also explored the powerful git merge command, which allows you to bring changes from different branches into the main codebase, and we saw how to handle both fast-forward merges and merges with conflicts.

By now, you should feel more confident in managing your code with Git and using branches to work on separate features. Congratulations on mastering the basics!

I hope you found this tutorial helpful, and I apologize for its length. I understand that it might have been quite detailed, but I believe that the in-depth explanations will benefit your understanding of Git. Your time and attention are greatly appreciated.

In the next tutorial, we'll take it a step further and explore the world of remote repositories. We'll show you how to collaborate with others, share your code on platforms like GitHub, and use Git's remote commands to work with repositories hosted on remote servers. Stay tuned for an exciting journey into the world of remote Git!

Feel free to leave your feedback or any questions in the comments below. Happy coding!