Modern Git commands and features that should be used

Modern Git commands and features that should be used

We, software developers, use git every day, but most of us only use the most important commands, such as add, commit, push and pullas in the yard, as before 2005.

Since then, many features have appeared in Git, the use of which may be very important in your life. So let’s explore some of the recently added modern teams gitwhich you should know about.

Switch

git switch which appeared in 2019, or more precisely in Git version 2.23, allows you to switch branches:

git switch other-branch
git switch -  # Переключение обратно на предыдудую ветвь, аналогично "cd -"
git switch remote-branch  # Непосредственное переключение на удалённую ветвь и её отслеживание

That’s great, but we’ve been able to switch branches in Git for a long time with help git checkoutwhy do you need a separate team? git checkout – A versatile command, it is able to (among other things) perform a check, restore specific files or even specific commits, and the new git switch only switches branches. In addition, switch performs additional health checks that are not performed checkoutexample, switch aborts the operation if it results in the loss of local changes.

Restore

Another new subcommand/feature added in Git 2.23 is this git restoreto restore the file to the latest commit version:

# Отмена внесённых в файл изменений, аналогично "git reset some-file.py"
git restore --staged some-file.py
# Отмена и сброс внесённых в файл изменений, аналогично "git checkout some-file.py"
git restore --staged --worktree some-file.py
# Откат файла к какому-то предыдущему коммиту, аналогично "git reset commit -- some-file.py"
git restore --source HEAD~2 some-file.py

The comments in the example above explain how the different options work git restore. In the general case git restore replaces and simplifies some of the ways to use too many features git reset and git checkout. also a comparison revert, restore andreset in this section of the documentation.

Sparse Checkout

Next we will consider git sparse-checkout — a slightly more complex feature added in Git 2.25, which was released on January 13, 2020.

Let’s say you have a large monorepository in which microservices are divided into separate folders; commands like checkout and status are extremely slow due to the size of the repository, but you may actually be fine with one subtree/folder. Then help will come git sparse-checkout:

$ git clone --no-checkout https://github.com/derrickstolee/sparse-checkout-example
$ cd sparse-checkout-example
$ git sparse-checkout init --cone  # Конфигурируем git, чтобы он подбирал файлы только в корневой папке
$ git checkout main  # Checkout только файлов в корневой папке
$ ls
bootstrap.sh  LICENSE.md  README.md
$ git sparse-checkout set service/common
$ ls
bootstrap.sh  LICENSE.md  README.md  service
$ tree .
.
├── bootstrap.sh
├── LICENSE.md
├── README.md
└── service
├── common
│   ├── app.js
│   ├── Dockerfile
... ...

In this example, we first clone the repository without checking all the files. Then we use it git sparse-checkout init --cone to adjust git so that it picks up files only in the root of the repository. After checkout, we will have only three files, not the whole tree. To then load/checkout a specific folder, we use git sparse-checkout set ....

As mentioned, this can be very convenient when working with huge repositories locally, but it is also useful in CI/CD to speed up the pipeline when we only need to build/deploy part of a monorepo and don’t need to check everything.

Detailed description sparse-checkout presented in the article.

Worktree

It often happens that one person simultaneously works on several features of the same program (repository); sometimes, in the process of working on a request for a new feature, a critical bug suddenly appears.

In such cases, you either have to have multiple cloned versions/branches of the repository, or suspend/cancel work on what you are currently doing. It was created to solve such problems git worktreeissued on September 24, 2018:

git branch
# * dev
# master
git worktree list
# /.../some-repo  ews5ger [dev]
git worktree add -b hotfix ./hotfix master
# Подготовка рабочего дерева (нового "хотфикса" ветви)
# HEAD теперь находится на коммите, подписанном 5ea9faa.
git worktree list
# /.../test-repo         ews5ger [dev]
# /.../test-repo/hotfix  5ea9faa [hotfix]
cd hotfix/  # Чистое рабочее дерево, в котором можно вносить изменения и пушить их

This allows us to simultaneously checkout several branches in one repository. In the example above we have two branches, dev and master. Suppose we work with a feature in a branch devBut we were asked to urgently eliminate the bug. Instead of deferring changes and resetting the branch to the original version, we create a new working tree in a subfolder ./hotfix from a branch master. You can then navigate to that folder, make changes, run them, and return to the original working tree.

You can read a more detailed description in the article.

Bisect

git bisect— not a particularly new feature (Git 1.7.14, released on May 13, 2012), but most people only use the features git that appeared around 2005, so I think it’s still worth showing.

The documentation page describes it as follows: git-bisect – Using binary search to find the commit that introduced the bug:

git bisect start
git bisect bad HEAD  # Указываем поломанный коммит
git bisect good 479420e  # Указываем точно работающий коммит
# Деление пополам: после этого осталось протестировать 2 ревизии (приблизительно 1 этап)
# [3258487215718444a6148439fa8476e8e7bd49c8] Рефакторинг.
# Проверяем текущий коммит...
git bisect bad  # Если коммит не работает
git bisect good # Если коммит работает
# В зависимости от последней команды Git делит пополам левую или правую половину
# Продолжаем тестирование, пока не найдём виновника
git bisect reset  # Сброс до исходного коммита

We start by running a bisect session using the command git bisect startafter which we specify a non-working commit (most likely this HEAD) and the last working commit or tag. With this information, git performs check out a commit in the middle between commits bad and good. At this point we need to test if this version has a bug; if the version works then we should use git bisect goodto saygit that she works, or git bisect bad, if not. We continue the process until there are no more commits left and git won’t tell us which comment has the problem.

I recommend studying the documentation page, where there are a couple more options git bisectincluding rendering, rendering, or skipping commits.

Conclusion

In search of problems related to gitYou will most likely come across questions StackOverflow with an answer that has several thousand votes. Although this answer will probably still be correct, it may well be out of date because it was written ten years ago. A better, simpler and more convenient solution may already exist. Therefore, if you encounter a problem with gitI recommend that you read the git documentation about the new commands, all of which are provided with excellent examples; or study the pages man various flags and options added over the years of development to the good old commands.

Related posts